[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Fri Aug 10 12:34:52 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/2d798fd21d78
changeset: 520:2d798fd21d78
user:      Aleksandr Rybalko <ray at ddteam.net>
date:      Fri Aug 10 14:19:25 2012 +0300
description:
FreeBSD HEAD @svn 239172r.

diffstat:

 head/Makefile.inc1                                                        =
     |      5 +-
 head/UPDATING                                                             =
     |      7 +-
 head/bin/sh/jobs.c                                                        =
     |     85 +-
 head/bin/sh/trap.c                                                        =
     |     10 +-
 head/bin/sh/trap.h                                                        =
     |      3 +-
 head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c                         =
     |      4 +-
 head/cddl/contrib/opensolaris/cmd/zpool/zpool.8                           =
     |     45 +-
 head/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c                      =
     |    435 +-
 head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c              =
     |      3 +-
 head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h                  =
     |      3 +-
 head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c           =
     |     25 +
 head/cddl/lib/libzfs/Makefile                                             =
     |      6 +-
 head/contrib/compiler-rt/LICENSE.TXT                                      =
     |      3 +-
 head/contrib/compiler-rt/lib/absvti2.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/adddf3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/addsf3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/addvti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/arm/aeabi_idivmod.S                          =
     |     27 +
 head/contrib/compiler-rt/lib/arm/aeabi_ldivmod.S                          =
     |     30 +
 head/contrib/compiler-rt/lib/arm/aeabi_memcmp.S                           =
     |     19 +
 head/contrib/compiler-rt/lib/arm/aeabi_memcpy.S                           =
     |     19 +
 head/contrib/compiler-rt/lib/arm/aeabi_memmove.S                          =
     |     19 +
 head/contrib/compiler-rt/lib/arm/aeabi_memset.S                           =
     |     32 +
 head/contrib/compiler-rt/lib/arm/aeabi_uidivmod.S                         =
     |     28 +
 head/contrib/compiler-rt/lib/arm/aeabi_uldivmod.S                         =
     |     30 +
 head/contrib/compiler-rt/lib/ashldi3.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/ashlti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/ashrdi3.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/ashrti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/assembly.h                                   =
     |      3 +
 head/contrib/compiler-rt/lib/atomic.c                                     =
     |    315 +
 head/contrib/compiler-rt/lib/clzti2.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/cmpti2.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/ctzti2.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/divdf3.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/divmoddi4.c                                  =
     |      2 -
 head/contrib/compiler-rt/lib/divsf3.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/divsi3.c                                     =
     |     10 +-
 head/contrib/compiler-rt/lib/divti3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/extendsfdf2.c                                =
     |      2 +-
 head/contrib/compiler-rt/lib/ffsti2.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/fixdfdi.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/fixdfsi.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/fixdfti.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/fixsfdi.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/fixsfsi.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/fixsfti.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/fixunsdfdi.c                                 =
     |      2 +-
 head/contrib/compiler-rt/lib/fixunsdfsi.c                                 =
     |      2 +-
 head/contrib/compiler-rt/lib/fixunsdfti.c                                 =
     |      4 +-
 head/contrib/compiler-rt/lib/fixunssfdi.c                                 =
     |      2 +-
 head/contrib/compiler-rt/lib/fixunssfsi.c                                 =
     |      2 +-
 head/contrib/compiler-rt/lib/fixunssfti.c                                 =
     |      4 +-
 head/contrib/compiler-rt/lib/fixunsxfti.c                                 =
     |      4 +-
 head/contrib/compiler-rt/lib/fixxfti.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/floatdidf.c                                  =
     |      2 +-
 head/contrib/compiler-rt/lib/floatdisf.c                                  =
     |      2 +-
 head/contrib/compiler-rt/lib/floatsidf.c                                  =
     |      2 +-
 head/contrib/compiler-rt/lib/floatsisf.c                                  =
     |      2 +-
 head/contrib/compiler-rt/lib/floattidf.c                                  =
     |      4 +-
 head/contrib/compiler-rt/lib/floattisf.c                                  =
     |      4 +-
 head/contrib/compiler-rt/lib/floattixf.c                                  =
     |      4 +-
 head/contrib/compiler-rt/lib/floatundidf.c                                =
     |      2 +-
 head/contrib/compiler-rt/lib/floatundisf.c                                =
     |      2 +-
 head/contrib/compiler-rt/lib/floatunsidf.c                                =
     |      2 +-
 head/contrib/compiler-rt/lib/floatunsisf.c                                =
     |      2 +-
 head/contrib/compiler-rt/lib/floatuntidf.c                                =
     |      4 +-
 head/contrib/compiler-rt/lib/floatuntisf.c                                =
     |      4 +-
 head/contrib/compiler-rt/lib/floatuntixf.c                                =
     |      4 +-
 head/contrib/compiler-rt/lib/fp_lib.h                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/int_endianness.h                             =
     |      9 +-
 head/contrib/compiler-rt/lib/int_util.c                                   =
     |     13 +
 head/contrib/compiler-rt/lib/int_util.h                                   =
     |      7 +-
 head/contrib/compiler-rt/lib/lshrdi3.c                                    =
     |      2 +-
 head/contrib/compiler-rt/lib/lshrti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/modti3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/muldf3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/muldi3.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/muloti4.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/mulsf3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/multi3.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/mulvti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/negdf2.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/negsf2.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/negti2.c                                     =
     |      4 +-
 head/contrib/compiler-rt/lib/negvti2.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/parityti2.c                                  =
     |      4 +-
 head/contrib/compiler-rt/lib/popcountti2.c                                =
     |      4 +-
 head/contrib/compiler-rt/lib/powitf2.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/subdf3.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/subsf3.c                                     =
     |      2 +-
 head/contrib/compiler-rt/lib/subvti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/truncdfsf2.c                                 =
     |      2 +-
 head/contrib/compiler-rt/lib/ucmpti2.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/udivmoddi4.c                                 =
     |      2 -
 head/contrib/compiler-rt/lib/udivmodti4.c                                 =
     |      4 +-
 head/contrib/compiler-rt/lib/udivsi3.c                                    =
     |      3 +-
 head/contrib/compiler-rt/lib/udivti3.c                                    =
     |      4 +-
 head/contrib/compiler-rt/lib/umodti3.c                                    =
     |      4 +-
 head/contrib/groff/tmac/doc-common                                        =
     |      3 -
 head/contrib/groff/tmac/doc-syms                                          =
     |      3 +-
 head/contrib/groff/tmac/doc.tmac                                          =
     |      2 +-
 head/contrib/groff/tmac/groff_mdoc.man                                    =
     |      2 -
 head/contrib/libarchive/FREEBSD-Xlist                                     =
     |      4 +-
 head/contrib/libarchive/FREEBSD-upgrade                                   =
     |      8 +-
 head/contrib/libarchive/NEWS                                              =
     |     18 +-
 head/contrib/libarchive/README                                            =
     |     13 +-
 head/contrib/libarchive/cpio/bsdcpio.1                                    =
     |      4 +-
 head/contrib/libarchive/cpio/cmdline.c                                    =
     |      3 +-
 head/contrib/libarchive/cpio/cpio.c                                       =
     |     38 +-
 head/contrib/libarchive/cpio/cpio.h                                       =
     |      6 +-
 head/contrib/libarchive/cpio/test/main.c                                  =
     |    323 +-
 head/contrib/libarchive/cpio/test/test.h                                  =
     |     14 +-
 head/contrib/libarchive/cpio/test/test_pathmatch.c                        =
     |    243 -
 head/contrib/libarchive/libarchive/archive.h                              =
     |    156 +-
 head/contrib/libarchive/libarchive/archive_acl.c                          =
     |     65 +-
 head/contrib/libarchive/libarchive/archive_check_magic.c                  =
     |      3 +-
 head/contrib/libarchive/libarchive/archive_endian.h                       =
     |     10 +-
 head/contrib/libarchive/libarchive/archive_entry.3                        =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_entry.c                        =
     |     80 +-
 head/contrib/libarchive/libarchive/archive_entry.h                        =
     |     63 +-
 head/contrib/libarchive/libarchive/archive_entry_acl.3                    =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_entry_link_resolver.c          =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_entry_linkify.3                =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_entry_paths.3                  =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_entry_perms.3                  =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_entry_stat.3                   =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_entry_stat.c                   =
     |     10 +-
 head/contrib/libarchive/libarchive/archive_entry_time.3                   =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_getdate.c                      =
     |   1037 +
 head/contrib/libarchive/libarchive/archive_match.c                        =
     |   1836 +
 head/contrib/libarchive/libarchive/archive_pathmatch.c                    =
     |    459 +
 head/contrib/libarchive/libarchive/archive_pathmatch.h                    =
     |     52 +
 head/contrib/libarchive/libarchive/archive_ppmd7.c                        =
     |      5 +-
 head/contrib/libarchive/libarchive/archive_private.h                      =
     |      3 +-
 head/contrib/libarchive/libarchive/archive_read.3                         =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read.c                         =
     |     13 +-
 head/contrib/libarchive/libarchive/archive_read_data.3                    =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_read_disk.3                    =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c    =
     |    419 +-
 head/contrib/libarchive/libarchive/archive_read_disk_posix.c              =
     |    503 +-
 head/contrib/libarchive/libarchive/archive_read_disk_private.h            =
     |     25 +-
 head/contrib/libarchive/libarchive/archive_read_extract.3                 =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_read_filter.3                  =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_read_format.3                  =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_free.3                    =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_header.3                  =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_read_new.3                     =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_open.3                    =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_open_fd.c                 =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_open_filename.c           =
     |     14 +-
 head/contrib/libarchive/libarchive/archive_read_private.h                 =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_read_set_options.3             =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_read_support_filter_rpm.c      =
     |      2 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c     =
     |    142 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_cab.c      =
     |    210 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_cpio.c     =
     |     57 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c  =
     |     38 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_lha.c      =
     |     12 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_mtree.c    =
     |     15 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_rar.c      =
     |     68 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_tar.c      =
     |    156 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_xar.c      =
     |     19 +-
 head/contrib/libarchive/libarchive/archive_read_support_format_zip.c      =
     |    160 +-
 head/contrib/libarchive/libarchive/archive_string.c                       =
     |    760 +-
 head/contrib/libarchive/libarchive/archive_string.h                       =
     |     12 +-
 head/contrib/libarchive/libarchive/archive_string_composition.h           =
     |    945 +-
 head/contrib/libarchive/libarchive/archive_string_sprintf.c               =
     |     16 +-
 head/contrib/libarchive/libarchive/archive_util.3                         =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_util.c                         =
     |      7 +-
 head/contrib/libarchive/libarchive/archive_write.3                        =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_write.c                        =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_write_add_filter.c             =
     |     66 +
 head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c       =
     |     14 +-
 head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c    =
     |     20 +-
 head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c        =
     |     36 +-
 head/contrib/libarchive/libarchive/archive_write_add_filter_program.c     =
     |    106 +-
 head/contrib/libarchive/libarchive/archive_write_add_filter_xz.c          =
     |     12 +-
 head/contrib/libarchive/libarchive/archive_write_blocksize.3              =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_data.3                   =
     |      8 +-
 head/contrib/libarchive/libarchive/archive_write_disk.3                   =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_write_disk_acl.c               =
     |    249 +
 head/contrib/libarchive/libarchive/archive_write_disk_posix.c             =
     |    161 +-
 head/contrib/libarchive/libarchive/archive_write_disk_private.h           =
     |      7 +-
 head/contrib/libarchive/libarchive/archive_write_disk_set_standard_lookup.=
c    |     30 +-
 head/contrib/libarchive/libarchive/archive_write_filter.3                 =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_finish_entry.3           =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_write_format.3                 =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_free.3                   =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_header.3                 =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_new.3                    =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_open.3                   =
     |      8 +-
 head/contrib/libarchive/libarchive/archive_write_open_filename.c          =
     |    169 +-
 head/contrib/libarchive/libarchive/archive_write_private.h                =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_7zip.c        =
     |     57 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_ar.c          =
     |      4 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_cpio.c        =
     |     13 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc.c   =
     |      9 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c      =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c     =
     |    151 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_mtree.c       =
     |     10 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_pax.c         =
     |     11 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_ustar.c       =
     |      6 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_xar.c         =
     |     17 +-
 head/contrib/libarchive/libarchive/archive_write_set_format_zip.c         =
     |    340 +-
 head/contrib/libarchive/libarchive/archive_write_set_options.3            =
     |      8 +-
 head/contrib/libarchive/libarchive/cpio.5                                 =
     |      4 +-
 head/contrib/libarchive/libarchive/libarchive-formats.5                   =
     |    106 +-
 head/contrib/libarchive/libarchive/libarchive.3                           =
     |     69 +-
 head/contrib/libarchive/libarchive/libarchive_changes.3                   =
     |      2 +-
 head/contrib/libarchive/libarchive/libarchive_internals.3                 =
     |      6 +-
 head/contrib/libarchive/libarchive/tar.5                                  =
     |      4 +-
 head/contrib/libarchive/libarchive/test/main.c                            =
     |    323 +-
 head/contrib/libarchive/libarchive/test/read_open_memory.c                =
     |      4 +-
 head/contrib/libarchive/libarchive/test/test.h                            =
     |     18 +-
 head/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c           =
     |   1094 +
 head/contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c        =
     |    520 +
 head/contrib/libarchive/libarchive/test/test_archive_getdate.c            =
     |     81 +
 head/contrib/libarchive/libarchive/test/test_archive_match_owner.c        =
     |    289 +
 head/contrib/libarchive/libarchive/test/test_archive_match_path.c         =
     |    450 +
 head/contrib/libarchive/libarchive/test/test_archive_match_time.c         =
     |   1358 +
 head/contrib/libarchive/libarchive/test/test_archive_pathmatch.c          =
     |    244 +
 head/contrib/libarchive/libarchive/test/test_archive_string_conversion.c  =
     |    487 +-
 head/contrib/libarchive/libarchive/test/test_compat_zip.c                 =
     |     16 +-
 head/contrib/libarchive/libarchive/test/test_read_disk_directory_traversal=
s.c  |    527 +-
 head/contrib/libarchive/libarchive/test/test_read_format_7zip.c           =
     |     18 +-
 head/contrib/libarchive/libarchive/test/test_read_format_cab.c            =
     |    116 +-
 head/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_r=
pm.c |      2 +-
 head/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rp=
m.c  |      2 +-
 head/contrib/libarchive/libarchive/test/test_read_format_rar.c            =
     |     25 +-
 head/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.rar.u=
u    |      5 +-
 head/contrib/libarchive/libarchive/test/test_read_format_tar_filename.c   =
     |      2 +-
 head/contrib/libarchive/libarchive/test/test_read_pax_truncated.c         =
     |      6 +-
 head/contrib/libarchive/libarchive/test/test_read_position.c              =
     |      4 +-
 head/contrib/libarchive/libarchive/test/test_sparse_basic.c               =
     |     28 +-
 head/contrib/libarchive/libarchive/test/test_write_format_zip.c           =
     |      4 +-
 head/contrib/libarchive/libarchive_fe/err.c                               =
     |      4 +-
 head/contrib/libarchive/libarchive_fe/err.h                               =
     |     14 +-
 head/contrib/libarchive/libarchive_fe/matching.c                          =
     |    281 -
 head/contrib/libarchive/libarchive_fe/matching.h                          =
     |     46 -
 head/contrib/libarchive/libarchive_fe/pathmatch.c                         =
     |    255 -
 head/contrib/libarchive/libarchive_fe/pathmatch.h                         =
     |     42 -
 head/contrib/libarchive/tar/bsdtar.1                                      =
     |      4 +-
 head/contrib/libarchive/tar/bsdtar.c                                      =
     |     87 +-
 head/contrib/libarchive/tar/bsdtar.h                                      =
     |     17 +-
 head/contrib/libarchive/tar/getdate.c                                     =
     |   1037 -
 head/contrib/libarchive/tar/read.c                                        =
     |     82 +-
 head/contrib/libarchive/tar/test/main.c                                   =
     |    323 +-
 head/contrib/libarchive/tar/test/test.h                                   =
     |     14 +-
 head/contrib/libarchive/tar/test/test_basic.c                             =
     |      8 +-
 head/contrib/libarchive/tar/test/test_format_newc.c                       =
     |     64 +
 head/contrib/libarchive/tar/test/test_getdate.c                           =
     |     80 -
 head/contrib/libarchive/tar/test/test_option_nodump.c                     =
     |     68 +
 head/contrib/libarchive/tar/tree.c                                        =
     |    848 -
 head/contrib/libarchive/tar/tree.h                                        =
     |    141 -
 head/contrib/libarchive/tar/write.c                                       =
     |    656 +-
 head/contrib/llvm/tools/clang/lib/Driver/Tools.cpp                        =
     |     12 +-
 head/contrib/opie/libopie/hash.c                                          =
     |     11 +-
 head/contrib/opie/libopie/hashlen.c                                       =
     |     11 +-
 head/etc/devd/usb.conf                                                    =
     |    286 +-
 head/games/fortune/datfiles/fortunes                                      =
     |     11 +-
 head/gnu/usr.bin/groff/tmac/mdoc.local                                    =
     |      4 +-
 head/include/gssapi/gssapi.h                                              =
     |     20 +-
 head/lib/libarchive/Makefile                                              =
     |      7 +-
 head/lib/libarchive/config_freebsd.h                                      =
     |      6 +-
 head/lib/libarchive/test/Makefile                                         =
     |     10 +-
 head/lib/libc/gen/fts.c                                                   =
     |      5 +-
 head/lib/libc/gen/ftw.c                                                   =
     |      5 +-
 head/lib/libc/gen/nftw.c                                                  =
     |     18 +-
 head/lib/libc/locale/Makefile.inc                                         =
     |      7 +-
 head/lib/libc/locale/isgraph.3                                            =
     |     22 +-
 head/lib/libc/locale/islower.3                                            =
     |     21 +-
 head/lib/libc/locale/ispunct.3                                            =
     |     22 +-
 head/lib/libc/locale/isspace.3                                            =
     |     22 +-
 head/lib/libc/locale/nl_langinfo.3                                        =
     |     18 +-
 head/lib/libedit/el.c                                                     =
     |     26 +-
 head/lib/libedit/histedit.h                                               =
     |      9 +-
 head/lib/libedit/term.c                                                   =
     |      4 +-
 head/lib/libpam/modules/pam_krb5/pam_krb5.c                               =
     |     21 +-
 head/lib/libpam/modules/pam_unix/pam_unix.c                               =
     |      6 +-
 head/lib/msun/ld128/s_expl.c                                              =
     |     16 +-
 head/lib/msun/ld80/s_expl.c                                               =
     |     30 +-
 head/lib/msun/src/s_cbrtl.c                                               =
     |     28 +-
 head/libexec/rtld-elf/arm/rtld_start.S                                    =
     |      8 +-
 head/libexec/rtld-elf/map_object.c                                        =
     |      6 +-
 head/rescue/rescue/Makefile                                               =
     |      4 +-
 head/sbin/camcontrol/camcontrol.c                                         =
     |      4 +-
 head/sbin/fsck_ffs/suj.c                                                  =
     |      4 +-
 head/sbin/geom/class/multipath/geom_multipath.c                           =
     |     28 +-
 head/sbin/geom/class/multipath/gmultipath.8                               =
     |     11 +-
 head/sbin/geom/class/sched/gsched.8                                       =
     |     16 +-
 head/sbin/geom/class/virstor/gvirstor.8                                   =
     |     11 +-
 head/sbin/ggate/shared/ggate.h                                            =
     |      6 +-
 head/sbin/ipfw/dummynet.c                                                 =
     |     16 +-
 head/sbin/ipfw/ipfw2.c                                                    =
     |     10 +-
 head/sbin/ipfw/nat.c                                                      =
     |      4 +-
 head/sbin/md5/Makefile                                                    =
     |      8 +-
 head/sbin/md5/md5.1                                                       =
     |     20 +-
 head/sbin/md5/md5.c                                                       =
     |     24 +-
 head/sbin/shutdown/shutdown.c                                             =
     |      8 +-
 head/share/examples/kld/dyn_sysctl/dyn_sysctl.c                           =
     |      8 +-
 head/share/man/man4/Makefile                                              =
     |      3 +-
 head/share/man/man4/ahci.4                                                =
     |     19 +-
 head/share/man/man4/hptiop.4                                              =
     |     54 +-
 head/share/man/man4/netmap.4                                              =
     |     48 +-
 head/share/man/man4/polling.4                                             =
     |      3 +-
 head/share/man/man4/umodem.4                                              =
     |      6 +-
 head/share/man/man4/uplcom.4                                              =
     |      6 +-
 head/share/man/man4/uslcom.4                                              =
     |    142 +-
 head/share/man/man4/vale.4                                                =
     |    131 +
 head/share/man/man5/rc.conf.5                                             =
     |      4 +-
 head/share/misc/bsd-family-tree                                           =
     |      6 +-
 head/share/misc/committers-ports.dot                                      =
     |      5 +-
 head/sys/amd64/amd64/elf_machdep.c                                        =
     |      3 +-
 head/sys/amd64/amd64/fpu.c                                                =
     |      4 +-
 head/sys/amd64/amd64/initcpu.c                                            =
     |     10 +-
 head/sys/amd64/amd64/pmap.c                                               =
     |     97 +-
 head/sys/amd64/include/cpufunc.h                                          =
     |      9 +-
 head/sys/arm/arm/bcopyinout.S                                             =
     |      5 +-
 head/sys/arm/arm/bcopyinout_xscale.S                                      =
     |      4 +-
 head/sys/arm/arm/exception.S                                              =
     |      5 +-
 head/sys/arm/arm/pmap.c                                                   =
     |      4 +-
 head/sys/arm/at91/at91_machdep.c                                          =
     |     34 +-
 head/sys/arm/at91/at91_pio_sam9g45.h                                      =
     |    272 +
 head/sys/arm/at91/at91_pmc.c                                              =
     |     69 +-
 head/sys/arm/at91/at91_pmcreg.h                                           =
     |     20 +-
 head/sys/arm/at91/at91_spi.c                                              =
     |     20 +-
 head/sys/arm/at91/at91sam9g45.c                                           =
     |    177 +
 head/sys/arm/at91/at91sam9g45reg.h                                        =
     |    294 +
 head/sys/arm/at91/at91sam9x25.c                                           =
     |    201 -
 head/sys/arm/at91/at91sam9x25reg.h                                        =
     |    316 -
 head/sys/arm/at91/at91sam9x5.c                                            =
     |    201 +
 head/sys/arm/at91/at91sam9x5reg.h                                         =
     |    315 +
 head/sys/arm/at91/board_sam9260ek.c                                       =
     |     82 +-
 head/sys/arm/at91/board_sn9g45.c                                          =
     |     55 +
 head/sys/arm/at91/files.at91                                              =
     |     13 +-
 head/sys/arm/at91/if_ate.c                                                =
     |     28 +-
 head/sys/arm/at91/std.at91sam9g45                                         =
     |     14 +
 head/sys/arm/at91/std.atmel                                               =
     |      5 +-
 head/sys/arm/at91/std.sam9x25ek                                           =
     |      4 +-
 head/sys/arm/at91/std.sn9g45                                              =
     |     12 +
 head/sys/arm/at91/uart_bus_at91usart.c                                    =
     |      8 +-
 head/sys/arm/conf/ATMEL                                                   =
     |     14 +-
 head/sys/arm/conf/ETHERNUT5                                               =
     |      6 +-
 head/sys/arm/conf/ETHERNUT5.hints                                         =
     |      4 +-
 head/sys/arm/conf/HL201                                                   =
     |      4 +-
 head/sys/arm/conf/KB920X                                                  =
     |      8 +-
 head/sys/arm/conf/QILA9G20                                                =
     |      3 +-
 head/sys/arm/conf/SAM9260EK                                               =
     |     56 +-
 head/sys/arm/conf/SAM9260EK.hints                                         =
     |     71 +-
 head/sys/arm/conf/SAM9G20EK                                               =
     |      3 +-
 head/sys/arm/conf/SAM9X25EK                                               =
     |      5 +-
 head/sys/arm/conf/SN9G45                                                  =
     |    129 +
 head/sys/arm/mv/common.c                                                  =
     |     17 +-
 head/sys/arm/mv/gpio.c                                                    =
     |      5 +-
 head/sys/arm/mv/ic.c                                                      =
     |      6 +-
 head/sys/arm/mv/kirkwood/kirkwood.c                                       =
     |      4 +-
 head/sys/arm/mv/mv_sata.c                                                 =
     |      3 +-
 head/sys/arm/mv/mvreg.h                                                   =
     |      3 +-
 head/sys/boot/common/Makefile.inc                                         =
     |     16 +-
 head/sys/boot/common/disk.c                                               =
     |    918 +-
 head/sys/boot/common/disk.h                                               =
     |     20 +-
 head/sys/boot/common/part.c                                               =
     |    839 +
 head/sys/boot/common/part.h                                               =
     |     82 +
 head/sys/boot/ficl/Makefile                                               =
     |      4 +-
 head/sys/boot/i386/libi386/Makefile                                       =
     |      6 +-
 head/sys/boot/i386/libi386/biosdisk.c                                     =
     |   1223 +-
 head/sys/boot/i386/libi386/devicename.c                                   =
     |     87 +-
 head/sys/boot/i386/libi386/libi386.h                                      =
     |      3 +-
 head/sys/boot/i386/loader/Makefile                                        =
     |      5 +-
 head/sys/boot/i386/loader/main.c                                          =
     |     20 +-
 head/sys/boot/i386/pmbr/pmbr.s                                            =
     |     45 +-
 head/sys/boot/pc98/boot2/boot2.c                                          =
     |     13 +-
 head/sys/boot/pc98/btx/btxldr/btxldr.S                                    =
     |      6 +-
 head/sys/boot/pc98/btx/lib/btxcsu.S                                       =
     |      6 +-
 head/sys/boot/pc98/cdboot/cdboot.S                                        =
     |      6 +-
 head/sys/boot/pc98/libpc98/Makefile                                       =
     |      5 +-
 head/sys/boot/sparc64/loader/main.c                                       =
     |     54 +-
 head/sys/boot/userboot/test/test.c                                        =
     |     30 +-
 head/sys/boot/userboot/userboot.h                                         =
     |      8 +-
 head/sys/boot/userboot/userboot/Makefile                                  =
     |      3 +-
 head/sys/boot/userboot/userboot/bootinfo32.c                              =
     |      4 +-
 head/sys/boot/userboot/userboot/copy.c                                    =
     |      3 +-
 head/sys/boot/userboot/userboot/devicename.c                              =
     |     82 +-
 head/sys/boot/userboot/userboot/main.c                                    =
     |      6 +-
 head/sys/boot/userboot/userboot/userboot_disk.c                           =
     |     85 +-
 head/sys/boot/zfs/Makefile                                                =
     |      4 +-
 head/sys/boot/zfs/zfs.c                                                   =
     |    107 +-
 head/sys/cam/ata/ata_all.h                                                =
     |      3 +-
 head/sys/cam/ata/ata_xpt.c                                                =
     |     14 +-
 head/sys/cam/cam_ccb.h                                                    =
     |      3 +-
 head/sys/cam/cam_periph.c                                                 =
     |      9 +-
 head/sys/cam/cam_xpt.c                                                    =
     |      3 +-
 head/sys/cam/ctl/scsi_ctl.c                                               =
     |    130 +-
 head/sys/cam/scsi/scsi_cd.c                                               =
     |    132 +-
 head/sys/cam/scsi/scsi_da.c                                               =
     |    135 +-
 head/sys/cam/scsi/scsi_enc.c                                              =
     |      4 +-
 head/sys/cam/scsi/scsi_enc_safte.c                                        =
     |      4 +-
 head/sys/cam/scsi/scsi_enc_ses.c                                          =
     |      4 +-
 head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c                 =
     |     21 +-
 head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h        =
     |      2 +-
 head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c            =
     |      9 +-
 head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c           =
     |      1 +
 head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h                 =
     |      1 +
 head/sys/conf/NOTES                                                       =
     |      4 +-
 head/sys/conf/files                                                       =
     |     13 +-
 head/sys/conf/files.powerpc                                               =
     |      3 +-
 head/sys/conf/kern.post.mk                                                =
     |      6 +-
 head/sys/dev/acpica/acpi_cpu.c                                            =
     |     34 +-
 head/sys/dev/agp/agp.c                                                    =
     |      3 +-
 head/sys/dev/agp/agp_i810.c                                               =
     |      3 +-
 head/sys/dev/ahci/ahci.c                                                  =
     |    138 +-
 head/sys/dev/ahci/ahci.h                                                  =
     |     22 +-
 head/sys/dev/ahci/ahciem.c                                                =
     |    600 +
 head/sys/dev/aic7xxx/aic79xx_osm.c                                        =
     |      3 +-
 head/sys/dev/aic7xxx/aic_osm_lib.c                                        =
     |      5 +-
 head/sys/dev/ath/ah_osdep.h                                               =
     |      8 +-
 head/sys/dev/ath/ath_hal/ah.c                                             =
     |      5 +-
 head/sys/dev/ath/ath_hal/ah.h                                             =
     |     21 +-
 head/sys/dev/ath/ath_hal/ah_desc.h                                        =
     |     25 +-
 head/sys/dev/ath/ath_hal/ah_devid.h                                       =
     |     11 +-
 head/sys/dev/ath/ath_hal/ah_internal.h                                    =
     |      3 +-
 head/sys/dev/ath/ath_hal/ar5210/ar5210.h                                  =
     |      5 +-
 head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c                           =
     |      3 +-
 head/sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c                             =
     |      8 +-
 head/sys/dev/ath/ath_hal/ar5211/ar5211.h                                  =
     |      5 +-
 head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c                           =
     |      3 +-
 head/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c                             =
     |      8 +-
 head/sys/dev/ath/ath_hal/ar5212/ar5212.h                                  =
     |      5 +-
 head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c                           =
     |      3 +-
 head/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c                             =
     |      8 +-
 head/sys/dev/ath/ath_hal/ar5416/ar5416.h                                  =
     |     10 +-
 head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c                           =
     |      3 +-
 head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c                             =
     |     20 +-
 head/sys/dev/ath/ath_rate/sample/sample.c                                 =
     |     14 +-
 head/sys/dev/ath/if_ath.c                                                 =
     |    183 +-
 head/sys/dev/ath/if_ath_beacon.c                                          =
     |     15 +-
 head/sys/dev/ath/if_ath_misc.h                                            =
     |     11 +-
 head/sys/dev/ath/if_ath_rx.c                                              =
     |      6 +-
 head/sys/dev/ath/if_ath_rx_edma.c                                         =
     |      6 +-
 head/sys/dev/ath/if_ath_tx.c                                              =
     |    249 +-
 head/sys/dev/ath/if_ath_tx.h                                              =
     |     12 +-
 head/sys/dev/ath/if_ath_tx_edma.c                                         =
     |    157 +-
 head/sys/dev/ath/if_ath_tx_ht.c                                           =
     |     28 +-
 head/sys/dev/ath/if_athioctl.h                                            =
     |      3 +-
 head/sys/dev/ath/if_athvar.h                                              =
     |     39 +-
 head/sys/dev/bce/if_bce.c                                                 =
     |      4 +-
 head/sys/dev/cesa/cesa.c                                                  =
     |      3 +-
 head/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.c                          =
     |      4 +-
 head/sys/dev/cxgbe/firmware/t4fw_interface.h                              =
     |      4 +-
 head/sys/dev/e1000/if_igb.c                                               =
     |     57 +-
 head/sys/dev/e1000/if_lem.c                                               =
     |    106 +-
 head/sys/dev/esp/ncr53c9x.c                                               =
     |     62 +-
 head/sys/dev/hptiop/hptiop.c                                              =
     |     14 +-
 head/sys/dev/ipmi/ipmi.c                                                  =
     |      9 +-
 head/sys/dev/ipmi/ipmivars.h                                              =
     |      3 +-
 head/sys/dev/isp/isp.c                                                    =
     |    571 +-
 head/sys/dev/isp/isp_freebsd.c                                            =
     |   1873 +-
 head/sys/dev/isp/isp_freebsd.h                                            =
     |    173 +-
 head/sys/dev/isp/isp_library.c                                            =
     |    399 +-
 head/sys/dev/isp/isp_library.h                                            =
     |     10 +-
 head/sys/dev/isp/isp_pci.c                                                =
     |    100 +-
 head/sys/dev/isp/isp_sbus.c                                               =
     |     98 +-
 head/sys/dev/isp/isp_stds.h                                               =
     |     80 +-
 head/sys/dev/isp/isp_target.c                                             =
     |     97 +-
 head/sys/dev/isp/isp_target.h                                             =
     |      3 +-
 head/sys/dev/isp/ispmbox.h                                                =
     |    114 +-
 head/sys/dev/isp/ispvar.h                                                 =
     |     48 +-
 head/sys/dev/ispfw/asm_2300.h                                             =
     |  12615 +++++----
 head/sys/dev/md/md.c                                                      =
     |     29 +-
 head/sys/dev/mge/if_mge.c                                                 =
     |      6 +-
 head/sys/dev/mii/e1000phy.c                                               =
     |      9 +-
 head/sys/dev/mlx/mlxvar.h                                                 =
     |      4 +-
 head/sys/dev/mps/mps.c                                                    =
     |     61 +-
 head/sys/dev/mps/mps_sas.c                                                =
     |      5 +-
 head/sys/dev/mps/mps_table.c                                              =
     |     14 +-
 head/sys/dev/mps/mps_user.c                                               =
     |     32 +-
 head/sys/dev/mps/mpsvar.h                                                 =
     |     10 +-
 head/sys/dev/mvs/mvs_soc.c                                                =
     |      3 +-
 head/sys/dev/netmap/if_em_netmap.h                                        =
     |      4 +-
 head/sys/dev/netmap/if_igb_netmap.h                                       =
     |      4 +-
 head/sys/dev/netmap/ixgbe_netmap.h                                        =
     |      4 +-
 head/sys/dev/netmap/netmap.c                                              =
     |    915 +-
 head/sys/dev/netmap/netmap_kern.h                                         =
     |     94 +-
 head/sys/dev/netmap/netmap_mem2.c                                         =
     |     13 +-
 head/sys/dev/pccbb/pccbb_pci.c                                            =
     |      7 +-
 head/sys/dev/pci/pci_pci.c                                                =
     |      9 +-
 head/sys/dev/puc/puc_cfg.h                                                =
     |      4 +-
 head/sys/dev/puc/pucdata.c                                                =
     |     52 +-
 head/sys/dev/sdhci/sdhci.c                                                =
     |      4 +-
 head/sys/dev/spibus/spi.h                                                 =
     |      5 +-
 head/sys/dev/spibus/spibus.c                                              =
     |      5 +-
 head/sys/dev/usb/controller/at91dci_atmelarm.c                            =
     |      6 +-
 head/sys/dev/usb/controller/ohci_atmelarm.c                               =
     |      3 +-
 head/sys/dev/usb/serial/uftdi.c                                           =
     |    604 +-
 head/sys/dev/usb/serial/uftdi_reg.h                                       =
     |      3 +-
 head/sys/dev/usb/serial/uslcom.c                                          =
     |     76 +-
 head/sys/dev/usb/usbdevs                                                  =
     |    727 +-
 head/sys/dev/wtap/if_wtap.c                                               =
     |     10 +-
 head/sys/fs/fifofs/fifo_vnops.c                                           =
     |     33 +-
 head/sys/fs/nfs/nfs_commonport.c                                          =
     |      3 +-
 head/sys/fs/nfsclient/nfs_clbio.c                                         =
     |     35 +-
 head/sys/fs/nwfs/nwfs_io.c                                                =
     |     35 +-
 head/sys/fs/smbfs/smbfs_io.c                                              =
     |     35 +-
 head/sys/fs/tmpfs/tmpfs_subr.c                                            =
     |      3 +-
 head/sys/fs/tmpfs/tmpfs_vnops.c                                           =
     |      3 +-
 head/sys/geom/gate/g_gate.c                                               =
     |    156 +-
 head/sys/geom/geom.h                                                      =
     |      8 +-
 head/sys/geom/geom_dev.c                                                  =
     |     22 +-
 head/sys/geom/geom_disk.c                                                 =
     |     28 +-
 head/sys/geom/geom_disk.h                                                 =
     |      4 +-
 head/sys/geom/geom_event.c                                                =
     |      8 +-
 head/sys/geom/geom_io.c                                                   =
     |     10 +-
 head/sys/geom/geom_slice.c                                                =
     |      3 +-
 head/sys/geom/geom_subr.c                                                 =
     |     97 +-
 head/sys/geom/geom_vfs.c                                                  =
     |      2 +-
 head/sys/geom/multipath/g_multipath.c                                     =
     |     76 +-
 head/sys/geom/part/g_part.c                                               =
     |      3 +-
 head/sys/geom/virstor/g_virstor.c                                         =
     |      8 +-
 head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c                                =
     |      6 +-
 head/sys/i386/i386/machdep.c                                              =
     |      4 +-
 head/sys/i386/i386/pmap.c                                                 =
     |      8 +-
 head/sys/i386/i386/trap.c                                                 =
     |     20 +-
 head/sys/i386/i386/vm86.c                                                 =
     |      8 +-
 head/sys/i386/i386/vm_machdep.c                                           =
     |      6 +-
 head/sys/i386/include/cpufunc.h                                           =
     |      9 +-
 head/sys/i386/include/pcpu.h                                              =
     |     24 +-
 head/sys/i386/isa/npx.c                                                   =
     |     33 +-
 head/sys/i386/linux/linux_proto.h                                         =
     |      6 +-
 head/sys/i386/linux/linux_syscall.h                                       =
     |      4 +-
 head/sys/i386/linux/linux_syscalls.c                                      =
     |      4 +-
 head/sys/i386/linux/linux_sysent.c                                        =
     |      4 +-
 head/sys/i386/linux/linux_systrace_args.c                                 =
     |      6 +-
 head/sys/i386/linux/syscalls.master                                       =
     |      4 +-
 head/sys/i386/xen/pmap.c                                                  =
     |      4 +-
 head/sys/ia64/ia64/pmap.c                                                 =
     |      3 +-
 head/sys/kern/kern_clocksource.c                                          =
     |     85 +-
 head/sys/kern/kern_descrip.c                                              =
     |     10 +-
 head/sys/kern/kern_intr.c                                                 =
     |     54 +-
 head/sys/kern/kern_ktr.c                                                  =
     |      6 +-
 head/sys/kern/kern_proc.c                                                 =
     |      3 +-
 head/sys/kern/sched_4bsd.c                                                =
     |     81 +-
 head/sys/kern/sched_ule.c                                                 =
     |     15 +-
 head/sys/kern/subr_uio.c                                                  =
     |      4 +-
 head/sys/kern/sys_pipe.c                                                  =
     |     10 +-
 head/sys/kern/sys_process.c                                               =
     |      3 +-
 head/sys/kern/uipc_syscalls.c                                             =
     |      3 +-
 head/sys/kern/vfs_syscalls.c                                              =
     |     46 +-
 head/sys/kern/vfs_vnops.c                                                 =
     |     62 +-
 head/sys/mips/include/pmap.h                                              =
     |      4 +-
 head/sys/mips/mips/pmap.c                                                 =
     |    121 +-
 head/sys/mips/mips/trap.c                                                 =
     |      4 +-
 head/sys/modules/ahci/Makefile                                            =
     |      4 +-
 head/sys/modules/cam/Makefile                                             =
     |      3 +-
 head/sys/net/bpf_zerocopy.c                                               =
     |      3 +-
 head/sys/net/flowtable.c                                                  =
     |      6 +-
 head/sys/net/if_llatbl.c                                                  =
     |     80 +-
 head/sys/net/if_llatbl.h                                                  =
     |     40 +-
 head/sys/net/if_loop.c                                                    =
     |     30 +-
 head/sys/net/if_var.h                                                     =
     |      4 +-
 head/sys/net80211/ieee80211.h                                             =
     |      4 +-
 head/sys/net80211/ieee80211_hwmp.c                                        =
     |     25 +-
 head/sys/netgraph/ng_ether.c                                              =
     |      4 +-
 head/sys/netgraph/ng_pptpgre.c                                            =
     |      4 +-
 head/sys/netinet/if_ether.c                                               =
     |    128 +-
 head/sys/netinet/in.c                                                     =
     |    103 +-
 head/sys/netinet/in_cksum.c                                               =
     |      4 +-
 head/sys/netinet/ip_dummynet.h                                            =
     |      6 +-
 head/sys/netinet/ipfw/dummynet.txt                                        =
     |      4 +-
 head/sys/netinet/ipfw/ip_dn_io.c                                          =
     |     39 +-
 head/sys/netinet/ipfw/ip_dummynet.c                                       =
     |      9 +-
 head/sys/netinet/ipfw/ip_fw2.c                                            =
     |      4 +-
 head/sys/netinet/ipfw/ip_fw_dynamic.c                                     =
     |     20 +-
 head/sys/netinet/ipfw/ip_fw_log.c                                         =
     |      8 +-
 head/sys/netinet/sctp_bsd_addr.c                                          =
     |     30 +-
 head/sys/netinet/sctp_input.c                                             =
     |      4 +-
 head/sys/netinet/sctp_pcb.c                                               =
     |     11 +-
 head/sys/netinet/sctp_uio.h                                               =
     |      6 +-
 head/sys/netinet/tcp_timer.c                                              =
     |     49 +-
 head/sys/netinet6/in6.c                                                   =
     |    105 +-
 head/sys/netinet6/ip6_ipsec.c                                             =
     |     10 +-
 head/sys/netinet6/ip6_output.c                                            =
     |     23 +-
 head/sys/nfsclient/nfs_bio.c                                              =
     |     35 +-
 head/sys/ofed/include/linux/gfp.h                                         =
     |      1 +
 head/sys/powerpc/conf/GENERIC                                             =
     |      3 +-
 head/sys/powerpc/conf/GENERIC64                                           =
     |      3 +-
 head/sys/powerpc/powermac/nvbl.c                                          =
     |    197 +
 head/sys/powerpc/powerpc/busdma_machdep.c                                 =
     |     43 +-
 head/sys/sparc64/include/pmap.h                                           =
     |     10 +-
 head/sys/sparc64/sparc64/pmap.c                                           =
     |     10 +-
 head/sys/sys/bus.h                                                        =
     |      4 +-
 head/sys/sys/fcntl.h                                                      =
     |      5 +-
 head/sys/sys/pipe.h                                                       =
     |      6 +-
 head/sys/sys/refcount.h                                                   =
     |      4 +-
 head/sys/ufs/ffs/ffs_vnops.c                                              =
     |      3 +-
 head/sys/vm/device_pager.c                                                =
     |      3 +-
 head/sys/vm/sg_pager.c                                                    =
     |      3 +-
 head/sys/vm/vm_page.c                                                     =
     |     92 +-
 head/sys/vm/vm_page.h                                                     =
     |     90 +-
 head/sys/vm/vm_pageout.c                                                  =
     |     79 +-
 head/sys/vm/vnode_pager.c                                                 =
     |     36 +-
 head/sys/x86/x86/busdma_machdep.c                                         =
     |     45 +-
 head/sys/x86/x86/local_apic.c                                             =
     |     45 +-
 head/sys/x86/x86/tsc.c                                                    =
     |    107 +-
 head/tools/regression/lib/libc/gen/Makefile                               =
     |      4 +-
 head/tools/regression/lib/libc/gen/test-ftw.c                             =
     |    141 +
 head/tools/tools/ath/ath_prom_read/Makefile                               =
     |      3 +-
 head/tools/tools/ath/athaggrstats/Makefile                                =
     |      3 +-
 head/tools/tools/ath/athratestats/main.c                                  =
     |    148 +-
 head/tools/tools/ath/athstats/Makefile                                    =
     |      3 +-
 head/tools/tools/ath/common/ah_osdep.h                                    =
     |      3 +-
 head/tools/tools/bootparttest/Makefile                                    =
     |     19 +
 head/tools/tools/bootparttest/bootparttest.c                              =
     |    172 +
 head/tools/tools/bootparttest/malloc.c                                    =
     |     44 +
 head/tools/tools/netmap/pkt-gen.c                                         =
     |     15 +-
 head/usr.bin/calendar/calendars/calendar.freebsd                          =
     |      3 +-
 head/usr.bin/cpio/Makefile                                                =
     |      6 +-
 head/usr.bin/cpio/test/Makefile                                           =
     |     13 +-
 head/usr.bin/du/du.c                                                      =
     |      4 +-
 head/usr.bin/find/extern.h                                                =
     |      6 +-
 head/usr.bin/find/find.1                                                  =
     |     12 +-
 head/usr.bin/find/find.c                                                  =
     |     10 +-
 head/usr.bin/find/function.c                                              =
     |     21 +-
 head/usr.bin/find/main.c                                                  =
     |      3 +-
 head/usr.bin/find/option.c                                                =
     |      6 +-
 head/usr.bin/make/var.c                                                   =
     |      4 +-
 head/usr.bin/script/script.1                                              =
     |     28 +-
 head/usr.bin/script/script.c                                              =
     |    220 +-
 head/usr.bin/tar/Makefile                                                 =
     |     10 +-
 head/usr.bin/tar/test/Makefile                                            =
     |     10 +-
 head/usr.sbin/ctladm/ctladm.c                                             =
     |      4 +-
 head/usr.sbin/portsnap/portsnap/portsnap.8                                =
     |     10 +-
 head/usr.sbin/portsnap/portsnap/portsnap.sh                               =
     |     22 +-
 633 files changed, 35095 insertions(+), 18673 deletions(-)

diffs (78903 lines):

diff -r 6b68d37bb4dc -r 2d798fd21d78 head/Makefile.inc1
--- a/head/Makefile.inc1	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/Makefile.inc1	Fri Aug 10 14:19:25 2012 +0300
@@ -1,5 +1,5 @@
 #
-# $FreeBSD: head/Makefile.inc1 238051 2012-07-03 06:41:00Z obrien $
+# $FreeBSD: head/Makefile.inc1 238926 2012-07-30 23:14:24Z mm $
 #
 # Make command line options:
 #	-DNO_CLEANDIR run ${MAKE} clean, instead of ${MAKE} cleandir
@@ -1277,7 +1277,7 @@
 		lib/ncurses/ncurses lib/ncurses/ncursesw \
 		lib/libopie lib/libpam ${_lib_libthr} \
 		lib/libradius lib/libsbuf lib/libtacplus \
-		${_cddl_lib_libumem} \
+		${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
 		lib/libutil ${_lib_libypclnt} lib/libz lib/msun \
 		${_secure_lib_libcrypto} ${_secure_lib_libssh} \
 		${_secure_lib_libssl}
@@ -1301,6 +1301,7 @@
=20
 .if ${MK_CDDL} !=3D "no"
 _cddl_lib_libumem=3D cddl/lib/libumem
+_cddl_lib_libnvpair=3D cddl/lib/libnvpair
 _cddl_lib=3D cddl/lib
 .endif
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/UPDATING
--- a/head/UPDATING	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/UPDATING	Fri Aug 10 14:19:25 2012 +0300
@@ -24,6 +24,11 @@
 	disable the most expensive debugging functionality run
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
=20
+20120727:
+	The sparc64 ZFS loader has been changed to no longer try to auto-
+	detect ZFS providers based on diskN aliases but now requires these
+	to be explicitly listed in the OFW boot-device environment variable.=20
+
 20120712:
 	The OpenSSL has been upgraded to 1.0.1c.  Any binaries requiring
 	libcrypto.so.6 or libssl.so.6 must be recompiled.  Also, there are
@@ -1615,4 +1620,4 @@
 Contact Warner Losh if you have any questions about your use of
 this document.
=20
-$FreeBSD: head/UPDATING 238405 2012-07-12 19:30:53Z jkim $
+$FreeBSD: head/UPDATING 238851 2012-07-27 18:23:11Z marius $
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/bin/sh/jobs.c
--- a/head/bin/sh/jobs.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/bin/sh/jobs.c	Fri Aug 10 14:19:25 2012 +0300
@@ -36,7 +36,7 @@
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/bin/sh/jobs.c 238470 2012-07-15 10:49:16Z jilles =
$");
+__FBSDID("$FreeBSD: head/bin/sh/jobs.c 238888 2012-07-29 18:04:38Z jilles =
$");
=20
 #include <sys/ioctl.h>
 #include <sys/param.h>
@@ -87,6 +87,10 @@
 volatile sig_atomic_t breakwaitcmd =3D 0;	/* should wait be terminated? */
 static int ttyfd =3D -1;
=20
+/* mode flags for dowait */
+#define DOWAIT_BLOCK	0x1 /* wait until a child exits */
+#define DOWAIT_SIG	0x2 /* if DOWAIT_BLOCK, abort on signals */
+
 #if JOBS
 static void restartjob(struct job *);
 #endif
@@ -94,7 +98,6 @@
 static struct job *getjob(char *);
 pid_t getjobpgrp(char *);
 static pid_t dowait(int, struct job *);
-static pid_t waitproc(int, int *);
 static void checkzombies(void);
 static void cmdtxt(union node *);
 static void cmdputs(const char *);
@@ -519,7 +522,7 @@
 					break;
 			}
 		}
-	} while (dowait(1, (struct job *)NULL) !=3D -1);
+	} while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) !=3D -1);
 	in_waitcmd--;
=20
 	return 0;
@@ -966,7 +969,7 @@
 	INTOFF;
 	TRACE(("waitforjob(%%%td) called\n", jp - jobtab + 1));
 	while (jp->state =3D=3D 0)
-		if (dowait(1, jp) =3D=3D -1)
+		if (dowait(DOWAIT_BLOCK | (Tflag ? DOWAIT_SIG : 0), jp) =3D=3D -1)
 			dotrap();
 #if JOBS
 	if (jp->jobctl) {
@@ -1004,14 +1007,20 @@
 }
=20
=20
+static void
+dummy_handler(int sig)
+{
+}
=20
 /*
  * Wait for a process to terminate.
  */
=20
 static pid_t
-dowait(int block, struct job *job)
+dowait(int mode, struct job *job)
 {
+	struct sigaction sa, osa;
+	sigset_t mask, omask;
 	pid_t pid;
 	int status;
 	struct procstat *sp;
@@ -1021,15 +1030,49 @@
 	int stopped;
 	int sig;
 	int coredump;
+	int wflags;
+	int restore_sigchld;
=20
 	TRACE(("dowait(%d) called\n", block));
+	restore_sigchld =3D 0;
+	if ((mode & DOWAIT_SIG) !=3D 0) {
+		sigfillset(&mask);
+		sigprocmask(SIG_BLOCK, &mask, &omask);
+		INTOFF;
+		if (!issigchldtrapped()) {
+			restore_sigchld =3D 1;
+			sa.sa_handler =3D dummy_handler;
+			sa.sa_flags =3D 0;
+			sigemptyset(&sa.sa_mask);
+			sigaction(SIGCHLD, &sa, &osa);
+		}
+	}
 	do {
-		pid =3D waitproc(block, &status);
+#if JOBS
+		if (iflag)
+			wflags =3D WUNTRACED | WCONTINUED;
+		else
+#endif
+			wflags =3D 0;
+		if ((mode & (DOWAIT_BLOCK | DOWAIT_SIG)) !=3D DOWAIT_BLOCK)
+			wflags |=3D WNOHANG;
+		pid =3D wait3(&status, wflags, (struct rusage *)NULL);
 		TRACE(("wait returns %d, status=3D%d\n", (int)pid, status));
-	} while ((pid =3D=3D -1 && errno =3D=3D EINTR && breakwaitcmd =3D=3D 0) ||
-		 (pid > 0 && WIFSTOPPED(status) && !iflag));
+		if (pid =3D=3D 0 && (mode & DOWAIT_SIG) !=3D 0) {
+			sigsuspend(&omask);
+			pid =3D -1;
+			if (int_pending())
+				break;
+		}
+	} while (pid =3D=3D -1 && errno =3D=3D EINTR && breakwaitcmd =3D=3D 0);
 	if (pid =3D=3D -1 && errno =3D=3D ECHILD && job !=3D NULL)
 		job->state =3D JOBDONE;
+	if ((mode & DOWAIT_SIG) !=3D 0) {
+		if (restore_sigchld)
+			sigaction(SIGCHLD, &osa, NULL);
+		sigprocmask(SIG_SETMASK, &omask, NULL);
+		INTON;
+	}
 	if (breakwaitcmd !=3D 0) {
 		breakwaitcmd =3D 0;
 		if (pid <=3D 0)
@@ -1050,7 +1093,11 @@
 					TRACE(("Changing status of proc %d from 0x%x to 0x%x\n",
 						   (int)pid, sp->status,
 						   status));
-					sp->status =3D status;
+					if (WIFCONTINUED(status)) {
+						sp->status =3D -1;
+						jp->state =3D 0;
+					} else
+						sp->status =3D status;
 					thisjob =3D jp;
 				}
 				if (sp->status =3D=3D -1)
@@ -1108,26 +1155,6 @@
=20
=20
 /*
- * Do a wait system call.  If job control is compiled in, we accept
- * stopped processes.  If block is zero, we return a value of zero
- * rather than blocking.
- */
-static pid_t
-waitproc(int block, int *status)
-{
-	int flags;
-
-#if JOBS
-	flags =3D WUNTRACED;
-#else
-	flags =3D 0;
-#endif
-	if (block =3D=3D 0)
-		flags |=3D WNOHANG;
-	return wait3(status, flags, (struct rusage *)NULL);
-}
-
-/*
  * return 1 if there are stopped jobs, otherwise 0
  */
 int job_warning =3D 0;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/bin/sh/trap.c
--- a/head/bin/sh/trap.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/bin/sh/trap.c	Fri Aug 10 14:19:25 2012 +0300
@@ -36,7 +36,7 @@
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/bin/sh/trap.c 238477 2012-07-15 11:18:52Z jilles =
$");
+__FBSDID("$FreeBSD: head/bin/sh/trap.c 238888 2012-07-29 18:04:38Z jilles =
$");
=20
 #include <signal.h>
 #include <unistd.h>
@@ -368,6 +368,14 @@
 }
=20
=20
+int
+issigchldtrapped(void)
+{
+
+	return (trap[SIGCHLD] !=3D NULL && *trap[SIGCHLD] !=3D '\0');
+}
+
+
 /*
  * Signal handler.
  */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/bin/sh/trap.h
--- a/head/bin/sh/trap.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/bin/sh/trap.h	Fri Aug 10 14:19:25 2012 +0300
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)trap.h	8.3 (Berkeley) 6/5/95
- * $FreeBSD: head/bin/sh/trap.h 223060 2011-06-13 21:03:27Z jilles $
+ * $FreeBSD: head/bin/sh/trap.h 238888 2012-07-29 18:04:38Z jilles $
  */
=20
 extern int pendingsigs;
@@ -41,6 +41,7 @@
 int have_traps(void);
 void setsignal(int);
 void ignoresig(int);
+int issigchldtrapped(void);
 void onsig(int);
 void dotrap(void);
 void setinteractive(int);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/contrib/opensolaris/cmd/dtra=
ce/dtrace.c
--- a/head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c	Mon Jul 30 11:44:18=
 2012 +0300
+++ b/head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c	Fri Aug 10 14:19:25=
 2012 +0300
@@ -70,8 +70,6 @@
 #define	E_ERROR		1
 #define	E_USAGE		2
=20
-#define IMPATIENT_LIMIT	2
-
 static const char DTRACE_OPTSTR[] =3D
 	"3:6:aAb:Bc:CD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
=20
@@ -1204,7 +1202,7 @@
 	if (!g_intr)
 		g_newline =3D 1;
=20
-	if (g_intr++ > IMPATIENT_LIMIT)
+	if (g_intr++)
 		g_impatient =3D 1;
 }
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/contrib/opensolaris/cmd/zpoo=
l/zpool.8
--- a/head/cddl/contrib/opensolaris/cmd/zpool/zpool.8	Mon Jul 30 11:44:18 2=
012 +0300
+++ b/head/cddl/contrib/opensolaris/cmd/zpool/zpool.8	Fri Aug 10 14:19:25 2=
012 +0300
@@ -22,7 +22,7 @@
 .\" Copyright (c) 2011, Justin T. Gibbs <gibbs at FreeBSD.org>
 .\" Copyright (c) 2012 by Delphix. All Rights Reserved.
 .\"
-.\" $FreeBSD: head/cddl/contrib/opensolaris/cmd/zpool/zpool.8 236960 2012-=
06-12 14:40:19Z mm $
+.\" $FreeBSD: head/cddl/contrib/opensolaris/cmd/zpool/zpool.8 238926 2012-=
07-30 23:14:24Z mm $
 .\"
 .Dd November 28, 2011
 .Dt ZPOOL 8
@@ -1636,21 +1636,22 @@
 .Op Fl v
 .Xc
 .Pp
-Displays all pools formatted using a different
+Displays pools which do not have all supported features enabled and pools
+formatted using a legacy
 .Tn ZFS
-pool on-disk version. Older versions can continue to be used, but some
-features may not be available. These pools can be upgraded using
-.Qq Nm Cm upgrade Fl a .
-Pools that are formatted with a more recent version are also displayed,
-although these pools will be inaccessible on the system.
+version number.
+These pools can continue to be used, but some features may not be availabl=
e.
+Use
+.Nm Cm upgrade Fl a
+to enable all features on all pools.
 .Bl -tag -width indent
 .It Fl v
-Displays
+Displays legacy
 .Tn ZFS
-pool versions supported by the current software. The current
-.Tn ZFS
-pool version and all previous supported versions are displayed, along
-with an explanation of the features provided with each version.
+versions supported by the current software.
+See
+.Xr zpool-features.5
+for a description of feature flags features supported by the current softw=
are.
 .El
 .It Xo
 .Nm
@@ -1659,18 +1660,22 @@
 .Fl a | Ar pool ...
 .Xc
 .Pp
-Upgrades the given pool to the latest on-disk pool version. Once this is d=
one,
-the pool will no longer be accessible on systems running older versions of=
 the
-software.
+Enables all supported features on the given pool.
+Once this is done, the pool will no longer be accessible on systems that do
+not support feature flags.
+See
+.Xr zpool-features.5
+for details on compatability with system sthat support feature flags, but =
do
+not support all features enabled on the pool.
 .Bl -tag -width indent
 .It Fl a
-Upgrades all pools.
+Enables all supported features on all pools.
 .It Fl V Ar version
-Upgrade to the specified version. If the
+Upgrade to the specified legacy version. If the
 .Fl V
-flag is not specified, the pool is upgraded to the most recent version. Th=
is
-option can only be used to increase the version number, and only up to the=
 most
-recent version supported by this software.
+flag is specified, no features will be enabled on the pool.
+This option can only be used to increase version number up to the last
+supported legacy version number.
 .El
 .El
 .Sh EXAMPLES
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/contrib/opensolaris/cmd/zpoo=
l/zpool_main.c
--- a/head/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c	Mon Jul 30 11:44=
:18 2012 +0300
+++ b/head/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c	Fri Aug 10 14:19=
:25 2012 +0300
@@ -389,6 +389,18 @@
 	}
 }
=20
+static boolean_t
+prop_list_contains_feature(nvlist_t *proplist)
+{
+	nvpair_t *nvp;
+	for (nvp =3D nvlist_next_nvpair(proplist, NULL); NULL !=3D nvp;
+	    nvp =3D nvlist_next_nvpair(proplist, nvp)) {
+		if (zpool_prop_feature(nvpair_name(nvp)))
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
 /*
  * Add a property pair (name, string-value) into a property nvlist.
  */
@@ -412,12 +424,30 @@
 	proplist =3D *props;
=20
 	if (poolprop) {
+		const char *vname =3D zpool_prop_to_name(ZPOOL_PROP_VERSION);
+
 		if ((prop =3D zpool_name_to_prop(propname)) =3D=3D ZPROP_INVAL &&
 		    !zpool_prop_feature(propname)) {
 			(void) fprintf(stderr, gettext("property '%s' is "
 			    "not a valid pool property\n"), propname);
 			return (2);
 		}
+
+		/*
+		 * feature@ properties and version should not be specified
+		 * at the same time.
+		 */
+		if ((prop =3D=3D ZPROP_INVAL && zpool_prop_feature(propname) &&
+		    nvlist_exists(proplist, vname)) ||
+		    (prop =3D=3D ZPOOL_PROP_VERSION &&
+		    prop_list_contains_feature(proplist))) {
+			(void) fprintf(stderr, gettext("'feature@' and "
+			    "'version' properties cannot be specified "
+			    "together\n"));
+			return (2);
+		}
+
+
 		if (zpool_prop_feature(propname))
 			normnm =3D propname;
 		else
@@ -1583,8 +1613,8 @@
 		break;
=20
 	case ZPOOL_STATUS_VERSION_OLDER:
-		(void) printf(gettext(" status: The pool is formatted using an "
-		    "older on-disk version.\n"));
+		(void) printf(gettext(" status: The pool is formatted using a "
+		    "legacy on-disk version.\n"));
 		break;
=20
 	case ZPOOL_STATUS_VERSION_NEWER:
@@ -1592,6 +1622,11 @@
 		    "incompatible version.\n"));
 		break;
=20
+	case ZPOOL_STATUS_FEAT_DISABLED:
+		(void) printf(gettext(" status: Some supported features are "
+		    "not enabled on the pool.\n"));
+		break;
+
 	case ZPOOL_STATUS_UNSUP_FEAT_READ:
 		(void) printf(gettext("status: The pool uses the following "
 		    "feature(s) not supported on this sytem:\n"));
@@ -1638,19 +1673,21 @@
 	 * Print out an action according to the overall state of the pool.
 	 */
 	if (vs->vs_state =3D=3D VDEV_STATE_HEALTHY) {
-		if (reason =3D=3D ZPOOL_STATUS_VERSION_OLDER)
+		if (reason =3D=3D ZPOOL_STATUS_VERSION_OLDER ||
+		    reason =3D=3D ZPOOL_STATUS_FEAT_DISABLED) {
 			(void) printf(gettext(" action: The pool can be "
 			    "imported using its name or numeric identifier, "
 			    "though\n\tsome features will not be available "
 			    "without an explicit 'zpool upgrade'.\n"));
-		else if (reason =3D=3D ZPOOL_STATUS_HOSTID_MISMATCH)
+		} else if (reason =3D=3D ZPOOL_STATUS_HOSTID_MISMATCH) {
 			(void) printf(gettext(" action: The pool can be "
 			    "imported using its name or numeric "
 			    "identifier and\n\tthe '-f' flag.\n"));
-		else
+		} else {
 			(void) printf(gettext(" action: The pool can be "
 			    "imported using its name or numeric "
 			    "identifier.\n"));
+		}
 	} else if (vs->vs_state =3D=3D VDEV_STATE_DEGRADED) {
 		(void) printf(gettext(" action: The pool can be imported "
 		    "despite missing or damaged devices.  The\n\tfault "
@@ -4108,12 +4145,13 @@
 		break;
=20
 	case ZPOOL_STATUS_VERSION_OLDER:
-		(void) printf(gettext("status: The pool is formatted using an "
-		    "older on-disk format.  The pool can\n\tstill be used, but "
-		    "some features are unavailable.\n"));
+		(void) printf(gettext("status: The pool is formatted using a "
+		    "legacy on-disk format.  The pool can\n\tstill be used, "
+		    "but some features are unavailable.\n"));
 		(void) printf(gettext("action: Upgrade the pool using 'zpool "
 		    "upgrade'.  Once this is done, the\n\tpool will no longer "
-		    "be accessible on older software versions.\n"));
+		    "be accessible on software that does not support feature\n"
+		    "\tflags.\n"));
 		break;
=20
 	case ZPOOL_STATUS_VERSION_NEWER:
@@ -4125,6 +4163,16 @@
 		    "backup.\n"));
 		break;
=20
+	case ZPOOL_STATUS_FEAT_DISABLED:
+		(void) printf(gettext("status: Some supported features are not "
+		    "enabled on the pool. The pool can\n\tstill be used, but "
+		    "some features are unavailable.\n"));
+		(void) printf(gettext("action: Enable all features using "
+		    "'zpool upgrade'. Once this is done,\n\tthe pool may no "
+		    "longer be accessible by software that does not support\n\t"
+		    "the features. See zpool-features(5) for details.\n"));
+		break;
+
 	case ZPOOL_STATUS_UNSUP_FEAT_READ:
 		(void) printf(gettext("status: The pool cannot be accessed on "
 		    "this system because it uses the\n\tfollowing feature(s) "
@@ -4354,15 +4402,14 @@
 }
=20
 typedef struct upgrade_cbdata {
-	int	cb_all;
 	int	cb_first;
-	int	cb_newer;
 	char	cb_poolname[ZPOOL_MAXNAMELEN];
 	int	cb_argc;
 	uint64_t cb_version;
 	char	**cb_argv;
 } upgrade_cbdata_t;
=20
+#ifdef __FreeBSD__
 static int
 is_root_pool(zpool_handle_t *zhp)
 {
@@ -4388,56 +4435,161 @@
 	return (poolname !=3D NULL && strcmp(poolname, zpool_get_name(zhp)) =3D=
=3D 0);
 }
=20
+static void
+root_pool_upgrade_check(zpool_handle_t *zhp, char *poolname, int size) {
+
+	if (poolname[0] =3D=3D '\0' && is_root_pool(zhp))
+		(void) strlcpy(poolname, zpool_get_name(zhp), size);
+}
+#endif	/* FreeBSD */
+
+static int
+upgrade_version(zpool_handle_t *zhp, uint64_t version)
+{
+	int ret;
+	nvlist_t *config;
+	uint64_t oldversion;
+
+	config =3D zpool_get_config(zhp, NULL);
+	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+	    &oldversion) =3D=3D 0);
+
+	assert(SPA_VERSION_IS_SUPPORTED(oldversion));
+	assert(oldversion < version);
+
+	ret =3D zpool_upgrade(zhp, version);
+	if (ret !=3D 0)
+		return (ret);
+
+	if (version >=3D SPA_VERSION_FEATURES) {
+		(void) printf(gettext("Successfully upgraded "
+		    "'%s' from version %llu to feature flags.\n"),
+		    zpool_get_name(zhp), oldversion);
+	} else {
+		(void) printf(gettext("Successfully upgraded "
+		    "'%s' from version %llu to version %llu.\n"),
+		    zpool_get_name(zhp), oldversion, version);
+	}
+
+	return (0);
+}
+
+static int
+upgrade_enable_all(zpool_handle_t *zhp, int *countp)
+{
+	int i, ret, count;
+	boolean_t firstff =3D B_TRUE;
+	nvlist_t *enabled =3D zpool_get_features(zhp);
+
+	count =3D 0;
+	for (i =3D 0; i < SPA_FEATURES; i++) {
+		const char *fname =3D spa_feature_table[i].fi_uname;
+		const char *fguid =3D spa_feature_table[i].fi_guid;
+		if (!nvlist_exists(enabled, fguid)) {
+			char *propname;
+			verify(-1 !=3D asprintf(&propname, "feature@%s", fname));
+			ret =3D zpool_set_prop(zhp, propname,
+			    ZFS_FEATURE_ENABLED);
+			if (ret !=3D 0) {
+				free(propname);
+				return (ret);
+			}
+			count++;
+
+			if (firstff) {
+				(void) printf(gettext("Enabled the "
+				    "following features on '%s':\n"),
+				    zpool_get_name(zhp));
+				firstff =3D B_FALSE;
+			}
+			(void) printf(gettext("  %s\n"), fname);
+			free(propname);
+		}
+	}
+
+	if (countp !=3D NULL)
+		*countp =3D count;
+	return (0);
+}
+
 static int
 upgrade_cb(zpool_handle_t *zhp, void *arg)
 {
 	upgrade_cbdata_t *cbp =3D arg;
 	nvlist_t *config;
 	uint64_t version;
-	int ret =3D 0;
+	boolean_t printnl =3D B_FALSE;
+	int ret;
=20
 	config =3D zpool_get_config(zhp, NULL);
 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
 	    &version) =3D=3D 0);
=20
-	if (!cbp->cb_newer && SPA_VERSION_IS_SUPPORTED(version) &&
-	    version !=3D SPA_VERSION) {
-		if (!cbp->cb_all) {
-			if (cbp->cb_first) {
-				(void) printf(gettext("The following pools are "
-				    "out of date, and can be upgraded.  After "
-				    "being\nupgraded, these pools will no "
-				    "longer be accessible by older software "
-				    "versions.\n\n"));
-				(void) printf(gettext("VER  POOL\n"));
-				(void) printf(gettext("---  ------------\n"));
-				cbp->cb_first =3D B_FALSE;
-			}
-
-			(void) printf("%2llu   %s\n", (u_longlong_t)version,
-			    zpool_get_name(zhp));
-		} else {
+	assert(SPA_VERSION_IS_SUPPORTED(version));
+
+	if (version < cbp->cb_version) {
+		cbp->cb_first =3D B_FALSE;
+		ret =3D upgrade_version(zhp, cbp->cb_version);
+		if (ret !=3D 0)
+			return (ret);
+#ifdef __FreeBSD__
+		root_pool_upgrade_check(zhp, cbp->cb_poolname,
+		    sizeof(cbp->cb_poolname));
+#endif	/* ___FreeBSD__ */
+		printnl =3D B_TRUE;
+
+#ifdef illumos
+		/*
+		 * If they did "zpool upgrade -a", then we could
+		 * be doing ioctls to different pools.  We need
+		 * to log this history once to each pool, and bypass
+		 * the normal history logging that happens in main().
+		 */
+		(void) zpool_log_history(g_zfs, history_str);
+		log_history =3D B_FALSE;
+#endif
+	}
+
+	if (cbp->cb_version >=3D SPA_VERSION_FEATURES) {
+		int count;
+		ret =3D upgrade_enable_all(zhp, &count);
+		if (ret !=3D 0)
+			return (ret);
+
+		if (count > 0) {
 			cbp->cb_first =3D B_FALSE;
-			ret =3D zpool_upgrade(zhp, cbp->cb_version);
-			if (!ret) {
-				(void) printf(gettext("Successfully upgraded "
-				    "'%s'\n\n"), zpool_get_name(zhp));
-				if (cbp->cb_poolname[0] =3D=3D '\0' &&
-				    is_root_pool(zhp)) {
-					(void) strlcpy(cbp->cb_poolname,
-					    zpool_get_name(zhp),
-					    sizeof(cbp->cb_poolname));
-				}
-			}
+			printnl =3D B_TRUE;
 		}
-	} else if (cbp->cb_newer && !SPA_VERSION_IS_SUPPORTED(version)) {
-		assert(!cbp->cb_all);
-
+	}
+
+	if (printnl) {
+		(void) printf(gettext("\n"));
+	}
+
+	return (0);
+}
+
+static int
+upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
+{
+	upgrade_cbdata_t *cbp =3D arg;
+	nvlist_t *config;
+	uint64_t version;
+
+	config =3D zpool_get_config(zhp, NULL);
+	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+	    &version) =3D=3D 0);
+
+	assert(SPA_VERSION_IS_SUPPORTED(version));
+
+	if (version < SPA_VERSION_FEATURES) {
 		if (cbp->cb_first) {
 			(void) printf(gettext("The following pools are "
-			    "formatted using an unsupported software version "
-			    "and\ncannot be accessed on the current "
-			    "system.\n\n"));
+			    "formatted with legacy version numbers and can\n"
+			    "be upgraded to use feature flags.  After "
+			    "being upgraded, these pools\nwill no "
+			    "longer be accessible by software that does not "
+			    "support feature\nflags.\n\n"));
 			(void) printf(gettext("VER  POOL\n"));
 			(void) printf(gettext("---  ------------\n"));
 			cbp->cb_first =3D B_FALSE;
@@ -4447,14 +4599,65 @@
 		    zpool_get_name(zhp));
 	}
=20
-	zpool_close(zhp);
-	return (ret);
+	return (0);
+}
+
+static int
+upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
+{
+	upgrade_cbdata_t *cbp =3D arg;
+	nvlist_t *config;
+	uint64_t version;
+
+	config =3D zpool_get_config(zhp, NULL);
+	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+	    &version) =3D=3D 0);
+
+	if (version >=3D SPA_VERSION_FEATURES) {
+		int i;
+		boolean_t poolfirst =3D B_TRUE;
+		nvlist_t *enabled =3D zpool_get_features(zhp);
+
+		for (i =3D 0; i < SPA_FEATURES; i++) {
+			const char *fguid =3D spa_feature_table[i].fi_guid;
+			const char *fname =3D spa_feature_table[i].fi_uname;
+			if (!nvlist_exists(enabled, fguid)) {
+				if (cbp->cb_first) {
+					(void) printf(gettext("\nSome "
+					    "supported features are not "
+					    "enabled on the following pools. "
+					    "Once a\nfeature is enabled the "
+					    "pool may become incompatible with "
+					    "software\nthat does not support "
+					    "the feature. See "
+					    "zpool-features(5) for "
+					    "details.\n\n"));
+					(void) printf(gettext("POOL  "
+					    "FEATURE\n"));
+					(void) printf(gettext("------"
+					    "---------\n"));
+					cbp->cb_first =3D B_FALSE;
+				}
+
+				if (poolfirst) {
+					(void) printf(gettext("%s\n"),
+					    zpool_get_name(zhp));
+					poolfirst =3D B_FALSE;
+				}
+
+				(void) printf(gettext("      %s\n"), fname);
+			}
+		}
+	}
+
+	return (0);
 }
=20
 /* ARGSUSED */
 static int
 upgrade_one(zpool_handle_t *zhp, void *data)
 {
+	boolean_t printnl =3D B_FALSE;
 	upgrade_cbdata_t *cbp =3D data;
 	uint64_t cur_version;
 	int ret;
@@ -4469,30 +4672,53 @@
 	cur_version =3D zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
 	if (cur_version > cbp->cb_version) {
 		(void) printf(gettext("Pool '%s' is already formatted "
-		    "using more current version '%llu'.\n"),
+		    "using more current version '%llu'.\n\n"),
 		    zpool_get_name(zhp), cur_version);
 		return (0);
 	}
-	if (cur_version =3D=3D cbp->cb_version) {
+
+	if (cbp->cb_version !=3D SPA_VERSION && cur_version =3D=3D cbp->cb_versio=
n) {
 		(void) printf(gettext("Pool '%s' is already formatted "
-		    "using the current version.\n"), zpool_get_name(zhp));
+		    "using version %llu.\n\n"), zpool_get_name(zhp),
+		    cbp->cb_version);
 		return (0);
 	}
=20
-	ret =3D zpool_upgrade(zhp, cbp->cb_version);
-
-	if (!ret) {
-		(void) printf(gettext("Successfully upgraded '%s' "
-		    "from version %llu to version %llu\n\n"),
-		    zpool_get_name(zhp), (u_longlong_t)cur_version,
-		    (u_longlong_t)cbp->cb_version);
-		if (cbp->cb_poolname[0] =3D=3D '\0' && is_root_pool(zhp)) {
-			(void) strlcpy(cbp->cb_poolname, zpool_get_name(zhp),
+	if (cur_version !=3D cbp->cb_version) {
+		printnl =3D B_TRUE;
+		ret =3D upgrade_version(zhp, cbp->cb_version);
+		if (ret !=3D 0)
+			return (ret);
+#ifdef __FreeBSD__
+		root_pool_upgrade_check(zhp, cbp->cb_poolname,
+		    sizeof(cbp->cb_poolname));
+#endif	/* ___FreeBSD__ */
+	}
+
+	if (cbp->cb_version >=3D SPA_VERSION_FEATURES) {
+		int count =3D 0;
+		ret =3D upgrade_enable_all(zhp, &count);
+		if (ret !=3D 0)
+			return (ret);
+
+		if (count !=3D 0) {
+			printnl =3D B_TRUE;
+#ifdef __FreeBSD__
+			root_pool_upgrade_check(zhp, cbp->cb_poolname,
 			    sizeof(cbp->cb_poolname));
+#endif	/* __FreeBSD __*/
+		} else if (cur_version =3D=3D SPA_VERSION) {
+			(void) printf(gettext("Pool '%s' already has all "
+			    "supported features enabled.\n"),
+			    zpool_get_name(zhp));
 		}
 	}
=20
-	return (ret !=3D 0);
+	if (printnl) {
+		(void) printf(gettext("\n"));
+	}
+
+	return (0);
 }
=20
 /*
@@ -4511,6 +4737,7 @@
 	upgrade_cbdata_t cb =3D { 0 };
 	int ret =3D 0;
 	boolean_t showversions =3D B_FALSE;
+	boolean_t upgradeall =3D B_FALSE;
 	char *end;
=20
=20
@@ -4518,7 +4745,7 @@
 	while ((c =3D getopt(argc, argv, ":avV:")) !=3D -1) {
 		switch (c) {
 		case 'a':
-			cb.cb_all =3D B_TRUE;
+			upgradeall =3D B_TRUE;
 			break;
 		case 'v':
 			showversions =3D B_TRUE;
@@ -4551,19 +4778,19 @@
=20
 	if (cb.cb_version =3D=3D 0) {
 		cb.cb_version =3D SPA_VERSION;
-	} else if (!cb.cb_all && argc =3D=3D 0) {
+	} else if (!upgradeall && argc =3D=3D 0) {
 		(void) fprintf(stderr, gettext("-V option is "
 		    "incompatible with other arguments\n"));
 		usage(B_FALSE);
 	}
=20
 	if (showversions) {
-		if (cb.cb_all || argc !=3D 0) {
+		if (upgradeall || argc !=3D 0) {
 			(void) fprintf(stderr, gettext("-v option is "
 			    "incompatible with other arguments\n"));
 			usage(B_FALSE);
 		}
-	} else if (cb.cb_all) {
+	} else if (upgradeall) {
 		if (argc !=3D 0) {
 			(void) fprintf(stderr, gettext("-a option should not "
 			    "be used along with a pool name\n"));
@@ -4573,9 +4800,25 @@
=20
 	(void) printf(gettext("This system supports ZFS pool feature "
 	    "flags.\n\n"));
-	cb.cb_first =3D B_TRUE;
 	if (showversions) {
-		(void) printf(gettext("The following versions are "
+		int i;
+
+		(void) printf(gettext("The following features are "
+		    "supported:\n\n"));
+		(void) printf(gettext("FEAT DESCRIPTION\n"));
+		(void) printf("----------------------------------------------"
+		    "---------------\n");
+		for (i =3D 0; i < SPA_FEATURES; i++) {
+			zfeature_info_t *fi =3D &spa_feature_table[i];
+			const char *ro =3D fi->fi_can_readonly ?
+			    " (read-only compatible)" : "";
+
+			(void) printf("%-37s%s\n", fi->fi_uname, ro);
+			(void) printf("     %s\n", fi->fi_desc);
+		}
+		(void) printf("\n");
+
+		(void) printf(gettext("The following legacy versions are also "
 		    "supported:\n\n"));
 		(void) printf(gettext("VER  DESCRIPTION\n"));
 		(void) printf("---  -----------------------------------------"
@@ -4618,32 +4861,44 @@
 		(void) printf(gettext("\nFor more information on a particular "
 		    "version, including supported releases,\n"));
 		(void) printf(gettext("see the ZFS Administration Guide.\n\n"));
-	} else if (argc =3D=3D 0) {
-		int notfound;
-
+	} else if (argc =3D=3D 0 && upgradeall) {
+		cb.cb_first =3D B_TRUE;
 		ret =3D zpool_iter(g_zfs, upgrade_cb, &cb);
-		notfound =3D cb.cb_first;
-
-		if (!cb.cb_all && ret =3D=3D 0) {
-			if (!cb.cb_first)
-				(void) printf("\n");
-			cb.cb_first =3D B_TRUE;
-			cb.cb_newer =3D B_TRUE;
-			ret =3D zpool_iter(g_zfs, upgrade_cb, &cb);
-			if (!cb.cb_first) {
-				notfound =3D B_FALSE;
-				(void) printf("\n");
+		if (ret =3D=3D 0 && cb.cb_first) {
+			if (cb.cb_version =3D=3D SPA_VERSION) {
+				(void) printf(gettext("All pools are already "
+				    "formatted using feature flags.\n\n"));
+				(void) printf(gettext("Every feature flags "
+				    "pool already has all supported features "
+				    "enabled.\n"));
+			} else {
+				(void) printf(gettext("All pools are already "
+				    "formatted with version %llu or higher.\n"),
+				    cb.cb_version);
 			}
 		}
-
-		if (ret =3D=3D 0) {
-			if (notfound)
-				(void) printf(gettext("All pools are formatted "
-				    "using this version.\n"));
-			else if (!cb.cb_all)
-				(void) printf(gettext("Use 'zpool upgrade -v' "
-				    "for a list of available versions and "
-				    "their associated\nfeatures.\n"));
+	} else if (argc =3D=3D 0) {
+		cb.cb_first =3D B_TRUE;
+		ret =3D zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
+		assert(ret =3D=3D 0);
+
+		if (cb.cb_first) {
+			(void) printf(gettext("All pools are formatted "
+			    "using feature flags.\n\n"));
+		} else {
+			(void) printf(gettext("\nUse 'zpool upgrade -v' "
+			    "for a list of available legacy versions.\n"));
+		}
+
+		cb.cb_first =3D B_TRUE;
+		ret =3D zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
+		assert(ret =3D=3D 0);
+
+		if (cb.cb_first) {
+			(void) printf(gettext("Every feature flags pool has "
+			    "all supported features enabled.\n"));
+		} else {
+			(void) printf(gettext("\n"));
 		}
 	} else {
 		ret =3D for_each_pool(argc, argv, B_FALSE, NULL,
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/contrib/opensolaris/lib/libd=
trace/common/dt_proc.c
--- a/head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c	Mon Jul =
30 11:44:18 2012 +0300
+++ b/head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c	Fri Aug =
10 14:19:25 2012 +0300
@@ -942,7 +942,8 @@
 		    (int)dpr->dpr_pid, strerror(err));
 	}
=20
-	(void) pthread_mutex_unlock(&dpr->dpr_lock);
+	if (err =3D=3D 0)
+		(void) pthread_mutex_unlock(&dpr->dpr_lock);
 	(void) pthread_attr_destroy(&a);
=20
 	return (err);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/contrib/opensolaris/lib/libz=
fs/common/libzfs.h
--- a/head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -316,7 +316,8 @@
 	 * requiring administrative attention.  There is no corresponding
 	 * message ID.
 	 */
-	ZPOOL_STATUS_VERSION_OLDER,	/* older on-disk version */
+	ZPOOL_STATUS_VERSION_OLDER,	/* older legacy on-disk version */
+	ZPOOL_STATUS_FEAT_DISABLED,	/* supported features are disabled */
 	ZPOOL_STATUS_RESILVERING,	/* device being resilvered */
 	ZPOOL_STATUS_OFFLINE_DEV,	/* device online */
 	ZPOOL_STATUS_REMOVED_DEV,	/* removed device */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/contrib/opensolaris/lib/libz=
fs/common/libzfs_status.c
--- a/head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c	Fri A=
ug 10 14:19:25 2012 +0300
@@ -44,6 +44,7 @@
 #include <string.h>
 #include <unistd.h>
 #include "libzfs_impl.h"
+#include "zfeature_common.h"
=20
 /*
  * Message ID table.  This must be kept in sync with the ZPOOL_STATUS_* de=
fines
@@ -319,6 +320,30 @@
 	if (SPA_VERSION_IS_SUPPORTED(version) && version !=3D SPA_VERSION)
 		return (ZPOOL_STATUS_VERSION_OLDER);
=20
+	/*
+	 * Usable pool with disabled features
+	 */
+	if (version >=3D SPA_VERSION_FEATURES) {
+		int i;
+		nvlist_t *feat;
+
+		if (isimport) {
+			feat =3D fnvlist_lookup_nvlist(config,
+			    ZPOOL_CONFIG_LOAD_INFO);
+			feat =3D fnvlist_lookup_nvlist(feat,
+			    ZPOOL_CONFIG_ENABLED_FEAT);
+		} else {
+			feat =3D fnvlist_lookup_nvlist(config,
+			    ZPOOL_CONFIG_FEATURE_STATS);
+		}
+
+		for (i =3D 0; i < SPA_FEATURES; i++) {
+			zfeature_info_t *fi =3D &spa_feature_table[i];
+			if (!nvlist_exists(feat, fi->fi_guid))
+				return (ZPOOL_STATUS_FEAT_DISABLED);
+		}
+	}
+
 	return (ZPOOL_STATUS_OK);
 }
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/cddl/lib/libzfs/Makefile
--- a/head/cddl/lib/libzfs/Makefile	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/cddl/lib/libzfs/Makefile	Fri Aug 10 14:19:25 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/cddl/lib/libzfs/Makefile 236884 2012-06-11 11:35:22Z mm $
+# $FreeBSD: head/cddl/lib/libzfs/Makefile 238926 2012-07-30 23:14:24Z mm $
=20
 .PATH: ${.CURDIR}/../../../cddl/compat/opensolaris/misc
 .PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
@@ -6,8 +6,8 @@
 .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
=20
 LIB=3D	zfs
-DPADD=3D	${LIBMD} ${LIBPTHREAD} ${LIBUMEM} ${LIBUTIL} ${LIBM}
-LDADD=3D	-lmd -lpthread -lumem -lutil -lm
+DPADD=3D	${LIBMD} ${LIBPTHREAD} ${LIBUMEM} ${LIBUTIL} ${LIBM} ${LIBNVPAIR}
+LDADD=3D	-lmd -lpthread -lumem -lutil -lm -lnvpair
=20
 SRCS=3D	deviceid.c \
 	fsshare.c \
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/LICENSE.TXT
--- a/head/contrib/compiler-rt/LICENSE.TXT	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/LICENSE.TXT	Fri Aug 10 14:19:25 2012 +0300
@@ -94,5 +94,4 @@
=20
 Program             Directory
 -------             ---------
-sysinfo             lib/asan/sysinfo
-mach_override       lib/asan/mach_override
+mach_override       lib/interception/mach_override
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/absvti2.c
--- a/head/contrib/compiler-rt/lib/absvti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/absvti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: absolute value */
=20
 /* Effects: aborts if abs(x) < 0 */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/adddf3.c
--- a/head/contrib/compiler-rt/lib/adddf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/adddf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -15,7 +15,7 @@
 #define DOUBLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(dadd, adddf3);
+ARM_EABI_FNALIAS(dadd, adddf3)
=20
 COMPILER_RT_ABI fp_t
 __adddf3(fp_t a, fp_t b) {
@@ -85,7 +85,7 @@
    =20
     // Shift the significand of b by the difference in exponents, with a s=
ticky
     // bottom bit to get rounding correct.
-    const int align =3D aExponent - bExponent;
+    const unsigned int align =3D aExponent - bExponent;
     if (align) {
         if (align < typeWidth) {
             const bool sticky =3D bSignificand << (typeWidth - align);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/addsf3.c
--- a/head/contrib/compiler-rt/lib/addsf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/addsf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -15,7 +15,7 @@
 #define SINGLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(fadd, addsf3);
+ARM_EABI_FNALIAS(fadd, addsf3)
=20
 fp_t __addsf3(fp_t a, fp_t b) {
=20
@@ -84,7 +84,7 @@
    =20
     // Shift the significand of b by the difference in exponents, with a s=
ticky
     // bottom bit to get rounding correct.
-    const int align =3D aExponent - bExponent;
+    const unsigned int align =3D aExponent - bExponent;
     if (align) {
         if (align < typeWidth) {
             const bool sticky =3D bSignificand << (typeWidth - align);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/addvti3.c
--- a/head/contrib/compiler-rt/lib/addvti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/addvti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: a + b */
=20
 /* Effects: aborts if a + b overflows */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_idivmod.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_idivmod.S	Fri Aug 10 14:19:25 =
2012 +0300
@@ -0,0 +1,27 @@
+//=3D=3D=3D-- aeabi_idivmod.S - EABI idivmod implementation --------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+// struct { int quot, int rem} __aeabi_idivmod(int numerator, int denomina=
tor) {
+//   int rem, quot;
+//   quot =3D __divmodsi4(numerator, denominator, &rem);
+//   return {quot, rem};
+// }
+
+        .syntax unified
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
+        push    { lr }
+        sub     sp, sp, #4
+        mov     r2, sp
+        bl      SYMBOL_NAME(__divmodsi4)
+        ldr     r1, [sp]
+        add     sp, sp, #4
+        pop     { pc }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_ldivmod.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_ldivmod.S	Fri Aug 10 14:19:25 =
2012 +0300
@@ -0,0 +1,30 @@
+//=3D=3D=3D-- aeabi_ldivmod.S - EABI ldivmod implementation --------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+// struct { int64_t quot, int64_t rem}
+//        __aeabi_ldivmod(int64_t numerator, int64_t denominator) {
+//   int64_t rem, quot;
+//   quot =3D __divmoddi4(numerator, denominator, &rem);
+//   return {quot, rem};
+// }
+
+        .syntax unified
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
+        push    {r11, lr}
+        sub     sp, sp, #16
+        add     r12, sp, #8
+        str     r12, [sp]
+        bl      SYMBOL_NAME(__divmoddi4)
+        ldr     r2, [sp, #8]
+        ldr     r3, [sp, #12]
+        add     sp, sp, #16
+        pop     {r11, pc}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_memcmp.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_memcmp.S	Fri Aug 10 14:19:25 2=
012 +0300
@@ -0,0 +1,19 @@
+//=3D=3D=3D-- aeabi_memcmp.S - EABI memcmp implementation ----------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+//  void __aeabi_memcmp(void *dest, void *src, size_t n) { memcmp(dest, sr=
c, n); }
+
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memcmp)
+        b       memcmp
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_memcpy.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_memcpy.S	Fri Aug 10 14:19:25 2=
012 +0300
@@ -0,0 +1,19 @@
+//=3D=3D=3D-- aeabi_memcpy.S - EABI memcpy implementation ----------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+//  void __aeabi_memcpy(void *dest, void *src, size_t n) { memcpy(dest, sr=
c, n); }
+
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memcpy)
+        b       memcpy
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_memmove.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_memmove.S	Fri Aug 10 14:19:25 =
2012 +0300
@@ -0,0 +1,19 @@
+//=3D=3D=3D-- aeabi_memmove.S - EABI memmove implementation --------------=
------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
------=3D=3D=3D//
+
+#include "../assembly.h"
+
+//  void __aeabi_memmove(void *dest, void *src, size_t n) { memmove(dest, =
src, n); }
+
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memmove)
+        b       memmove
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_memset.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_memset.S	Fri Aug 10 14:19:25 2=
012 +0300
@@ -0,0 +1,32 @@
+//=3D=3D=3D-- aeabi_memset.S - EABI memset implementation ----------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+//  void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n);=
 }
+//  void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0)=
; }
+
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
+        mov     r3, r1
+        mov     r1, r2
+        mov     r2, r3
+        b       memset
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
+       =20
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
+        mov     r2, r1
+        mov     r1, #0
+        b       memset
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
+
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_uidivmod.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_uidivmod.S	Fri Aug 10 14:19:25=
 2012 +0300
@@ -0,0 +1,28 @@
+//=3D=3D=3D-- aeabi_uidivmod.S - EABI uidivmod implementation ------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+// struct { unsigned quot, unsigned rem}
+//        __aeabi_uidivmod(unsigned numerator, unsigned denominator) {
+//   unsigned rem, quot;
+//   quot =3D __udivmodsi4(numerator, denominator, &rem);
+//   return {quot, rem};
+// }
+
+        .syntax unified
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
+        push    { lr }
+        sub     sp, sp, #4
+        mov     r2, sp
+        bl      SYMBOL_NAME(__udivmodsi4)
+        ldr     r1, [sp]
+        add     sp, sp, #4
+        pop     { pc }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/arm/aeabi=
_uldivmod.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/arm/aeabi_uldivmod.S	Fri Aug 10 14:19:25=
 2012 +0300
@@ -0,0 +1,30 @@
+//=3D=3D=3D-- aeabi_uldivmod.S - EABI uldivmod implementation ------------=
-------=3D=3D=3D//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois=
 Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D//
+
+#include "../assembly.h"
+
+// struct { uint64_t quot, uint64_t rem}
+//        __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) {
+//   uint64_t rem, quot;
+//   quot =3D __udivmoddi4(numerator, denominator, &rem);
+//   return {quot, rem};
+// }
+
+        .syntax unified
+        .align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
+        push	{r11, lr}
+        sub	sp, sp, #16
+        add	r12, sp, #8
+        str	r12, [sp]
+        bl	SYMBOL_NAME(__udivmoddi4)
+        ldr	r2, [sp, #8]
+        ldr	r3, [sp, #12]
+        add	sp, sp, #16
+        pop	{r11, pc}
\ No newline at end of file
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ashldi3.c
--- a/head/contrib/compiler-rt/lib/ashldi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ashldi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,7 +18,7 @@
=20
 /* Precondition:  0 <=3D b < bits_in_dword */
=20
-ARM_EABI_FNALIAS(llsl, ashldi3);
+ARM_EABI_FNALIAS(llsl, ashldi3)
=20
 COMPILER_RT_ABI di_int
 __ashldi3(di_int a, si_int b)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ashlti3.c
--- a/head/contrib/compiler-rt/lib/ashlti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ashlti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: a << b */
=20
 /* Precondition:  0 <=3D b < bits_in_tword */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ashrdi3.c
--- a/head/contrib/compiler-rt/lib/ashrdi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ashrdi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,7 +18,7 @@
=20
 /* Precondition:  0 <=3D b < bits_in_dword */
=20
-ARM_EABI_FNALIAS(lasr, ashrdi3);
+ARM_EABI_FNALIAS(lasr, ashrdi3)
=20
 COMPILER_RT_ABI di_int
 __ashrdi3(di_int a, si_int b)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ashrti3.c
--- a/head/contrib/compiler-rt/lib/ashrti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ashrti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: arithmetic a >> b */
=20
 /* Precondition:  0 <=3D b < bits_in_tword */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/assembly.h
--- a/head/contrib/compiler-rt/lib/assembly.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/assembly.h	Fri Aug 10 14:19:25 2012 +0300
@@ -25,9 +25,11 @@
 #if defined(__APPLE__)
 #define HIDDEN_DIRECTIVE .private_extern
 #define LOCAL_LABEL(name) L_##name
+#define FILE_LEVEL_DIRECTIVE  .subsections_via_symbols
 #else
 #define HIDDEN_DIRECTIVE .hidden
 #define LOCAL_LABEL(name) .L_##name
+#define FILE_LEVEL_DIRECTIVE =20
 #endif
=20
 #define GLUE2(a, b) a ## b
@@ -42,6 +44,7 @@
 #endif
=20
 #define DEFINE_COMPILERRT_FUNCTION(name)                   \
+  FILE_LEVEL_DIRECTIVE     SEPARATOR                       \
   .globl SYMBOL_NAME(name) SEPARATOR                       \
   DECLARE_SYMBOL_VISIBILITY(name)                          \
   SYMBOL_NAME(name):
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/atomic.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/atomic.c	Fri Aug 10 14:19:25 2012 +0300
@@ -0,0 +1,315 @@
+/*=3D=3D=3D-- atomic.c - Implement support functions for atomic operations=
.------=3D=3D=3D
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois=
 Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D
+ *
+ *  atomic.c defines a set of functions for performing atomic accesses on
+ *  arbitrary-sized memory locations.  This design uses locks that should
+ *  be fast in the uncontended case, for two reasons:
+ *=20
+ *  1) This code must work with C programs that do not link to anything
+ *     (including pthreads) and so it should not depend on any pthread
+ *     functions.
+ *  2) Atomic operations, rather than explicit mutexes, are most commonly =
used
+ *     on code where contended operations are rate.
+ *=20
+ *  To avoid needing a per-object lock, this code allocates an array of
+ *  locks and hashes the object pointers to find the one that it should us=
e.
+ *  For operations that must be atomic on two locations, the lower lock is
+ *  always acquired first, to avoid deadlock.
+ *
+ *=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+// Clang objects if you redefine a builtin.  This little hack allows us to
+// define a function with the same name as an intrinsic.
+#pragma redefine_extname __atomic_load_c __atomic_load
+#pragma redefine_extname __atomic_store_c __atomic_store
+#pragma redefine_extname __atomic_exchange_c __atomic_exchange
+#pragma redefine_extname __atomic_compare_exchange_c __atomic_compare_exch=
ange
+
+/// Number of locks.  This allocates one page on 32-bit platforms, two on
+/// 64-bit.  This can be specified externally if a different trade between
+/// memory usage and contention probability is required for a given platfo=
rm.
+#ifndef SPINLOCK_COUNT
+#define SPINLOCK_COUNT (1<<10)
+#endif
+static const long SPINLOCK_MASK =3D SPINLOCK_COUNT - 1;
+
+//////////////////////////////////////////////////////////////////////////=
//////
+// Platform-specific lock implementation.  Falls back to spinlocks if none=
 is
+// defined.  Each platform should define the Lock type, and corresponding
+// lock() and unlock() functions.
+//////////////////////////////////////////////////////////////////////////=
//////
+#ifdef __FreeBSD__
+#include <errno.h>
+#include <sys/types.h>
+#include <machine/atomic.h>
+#include <sys/umtx.h>
+typedef struct _usem Lock;
+inline static void unlock(Lock *l) {
+  __c11_atomic_store((_Atomic(uint32_t)*)&l->_count, 1, __ATOMIC_RELEASE);
+  __c11_atomic_thread_fence(__ATOMIC_SEQ_CST);
+  if (l->_has_waiters)
+      _umtx_op(l, UMTX_OP_SEM_WAKE, 1, 0, 0);
+}
+inline static void lock(Lock *l) {
+  uint32_t old =3D 1;
+  while (!__c11_atomic_compare_exchange_weak((_Atomic(uint32_t)*)&l->_coun=
t, &old,
+        0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
+    _umtx_op(l, UMTX_OP_SEM_WAIT, 0, 0, 0);
+    old =3D 1;
+  }
+}
+/// locks for atomic operations
+static Lock locks[SPINLOCK_COUNT] =3D { [0 ...  SPINLOCK_COUNT-1] =3D {0,1=
,0} };
+#else
+typedef _Atomic(uintptr_t) Lock;
+/// Unlock a lock.  This is a release operation.
+inline static void unlock(Lock *l) {
+  __c11_atomic_store(l, 0, __ATOMIC_RELEASE);
+}
+/// Locks a lock.  In the current implementation, this is potentially
+/// unbounded in the contended case.
+inline static void lock(Lock *l) {
+  uintptr_t old =3D 0;
+  while (!__c11_atomic_compare_exchange_weak(l, &old, 1, __ATOMIC_ACQUIRE,
+        __ATOMIC_RELAXED))
+    old =3D 0;
+}
+/// locks for atomic operations
+static Lock locks[SPINLOCK_COUNT];
+#endif
+
+
+/// Returns a lock to use for a given pointer. =20
+static inline Lock *lock_for_pointer(void *ptr) {
+  intptr_t hash =3D (intptr_t)ptr;
+  // Disregard the lowest 4 bits.  We want all values that may be part of =
the
+  // same memory operation to hash to the same value and therefore use the=
 same
+  // lock. =20
+  hash >>=3D 4;
+  // Use the next bits as the basis for the hash
+  intptr_t low =3D hash & SPINLOCK_MASK;
+  // Now use the high(er) set of bits to perturb the hash, so that we don't
+  // get collisions from atomic fields in a single object
+  hash >>=3D 16;
+  hash ^=3D low;
+  // Return a pointer to the word to use
+  return locks + (hash & SPINLOCK_MASK);
+}
+
+/// Macros for determining whether a size is lock free.  Clang can not yet
+/// codegen __atomic_is_lock_free(16), so for now we assume 16-byte values=
 are
+/// not lock free.
+#define IS_LOCK_FREE_1 __c11_atomic_is_lock_free(1)
+#define IS_LOCK_FREE_2 __c11_atomic_is_lock_free(2)
+#define IS_LOCK_FREE_4 __c11_atomic_is_lock_free(4)
+#define IS_LOCK_FREE_8 __c11_atomic_is_lock_free(8)
+#define IS_LOCK_FREE_16 0
+
+/// Macro that calls the compiler-generated lock-free versions of functions
+/// when they exist.
+#define LOCK_FREE_CASES() \
+  do {\
+  switch (size) {\
+    case 2:\
+      if (IS_LOCK_FREE_2) {\
+        LOCK_FREE_ACTION(uint16_t);\
+      }\
+    case 4:\
+      if (IS_LOCK_FREE_4) {\
+        LOCK_FREE_ACTION(uint32_t);\
+      }\
+    case 8:\
+      if (IS_LOCK_FREE_8) {\
+        LOCK_FREE_ACTION(uint64_t);\
+      }\
+    case 16:\
+      if (IS_LOCK_FREE_16) {\
+        /* FIXME: __uint128_t isn't available on 32 bit platforms.
+        LOCK_FREE_ACTION(__uint128_t);*/\
+      }\
+  }\
+  } while (0)
+
+
+/// An atomic load operation.  This is atomic with respect to the source
+/// pointer only.
+void __atomic_load_c(int size, void *src, void *dest, int model) {
+#define LOCK_FREE_ACTION(type) \
+    *((type*)dest) =3D __c11_atomic_load((_Atomic(type)*)src, model);\
+    return;
+  LOCK_FREE_CASES();
+#undef LOCK_FREE_ACTION
+  Lock *l =3D lock_for_pointer(src);
+  lock(l);
+  memcpy(dest, src, size);
+  unlock(l);
+}
+
+/// An atomic store operation.  This is atomic with respect to the destina=
tion
+/// pointer only.
+void __atomic_store_c(int size, void *dest, void *src, int model) {
+#define LOCK_FREE_ACTION(type) \
+    __c11_atomic_store((_Atomic(type)*)dest, *(type*)dest, model);\
+    return;
+  LOCK_FREE_CASES();
+#undef LOCK_FREE_ACTION
+  Lock *l =3D lock_for_pointer(dest);
+  lock(l);
+  memcpy(dest, src, size);
+  unlock(l);
+}
+
+/// Atomic compare and exchange operation.  If the value at *ptr is identi=
cal
+/// to the value at *expected, then this copies value at *desired to *ptr.=
  If
+/// they  are not, then this stores the current value from *ptr in *expect=
ed.
+///
+/// This function returns 1 if the exchange takes place or 0 if it fails.=20
+int __atomic_compare_exchange_c(int size, void *ptr, void *expected,
+    void *desired, int success, int failure) {
+#define LOCK_FREE_ACTION(type) \
+  return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, (type*)=
expected,\
+      *(type*)desired, success, failure)
+  LOCK_FREE_CASES();
+#undef LOCK_FREE_ACTION
+  Lock *l =3D lock_for_pointer(ptr);
+  lock(l);
+  if (memcmp(ptr, expected, size) =3D=3D 0) {
+    memcpy(ptr, desired, size);
+    unlock(l);
+    return 1;
+  }
+  memcpy(expected, ptr, size);
+  unlock(l);
+  return 0;
+}
+
+/// Performs an atomic exchange operation between two pointers.  This is a=
tomic
+/// with respect to the target address.
+void __atomic_exchange_c(int size, void *ptr, void *val, void *old, int mo=
del) {
+#define LOCK_FREE_ACTION(type) \
+    *(type*)old =3D __c11_atomic_exchange((_Atomic(type)*)ptr, *(type*)val=
,\
+        model);\
+    return;
+  LOCK_FREE_CASES();
+#undef LOCK_FREE_ACTION
+  Lock *l =3D lock_for_pointer(ptr);
+  lock(l);
+  memcpy(old, ptr, size);
+  memcpy(ptr, val, size);
+  unlock(l);
+}
+
+//////////////////////////////////////////////////////////////////////////=
//////
+// Where the size is known at compile time, the compiler may emit calls to
+// specialised versions of the above functions.
+//////////////////////////////////////////////////////////////////////////=
//////
+#define OPTIMISED_CASES\
+  OPTIMISED_CASE(1, IS_LOCK_FREE_1, uint8_t)\
+  OPTIMISED_CASE(2, IS_LOCK_FREE_2, uint16_t)\
+  OPTIMISED_CASE(4, IS_LOCK_FREE_4, uint32_t)\
+  OPTIMISED_CASE(8, IS_LOCK_FREE_8, uint64_t)\
+  /* FIXME: __uint128_t isn't available on 32 bit platforms.
+  OPTIMISED_CASE(16, IS_LOCK_FREE_16, __uint128_t)*/\
+
+#define OPTIMISED_CASE(n, lockfree, type)\
+type __atomic_load_##n(type *src, int model) {\
+  if (lockfree)\
+    return __c11_atomic_load((_Atomic(type)*)src, model);\
+  Lock *l =3D lock_for_pointer(src);\
+  lock(l);\
+  type val =3D *src;\
+  unlock(l);\
+  return val;\
+}
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+
+#define OPTIMISED_CASE(n, lockfree, type)\
+void  __atomic_store_##n(type *dest, type val, int model) {\
+  if (lockfree) {\
+    __c11_atomic_store((_Atomic(type)*)dest, val, model);\
+    return;\
+  }\
+  Lock *l =3D lock_for_pointer(dest);\
+  lock(l);\
+  *dest =3D val;\
+  unlock(l);\
+  return;\
+}
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+
+#define OPTIMISED_CASE(n, lockfree, type)\
+type __atomic_exchange_##n(type *dest, type val, int model) {\
+  if (lockfree)\
+    return __c11_atomic_exchange((_Atomic(type)*)dest, val, model);\
+  Lock *l =3D lock_for_pointer(dest);\
+  lock(l);\
+  type tmp =3D *dest;\
+  *dest =3D val;\
+  unlock(l);\
+  return tmp;\
+}
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+
+#define OPTIMISED_CASE(n, lockfree, type)\
+int __atomic_compare_exchange_##n(type *ptr, type *expected, type desired,\
+    int success, int failure) {\
+  if (lockfree)\
+    return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, expec=
ted, desired,\
+        success, failure);\
+  Lock *l =3D lock_for_pointer(ptr);\
+  lock(l);\
+  if (*ptr =3D=3D *expected) {\
+    *ptr =3D desired;\
+    unlock(l);\
+    return 1;\
+  }\
+  *expected =3D *ptr;\
+  unlock(l);\
+  return 0;\
+}
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+
+//////////////////////////////////////////////////////////////////////////=
//////
+// Atomic read-modify-write operations for integers of various sizes.
+//////////////////////////////////////////////////////////////////////////=
//////
+#define ATOMIC_RMW(n, lockfree, type, opname, op) \
+type __atomic_fetch_##opname##_##n(type *ptr, type val, int model) {\
+  if (lockfree) \
+    return __c11_atomic_fetch_##opname((_Atomic(type)*)ptr, val, model);\
+  Lock *l =3D lock_for_pointer(ptr);\
+  lock(l);\
+  type tmp =3D *ptr;\
+  *ptr =3D tmp op val;\
+  unlock(l);\
+  return tmp;\
+}
+
+#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, ad=
d, +)
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, su=
b, -)
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, an=
d, &)
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, or=
, |)
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, xo=
r, ^)
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/clzti2.c
--- a/head/contrib/compiler-rt/lib/clzti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/clzti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: the number of leading 0-bits */
=20
 /* Precondition: a !=3D 0 */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/cmpti2.c
--- a/head/contrib/compiler-rt/lib/cmpti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/cmpti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns:  if (a <  b) returns 0
  *           if (a =3D=3D b) returns 1
  *           if (a >  b) returns 2
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ctzti2.c
--- a/head/contrib/compiler-rt/lib/ctzti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ctzti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: the number of trailing 0-bits */
=20
 /* Precondition: a !=3D 0 */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/divdf3.c
--- a/head/contrib/compiler-rt/lib/divdf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/divdf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -19,7 +19,7 @@
 #define DOUBLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(ddiv, divdf3);
+ARM_EABI_FNALIAS(ddiv, divdf3)
=20
 fp_t __divdf3(fp_t a, fp_t b) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/divmoddi4=
.c
--- a/head/contrib/compiler-rt/lib/divmoddi4.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/divmoddi4.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -16,8 +16,6 @@
=20
 extern COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
=20
-ARM_EABI_FNALIAS(ldivmod, divmoddi4);
-
 /* Returns: a / b, *rem =3D a % b  */
=20
 COMPILER_RT_ABI di_int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/divsf3.c
--- a/head/contrib/compiler-rt/lib/divsf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/divsf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -19,7 +19,7 @@
 #define SINGLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(fdiv, divsf3);
+ARM_EABI_FNALIAS(fdiv, divsf3)
=20
 fp_t __divsf3(fp_t a, fp_t b) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/divsi3.c
--- a/head/contrib/compiler-rt/lib/divsi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/divsi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,7 +18,7 @@
=20
 /* Returns: a / b */
=20
-ARM_EABI_FNALIAS(idiv, divsi3);
+ARM_EABI_FNALIAS(idiv, divsi3)
=20
 COMPILER_RT_ABI si_int
 __divsi3(si_int a, si_int b)
@@ -29,5 +29,11 @@
     a =3D (a ^ s_a) - s_a;                         /* negate if s_a =3D=3D=
 -1 */
     b =3D (b ^ s_b) - s_b;                         /* negate if s_b =3D=3D=
 -1 */
     s_a ^=3D s_b;                                  /* sign of quotient */
-    return (__udivsi3(a, b) ^ s_a) - s_a;        /* negate if s_a =3D=3D -=
1 */
+    /*
+     * On CPUs without unsigned hardware division support,
+     *  this calls __udivsi3 (notice the cast to su_int).
+     * On CPUs with unsigned hardware division support,
+     *  this uses the unsigned division instruction.
+     */
+    return ((su_int)a/(su_int)b ^ s_a) - s_a;    /* negate if s_a =3D=3D -=
1 */
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/divti3.c
--- a/head/contrib/compiler-rt/lib/divti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/divti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
=20
 /* Returns: a / b */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/extendsfd=
f2.c
--- a/head/contrib/compiler-rt/lib/extendsfdf2.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/extendsfdf2.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -66,7 +66,7 @@
=20
 // End helper routines.  Conversion implementation follows.
=20
-ARM_EABI_FNALIAS(f2d, extendsfdf2);
+ARM_EABI_FNALIAS(f2d, extendsfdf2)
=20
 dst_t __extendsfdf2(src_t a) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ffsti2.c
--- a/head/contrib/compiler-rt/lib/ffsti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ffsti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: the index of the least significant 1-bit in a, or
  * the value zero if a is zero. The least significant bit is index one.
  */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixdfdi.c
--- a/head/contrib/compiler-rt/lib/fixdfdi.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixdfdi.c	Fri Aug 10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
=20
 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm=
 mmmm mmmm */
=20
-ARM_EABI_FNALIAS(d2lz, fixdfdi);
+ARM_EABI_FNALIAS(d2lz, fixdfdi)
=20
 di_int
 __fixdfdi(double a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixdfsi.c
--- a/head/contrib/compiler-rt/lib/fixdfsi.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixdfsi.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,7 +18,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(d2iz, fixdfsi);
+ARM_EABI_FNALIAS(d2iz, fixdfsi)
=20
 int __fixdfsi(fp_t a) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixdfti.c
--- a/head/contrib/compiler-rt/lib/fixdfti.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixdfti.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a signed long long, rounding toward zero. */
=20
 /* Assumption: double is a IEEE 64 bit floating point type=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixsfdi.c
--- a/head/contrib/compiler-rt/lib/fixsfdi.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixsfdi.c	Fri Aug 10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
=20
 /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
=20
-ARM_EABI_FNALIAS(d2lz, fixsfdi);
+ARM_EABI_FNALIAS(d2lz, fixsfdi)
=20
 COMPILER_RT_ABI di_int
 __fixsfdi(float a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixsfsi.c
--- a/head/contrib/compiler-rt/lib/fixsfsi.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixsfsi.c	Fri Aug 10 14:19:25 2012 +0300
@@ -16,7 +16,7 @@
 #define SINGLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(f2iz, fixsfsi);
+ARM_EABI_FNALIAS(f2iz, fixsfsi)
=20
 COMPILER_RT_ABI int
 __fixsfsi(fp_t a) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixsfti.c
--- a/head/contrib/compiler-rt/lib/fixsfti.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixsfti.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a signed long long, rounding toward zero. */
=20
 /* Assumption: float is a IEEE 32 bit floating point type=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunsdfd=
i.c
--- a/head/contrib/compiler-rt/lib/fixunsdfdi.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunsdfdi.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -26,7 +26,7 @@
=20
 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm=
 mmmm mmmm */
=20
-ARM_EABI_FNALIAS(d2ulz, fixunsdfdi);
+ARM_EABI_FNALIAS(d2ulz, fixunsdfdi)
=20
 COMPILER_RT_ABI du_int
 __fixunsdfdi(double a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunsdfs=
i.c
--- a/head/contrib/compiler-rt/lib/fixunsdfsi.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunsdfsi.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -26,7 +26,7 @@
=20
 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm=
 mmmm mmmm */
=20
-ARM_EABI_FNALIAS(d2uiz, fixunsdfsi);
+ARM_EABI_FNALIAS(d2uiz, fixunsdfsi)
=20
 COMPILER_RT_ABI su_int
 __fixunsdfsi(double a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunsdft=
i.c
--- a/head/contrib/compiler-rt/lib/fixunsdfti.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunsdfti.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a unsigned long long, rounding toward zero.
  *          Negative values all become zero.
  */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunssfd=
i.c
--- a/head/contrib/compiler-rt/lib/fixunssfdi.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunssfdi.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -25,7 +25,7 @@
=20
 /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
=20
-ARM_EABI_FNALIAS(f2ulz, fixunssfdi);
+ARM_EABI_FNALIAS(f2ulz, fixunssfdi)
=20
 COMPILER_RT_ABI du_int
 __fixunssfdi(float a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunssfs=
i.c
--- a/head/contrib/compiler-rt/lib/fixunssfsi.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunssfsi.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -26,7 +26,7 @@
=20
 /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
=20
-ARM_EABI_FNALIAS(f2uiz, fixunssfsi);
+ARM_EABI_FNALIAS(f2uiz, fixunssfsi)
=20
 COMPILER_RT_ABI su_int
 __fixunssfsi(float a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunssft=
i.c
--- a/head/contrib/compiler-rt/lib/fixunssfti.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunssfti.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a unsigned long long, rounding toward zero.
  *          Negative values all become zero.
  */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixunsxft=
i.c
--- a/head/contrib/compiler-rt/lib/fixunsxfti.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/fixunsxfti.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a unsigned long long, rounding toward zero.
  *          Negative values all become zero.
  */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fixxfti.c
--- a/head/contrib/compiler-rt/lib/fixxfti.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fixxfti.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a signed long long, rounding toward zero. */
=20
 /* Assumption: long double is an intel 80 bit floating point type padded w=
ith 6 bytes
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatdidf=
.c
--- a/head/contrib/compiler-rt/lib/floatdidf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floatdidf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -22,7 +22,7 @@
=20
 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm=
 mmmm mmmm */
=20
-ARM_EABI_FNALIAS(l2d, floatdidf);
+ARM_EABI_FNALIAS(l2d, floatdidf)
=20
 #ifndef __SOFT_FP__
 /* Support for systems that have hardware floating-point; we'll set the in=
exact flag
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatdisf=
.c
--- a/head/contrib/compiler-rt/lib/floatdisf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floatdisf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -22,7 +22,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(l2f, floatdisf);
+ARM_EABI_FNALIAS(l2f, floatdisf)
=20
 COMPILER_RT_ABI float
 __floatdisf(di_int a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatsidf=
.c
--- a/head/contrib/compiler-rt/lib/floatsidf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floatsidf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -18,7 +18,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(i2d, floatsidf);
+ARM_EABI_FNALIAS(i2d, floatsidf)
=20
 fp_t __floatsidf(int a) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatsisf=
.c
--- a/head/contrib/compiler-rt/lib/floatsisf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floatsisf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -18,7 +18,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(i2f, floatsisf);
+ARM_EABI_FNALIAS(i2f, floatsisf)
=20
 fp_t __floatsisf(int a) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floattidf=
.c
--- a/head/contrib/compiler-rt/lib/floattidf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floattidf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */=20
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a double, rounding toward even.*/
=20
 /* Assumption: double is a IEEE 64 bit floating point type=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floattisf=
.c
--- a/head/contrib/compiler-rt/lib/floattisf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floattisf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a float, rounding toward even. */
=20
 /* Assumption: float is a IEEE 32 bit floating point type=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floattixf=
.c
--- a/head/contrib/compiler-rt/lib/floattixf.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/floattixf.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a long double, rounding toward even. */
=20
 /* Assumption: long double is a IEEE 80 bit floating point type padded to =
128 bits
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatundi=
df.c
--- a/head/contrib/compiler-rt/lib/floatundidf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatundidf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -22,7 +22,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(ul2d, floatundidf);
+ARM_EABI_FNALIAS(ul2d, floatundidf)
=20
 #ifndef __SOFT_FP__
 /* Support for systems that have hardware floating-point; we'll set the in=
exact flag
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatundi=
sf.c
--- a/head/contrib/compiler-rt/lib/floatundisf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatundisf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -22,7 +22,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(ul2f, floatundisf);
+ARM_EABI_FNALIAS(ul2f, floatundisf)
=20
 COMPILER_RT_ABI float
 __floatundisf(du_int a)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatunsi=
df.c
--- a/head/contrib/compiler-rt/lib/floatunsidf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatunsidf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -18,7 +18,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(ui2d, floatunsidf);
+ARM_EABI_FNALIAS(ui2d, floatunsidf)
=20
 fp_t __floatunsidf(unsigned int a) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatunsi=
sf.c
--- a/head/contrib/compiler-rt/lib/floatunsisf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatunsisf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -18,7 +18,7 @@
=20
 #include "int_lib.h"
=20
-ARM_EABI_FNALIAS(ui2f, floatunsisf);
+ARM_EABI_FNALIAS(ui2f, floatunsisf)
=20
 fp_t __floatunsisf(unsigned int a) {
    =20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatunti=
df.c
--- a/head/contrib/compiler-rt/lib/floatuntidf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatuntidf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a double, rounding toward even. */
=20
 /* Assumption: double is a IEEE 64 bit floating point type=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatunti=
sf.c
--- a/head/contrib/compiler-rt/lib/floatuntisf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatuntisf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a float, rounding toward even. */
=20
 /* Assumption: float is a IEEE 32 bit floating point type=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/floatunti=
xf.c
--- a/head/contrib/compiler-rt/lib/floatuntixf.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/floatuntixf.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: convert a to a long double, rounding toward even. */
=20
 /* Assumption: long double is a IEEE 80 bit floating point type padded to =
128 bits
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/fp_lib.h
--- a/head/contrib/compiler-rt/lib/fp_lib.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/fp_lib.h	Fri Aug 10 14:19:25 2012 +0300
@@ -124,7 +124,7 @@
     *lo =3D *lo << count;
 }
=20
-static inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, int coun=
t) {
+static inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned=
 int count) {
     if (count < typeWidth) {
         const bool sticky =3D *lo << (typeWidth - count);
         *lo =3D *hi << (typeWidth - count) | *lo >> count | sticky;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/int_endia=
nness.h
--- a/head/contrib/compiler-rt/lib/int_endianness.h	Mon Jul 30 11:44:18 201=
2 +0300
+++ b/head/contrib/compiler-rt/lib/int_endianness.h	Fri Aug 10 14:19:25 201=
2 +0300
@@ -31,7 +31,7 @@
=20
 /* .. */
=20
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||=
 defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||=
 defined(__DragonFly__) || defined(__minix)
 #include <sys/endian.h>
=20
 #if _BYTE_ORDER =3D=3D _BIG_ENDIAN
@@ -80,6 +80,13 @@
=20
 #endif /* GNU/Linux */
=20
+#if defined(_WIN32)
+
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+
+#endif /* Windows */
+
 /* . */
=20
 #if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/int_util.c
--- a/head/contrib/compiler-rt/lib/int_util.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/int_util.c	Fri Aug 10 14:19:25 2012 +0300
@@ -29,6 +29,19 @@
   panic("%s:%d: abort in %s", file, line, function);
 }
=20
+#elif __APPLE__ && !__STATIC__
+
+/* from libSystem.dylib */
+extern void __assert_rtn(const char *func, const char *file,=20
+                     int line, const char * message) __attribute__((noretu=
rn));
+
+__attribute__((weak))
+__attribute__((visibility("hidden")))
+void compilerrt_abort_impl(const char *file, int line, const char *functio=
n) {
+  __assert_rtn(function, file, line, "libcompiler_rt abort");
+}
+
+
 #else
=20
 /* Get the system definition of abort() */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/int_util.h
--- a/head/contrib/compiler-rt/lib/int_util.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/int_util.h	Fri Aug 10 14:19:25 2012 +0300
@@ -22,11 +22,8 @@
 /** \brief Trigger a program abort (or panic for kernel code). */
 #define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, \
                                                  __FUNCTION__)
+
 void compilerrt_abort_impl(const char *file, int line,
-                           const char *function)
-#ifndef KERNEL_USE
-  __attribute__((weak))
-#endif
-  __attribute__((noreturn)) __attribute__((visibility("hidden")));
+                           const char *function) __attribute__((noreturn));
=20
 #endif /* INT_UTIL_H */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/lshrdi3.c
--- a/head/contrib/compiler-rt/lib/lshrdi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/lshrdi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,7 +18,7 @@
=20
 /* Precondition:  0 <=3D b < bits_in_dword */
=20
-ARM_EABI_FNALIAS(llsr, lshrdi3);
+ARM_EABI_FNALIAS(llsr, lshrdi3)
=20
 COMPILER_RT_ABI di_int
 __lshrdi3(di_int a, si_int b)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/lshrti3.c
--- a/head/contrib/compiler-rt/lib/lshrti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/lshrti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: logical a >> b */
=20
 /* Precondition:  0 <=3D b < bits_in_tword */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/modti3.c
--- a/head/contrib/compiler-rt/lib/modti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/modti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
=20
 /*Returns: a % b */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/muldf3.c
--- a/head/contrib/compiler-rt/lib/muldf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/muldf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -15,7 +15,7 @@
 #define DOUBLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(dmul, muldf3);
+ARM_EABI_FNALIAS(dmul, muldf3)
=20
 COMPILER_RT_ABI fp_t
 __muldf3(fp_t a, fp_t b) {
@@ -96,7 +96,7 @@
         // a zero of the appropriate sign.  Mathematically there is no nee=
d to
         // handle this case separately, but we make it a special case to
         // simplify the shift logic.
-        const int shift =3D 1 - productExponent;
+        const unsigned int shift =3D 1U - (unsigned int)productExponent;
         if (shift >=3D typeWidth) return fromRep(productSign);
        =20
         // Otherwise, shift the significand of the result so that the round
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/muldi3.c
--- a/head/contrib/compiler-rt/lib/muldi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/muldi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -40,7 +40,7 @@
=20
 /* Returns: a * b */
=20
-ARM_EABI_FNALIAS(lmul, muldi3);
+ARM_EABI_FNALIAS(lmul, muldi3)
=20
 COMPILER_RT_ABI di_int
 __muldi3(di_int a, di_int b)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/muloti4.c
--- a/head/contrib/compiler-rt/lib/muloti4.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/muloti4.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: a * b */
=20
 /* Effects: sets *overflow to 1  if a * b overflows */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/mulsf3.c
--- a/head/contrib/compiler-rt/lib/mulsf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/mulsf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -15,7 +15,7 @@
 #define SINGLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(fmul, mulsf3);
+ARM_EABI_FNALIAS(fmul, mulsf3)
=20
 COMPILER_RT_ABI fp_t
 __mulsf3(fp_t a, fp_t b) {
@@ -92,7 +92,7 @@
     if (productExponent <=3D 0) {
         // Result is denormal before rounding, the exponent is zero and we
         // need to shift the significand.
-        wideRightShiftWithSticky(&productHi, &productLo, 1 - productExpone=
nt);
+        wideRightShiftWithSticky(&productHi, &productLo, 1U - (unsigned)pr=
oductExponent);
     }
    =20
     else {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/multi3.c
--- a/head/contrib/compiler-rt/lib/multi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/multi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: a * b */
=20
 static
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/mulvti3.c
--- a/head/contrib/compiler-rt/lib/mulvti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/mulvti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: a * b */
=20
 /* Effects: aborts if a * b overflows */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/negdf2.c
--- a/head/contrib/compiler-rt/lib/negdf2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/negdf2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -14,7 +14,7 @@
 #define DOUBLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(dneg, negdf2);
+ARM_EABI_FNALIAS(dneg, negdf2)
=20
 fp_t __negdf2(fp_t a) {
     return fromRep(toRep(a) ^ signBit);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/negsf2.c
--- a/head/contrib/compiler-rt/lib/negsf2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/negsf2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -14,7 +14,7 @@
 #define SINGLE_PRECISION
 #include "fp_lib.h"
=20
-ARM_EABI_FNALIAS(fneg, negsf2);
+ARM_EABI_FNALIAS(fneg, negsf2)
=20
 COMPILER_RT_ABI fp_t
 __negsf2(fp_t a) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/negti2.c
--- a/head/contrib/compiler-rt/lib/negti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/negti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: -a */
=20
 ti_int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/negvti2.c
--- a/head/contrib/compiler-rt/lib/negvti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/negvti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  *=3D=3D=3D---------------------------------------------------------------=
-------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: -a */
=20
 /* Effects: aborts if -a overflows */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/parityti2=
.c
--- a/head/contrib/compiler-rt/lib/parityti2.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/compiler-rt/lib/parityti2.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */=20
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: 1 if number of bits is odd else returns 0 */
=20
 si_int __paritydi2(di_int a);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/popcountt=
i2.c
--- a/head/contrib/compiler-rt/lib/popcountti2.c	Mon Jul 30 11:44:18 2012 +=
0300
+++ b/head/contrib/compiler-rt/lib/popcountti2.c	Fri Aug 10 14:19:25 2012 +=
0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: count of 1 bits */
=20
 si_int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/powitf2.c
--- a/head/contrib/compiler-rt/lib/powitf2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/powitf2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if _ARCH_PPC
=20
-#include "int_lib.h"
-
 /* Returns: a ^ b */
=20
 long double
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/subdf3.c
--- a/head/contrib/compiler-rt/lib/subdf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/subdf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,7 +18,7 @@
 fp_t COMPILER_RT_ABI __adddf3(fp_t a, fp_t b);
=20
=20
-ARM_EABI_FNALIAS(dsub, subdf3);
+ARM_EABI_FNALIAS(dsub, subdf3)
=20
 // Subtraction; flip the sign bit of b and add.
 COMPILER_RT_ABI fp_t
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/subsf3.c
--- a/head/contrib/compiler-rt/lib/subsf3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/subsf3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -17,7 +17,7 @@
=20
 fp_t COMPILER_RT_ABI __addsf3(fp_t a, fp_t b);
=20
-ARM_EABI_FNALIAS(fsub, subsf3);
+ARM_EABI_FNALIAS(fsub, subsf3)
=20
 // Subtraction; flip the sign bit of b and add.
 COMPILER_RT_ABI fp_t
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/subvti3.c
--- a/head/contrib/compiler-rt/lib/subvti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/subvti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns: a - b */
=20
 /* Effects: aborts if a - b overflows */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/truncdfsf=
2.c
--- a/head/contrib/compiler-rt/lib/truncdfsf2.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/truncdfsf2.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -64,7 +64,7 @@
=20
 // End helper routines.  Conversion implementation follows.
=20
-ARM_EABI_FNALIAS(d2f, truncdfsf2);
+ARM_EABI_FNALIAS(d2f, truncdfsf2)
=20
 COMPILER_RT_ABI dst_t
 __truncdfsf2(src_t a) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/ucmpti2.c
--- a/head/contrib/compiler-rt/lib/ucmpti2.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/ucmpti2.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Returns:  if (a <  b) returns 0
  *           if (a =3D=3D b) returns 1
  *           if (a >  b) returns 2
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/udivmoddi=
4.c
--- a/head/contrib/compiler-rt/lib/udivmoddi4.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/udivmoddi4.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -20,8 +20,6 @@
=20
 /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
=20
-ARM_EABI_FNALIAS(uldivmod, udivmoddi4);
-
 COMPILER_RT_ABI du_int
 __udivmoddi4(du_int a, du_int b, du_int* rem)
 {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/udivmodti=
4.c
--- a/head/contrib/compiler-rt/lib/udivmodti4.c	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/compiler-rt/lib/udivmodti4.c	Fri Aug 10 14:19:25 2012 +0=
300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */=20
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 /* Effects: if rem !=3D 0, *rem =3D a % b=20
  * Returns: a / b=20
  */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/udivsi3.c
--- a/head/contrib/compiler-rt/lib/udivsi3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/udivsi3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -18,8 +18,9 @@
=20
 /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
=20
-ARM_EABI_FNALIAS(uidiv, udivsi3);
+ARM_EABI_FNALIAS(uidiv, udivsi3)
=20
+/* This function should not call __divsi3! */
 COMPILER_RT_ABI su_int
 __udivsi3(su_int n, su_int d)
 {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/udivti3.c
--- a/head/contrib/compiler-rt/lib/udivti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/udivti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
=20
 /* Returns: a / b */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/compiler-rt/lib/umodti3.c
--- a/head/contrib/compiler-rt/lib/umodti3.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/compiler-rt/lib/umodti3.c	Fri Aug 10 14:19:25 2012 +0300
@@ -12,10 +12,10 @@
  * =3D=3D=3D--------------------------------------------------------------=
--------=3D=3D=3D
  */
=20
+#include "int_lib.h"
+
 #if __x86_64
=20
-#include "int_lib.h"
-
 tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
=20
 /* Returns: a % b */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/groff/tmac/doc-common
--- a/head/contrib/groff/tmac/doc-common	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/groff/tmac/doc-common	Fri Aug 10 14:19:25 2012 +0300
@@ -574,10 +574,7 @@
 .ds doc-operating-system-FreeBSD-8.0     8.0
 .ds doc-operating-system-FreeBSD-8.1     8.1
 .ds doc-operating-system-FreeBSD-8.2     8.2
-.ds doc-operating-system-FreeBSD-8.3     8.3
 .ds doc-operating-system-FreeBSD-9.0     9.0
-.ds doc-operating-system-FreeBSD-9.1     9.1
-.ds doc-operating-system-FreeBSD-10.0    10.0
 .
 .ds doc-operating-system-Darwin-8.0.0  8.0.0
 .ds doc-operating-system-Darwin-8.1.0  8.1.0
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/groff/tmac/doc-syms
--- a/head/contrib/groff/tmac/doc-syms	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/groff/tmac/doc-syms	Fri Aug 10 14:19:25 2012 +0300
@@ -661,7 +661,7 @@
 .as doc-str-St--susv3          " (\*[Lq]\*[doc-Tn-font-size]SUSv3\*[doc-st=
r-St]\*[Rq])
 .ds doc-str-St--svid4          System\~V Interface Definition, Fourth Edit=
ion
 .as doc-str-St--svid4          " (\*[Lq]\*[doc-Tn-font-size]SVID\*[doc-str=
-St]\^4\*[Rq])
-.ds doc-str-St--xbd5           \*[doc-Tn-font-size]X/Open\*[doc-str-St] Sy=
stem Interface Definitions Issue\~5
+.ds doc-str-St--xbd5           \*[doc-Tn-font-size]X/Open\*[doc-str-St] Ba=
se Definitions Issue\~5
 .as doc-str-St--xbd5           " (\*[Lq]\*[doc-Tn-font-size]XBD\*[doc-str-=
St]\^5\*[Rq])
 .ds doc-str-St--xcu5           \*[doc-Tn-font-size]X/Open\*[doc-str-St] Co=
mmands and Utilities Issue\~5
 .as doc-str-St--xcu5           " (\*[Lq]\*[doc-Tn-font-size]XCU\*[doc-str-=
St]\^5\*[Rq])
@@ -814,7 +814,6 @@
 .ds doc-str-Lb-librt       \*[Px] \*[doc-str-Lb]Real-time Library (librt, =
\-lrt)
 .ds doc-str-Lb-libsdp      Bluetooth Service Discovery Protocol User Libra=
ry (libsdp, \-lsdp)
 .ds doc-str-Lb-libssp      Buffer Overflow Protection Library (libssp, \-l=
ssp)
-.ds doc-str-Lb-libstdthreads C11 Threads Library (libstdthreads, \-lstdthr=
eads)
 .ds doc-str-Lb-libSystem   System Library (libSystem, \-lSystem)
 .ds doc-str-Lb-libtermcap  Termcap Access Library (libtermcap, \-ltermcap)
 .ds doc-str-Lb-libterminfo Terminal Information Library (libterminfo, \-lt=
erminfo)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/groff/tmac/doc.tmac
--- a/head/contrib/groff/tmac/doc.tmac	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/groff/tmac/doc.tmac	Fri Aug 10 14:19:25 2012 +0300
@@ -438,7 +438,7 @@
 .      \" last argument
 .      if (\n[doc-reg-dfr1] =3D=3D 4) \
 .        nop \|\-\c
-.      nop \f[]\s[0]\c
+.      nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c
 .      doc-print-and-reset
 .    \}
 .    el \{\
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/groff/tmac/groff_mdoc.man
--- a/head/contrib/groff/tmac/groff_mdoc.man	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/groff/tmac/groff_mdoc.man	Fri Aug 10 14:19:25 2012 +0300
@@ -1797,8 +1797,6 @@
 .Lb libsdp
 .It Li libssp
 .Lb libssp
-.It Li libstdthreads
-.Lb libstdthreads
 .It Li libSystem
 .Lb libSystem
 .It Li libtermcap
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/FREEBSD-Xlist
--- a/head/contrib/libarchive/FREEBSD-Xlist	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/FREEBSD-Xlist	Fri Aug 10 14:19:25 2012 +0300
@@ -1,4 +1,6 @@
-$FreeBSD: head/contrib/libarchive/FREEBSD-Xlist 232153 2012-02-25 10:58:02=
Z mm $
+.git
+.gitattributes
+.gitignore
 CMakeLists.txt
 CTestConfig.cmake
 INSTALL
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/FREEBSD-upgrade
--- a/head/contrib/libarchive/FREEBSD-upgrade	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/FREEBSD-upgrade	Fri Aug 10 14:19:25 2012 +0300
@@ -1,10 +1,10 @@
-$FreeBSD: head/contrib/libarchive/FREEBSD-upgrade 228835 2011-12-23 08:50:=
26Z mm $
+$FreeBSD: head/contrib/libarchive/FREEBSD-upgrade 238827 2012-07-27 08:28:=
44Z mm $
=20
 libarchive
=20
-The source code is pulled with svn:
+The source code is pulled with git:
=20
-	svn checkout http://libarchive.googlecode.com/svn/release/2.8
+	git clone -b release git://github.com/libarchive/libarchive.git
=20
 For the contrib directory files and directories were pruned by:
 =09
@@ -21,4 +21,4 @@
 branch (aka HEAD).  Never make local changes on the vendor branch.
=20
 mm at FreeBSD.org
-21-December-2011
+27-July-2012
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/NEWS
--- a/head/contrib/libarchive/NEWS	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/NEWS	Fri Aug 10 14:19:25 2012 +0300
@@ -1,14 +1,10 @@
-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
+Mar 27, 2012: libarchive 3.0.4 released
+
+Feb 05, 2012: libarchive development now hosted at GitHub.
+    http://libarchive.github.com/
+Feb 05, 2012: libarchive's issue tracker remains at Google Code.
+    http://code.google.com/p/libarchive/issues/list
+Feb 05, 2012: libarchive's mailing lists remain at Google Groups.
=20
 Dec 24, 2011: libarchive 3.0.2 released
 Dec 23, 2011: Various fixes merged from FreeBSD
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/README
--- a/head/contrib/libarchive/README	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/README	Fri Aug 10 14:19:25 2012 +0300
@@ -1,9 +1,14 @@
 README for libarchive bundle.
=20
 Questions?  Issues?
-   * http://libarchive.googlecode.com/ is the home for ongoing
-     libarchive development, including issue tracker, additional
-     documentation, and links to the libarchive mailing lists.
+   * http://libarchive.github.com/ is the home for ongoing
+     libarchive development, including documentation, and
+     links to the libarchive mailing lists.
+   * To report an issue, use the issue tracker at
+     http://code.google.com/p/libarchive/issues/list
+   * To submit an enhancement to libarchive, please submit
+     a pull request via GitHub.
+     https://github.com/libarchive/libarchive/pulls
=20
 This distribution bundle includes the following components:
    * libarchive: a library for reading and writing streaming archives
@@ -66,6 +71,7 @@
   * ZIP archives (with uncompressed or "deflate" compressed entries)
   * GNU and BSD 'ar' archives
   * 'mtree' format
+  * 7-Zip archives
   * Microsoft CAB format
   * LHA and LZH archives
   * RAR archives
@@ -92,6 +98,7 @@
   * GNU and BSD 'ar' archives
   * 'mtree' format
   * ISO9660 format
+  * 7-Zip archives
   * XAR archives
=20
 When creating archives, the result can be filtered with any of the followi=
ng:
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/bsdcpio.1
--- a/head/contrib/libarchive/cpio/bsdcpio.1	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/cpio/bsdcpio.1	Fri Aug 10 14:19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/cpio/bsdcpio.1 232153 2012-02-25 10:=
58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/cpio/bsdcpio.1 238856 2012-07-28 06:=
38:44Z mm $
 .\"
-.Dd December 21, 2007
+.Dd December 24, 2011
 .Dt CPIO 1
 .Os
 .Sh NAME
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/cmdline.c
--- a/head/contrib/libarchive/cpio/cmdline.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/cpio/cmdline.c	Fri Aug 10 14:19:25 2012 +0300
@@ -26,7 +26,7 @@
=20
=20
 #include "cpio_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/cmdline.c 232153 2012-02-=
25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/cmdline.c 238856 2012-07-=
28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -346,6 +346,7 @@
 				snprintf(errbuff, sizeof(errbuff),
 				    "Couldn't lookup user ``%s''", user);
 				errbuff[sizeof(errbuff) - 1] =3D '\0';
+				free(user);
 				return (errbuff);
 			}
 		}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/cpio.c
--- a/head/contrib/libarchive/cpio/cpio.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/cpio/cpio.c	Fri Aug 10 14:19:25 2012 +0300
@@ -26,7 +26,7 @@
=20
=20
 #include "cpio_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/cpio.c 232153 2012-02-25 =
10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/cpio.c 238856 2012-07-28 =
06:38:44Z mm $");
=20
 #include <sys/types.h>
 #include <archive.h>
@@ -82,7 +82,6 @@
 #include "cpio.h"
 #include "err.h"
 #include "line_reader.h"
-#include "matching.h"
=20
 /* Fixed size of uname/gname caches. */
 #define	name_cache_size 101
@@ -190,6 +189,10 @@
 	cpio->bytes_per_block =3D 512;
 	cpio->filename =3D NULL;
=20
+	cpio->matching =3D archive_match_new();
+	if (cpio->matching =3D=3D NULL)
+		lafe_errc(1, 0, "Out of memory");
+
 	while ((opt =3D cpio_getopt(cpio)) !=3D -1) {
 		switch (opt) {
 		case '0': /* GNU convention: --null, -0 */
@@ -216,14 +219,20 @@
 			cpio->extract_flags &=3D ~ARCHIVE_EXTRACT_NO_AUTODIR;
 			break;
 		case 'E': /* NetBSD/OpenBSD */
-			lafe_include_from_file(&cpio->matching,
-			    cpio->argument, cpio->option_null);
+			if (archive_match_include_pattern_from_file(
+			    cpio->matching, cpio->argument,
+			    cpio->option_null) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(cpio->matching));
 			break;
 		case 'F': /* NetBSD/OpenBSD/GNU cpio */
 			cpio->filename =3D cpio->argument;
 			break;
 		case 'f': /* POSIX 1997 */
-			lafe_exclude(&cpio->matching, cpio->argument);
+			if (archive_match_exclude_pattern(cpio->matching,
+			    cpio->argument) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(cpio->matching));
 			break;
 		case 'H': /* GNU cpio (also --format) */
 			cpio->format =3D cpio->argument;
@@ -369,9 +378,6 @@
 	/* -v overrides -V */
 	if (cpio->dot && cpio->verbose)
 		cpio->dot =3D 0;
-	/* -v overrides -V */
-	if (cpio->dot && cpio->verbose)
-		cpio->dot =3D 0;
 	/* TODO: Flag other nonsensical combinations. */
=20
 	switch (cpio->mode) {
@@ -385,7 +391,10 @@
 		break;
 	case 'i':
 		while (*cpio->argv !=3D NULL) {
-			lafe_include(&cpio->matching, *cpio->argv);
+			if (archive_match_include_pattern(cpio->matching,
+			    *cpio->argv) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(cpio->matching));
 			--cpio->argc;
 			++cpio->argv;
 		}
@@ -405,6 +414,7 @@
 		    "Must specify at least one of -i, -o, or -p");
 	}
=20
+	archive_match_free(cpio->matching);
 	free_cache(cpio->gname_cache);
 	free_cache(cpio->uname_cache);
 	return (cpio->return_value);
@@ -909,7 +919,7 @@
 			lafe_errc(1, archive_errno(a),
 			    "%s", archive_error_string(a));
 		}
-		if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
+		if (archive_match_path_excluded(cpio->matching, entry))
 			continue;
 		if (cpio->option_rename) {
 			destpath =3D cpio_rename(archive_entry_pathname(entry));
@@ -1011,7 +1021,7 @@
 			lafe_errc(1, archive_errno(a),
 			    "%s", archive_error_string(a));
 		}
-		if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
+		if (archive_match_path_excluded(cpio->matching, entry))
 			continue;
 		if (cpio->verbose)
 			list_item_verbose(cpio, entry);
@@ -1306,7 +1316,8 @@
 	if (pwent =3D=3D NULL) {
 		*name =3D NULL;
 		if (errno !=3D 0 && errno !=3D ENOENT)
-			lafe_warnc(errno, "getpwuid(%d) failed", id);
+			lafe_warnc(errno, "getpwuid(%s) failed",
+			    cpio_i64toa((int64_t)id));
 		return (errno);
 	}
=20
@@ -1333,7 +1344,8 @@
 	if (grent =3D=3D NULL) {
 		*name =3D NULL;
 		if (errno !=3D 0)
-			lafe_warnc(errno, "getgrgid(%d) failed", id);
+			lafe_warnc(errno, "getgrgid(%s) failed",
+			    cpio_i64toa((int64_t)id));
 		return (errno);
 	}
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/cpio.h
--- a/head/contrib/libarchive/cpio/cpio.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/cpio/cpio.h	Fri Aug 10 14:19:25 2012 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/cpio/cpio.h 232153 2012-02-25 10:58:0=
2Z mm $
+ * $FreeBSD: head/contrib/libarchive/cpio/cpio.h 238856 2012-07-28 06:38:4=
4Z mm $
  */
=20
 #ifndef CPIO_H_INCLUDED
@@ -31,8 +31,6 @@
 #include "cpio_platform.h"
 #include <stdio.h>
=20
-#include "matching.h"
-
 /*
  * The internal state for the "cpio" program.
  *
@@ -88,7 +86,7 @@
 	struct name_cache *gname_cache;
=20
 	/* Work data. */
-	struct lafe_matching  *matching;
+	struct archive   *matching;
 	char		 *buff;
 	size_t		  buff_size;
 };
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/test/main=
.c
--- a/head/contrib/libarchive/cpio/test/main.c	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/libarchive/cpio/test/main.c	Fri Aug 10 14:19:25 2012 +03=
00
@@ -24,6 +24,9 @@
  */
=20
 #include "test.h"
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
@@ -31,6 +34,16 @@
 #ifdef HAVE_ICONV_H
 #include <iconv.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
 #include <limits.h>
 #include <locale.h>
 #ifdef HAVE_SIGNAL_H
@@ -46,7 +59,7 @@
  * TODO: Move this into a separate configuration header, have all test
  * suites share one copy of this file.
  */
-__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/test/main.c 232153 2012-0=
2-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/cpio/test/main.c 238856 2012-0=
7-28 06:38:44Z mm $");
 #define KNOWNREF	"test_option_f.cpio.uu"
 #define ENVBASE "BSDCPIO" /* Prefix for environment variables. */
 #define	PROGRAM "bsdcpio" /* Name of program being tested. */
@@ -116,7 +129,14 @@
 #endif
=20
 #if defined(_WIN32) && !defined(__CYGWIN__)
-void *GetFunctionKernel32(const char *name)
+static void	*GetFunctionKernel32(const char *);
+static int	 my_CreateSymbolicLinkA(const char *, const char *, int);
+static int	 my_CreateHardLinkA(const char *, const char *);
+static int	 my_GetFileInformationByName(const char *,
+		     BY_HANDLE_FILE_INFORMATION *);
+
+static void *
+GetFunctionKernel32(const char *name)
 {
 	static HINSTANCE lib;
 	static int set;
@@ -155,7 +175,7 @@
 	return f =3D=3D NULL ? 0 : (*f)(linkname, target, NULL);
 }
=20
-int
+static int
 my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *=
bhfi)
 {
 	HANDLE h;
@@ -1507,7 +1527,7 @@
 /* Create a file with the specified contents and report any failures. */
 int
 assertion_make_file(const char *file, int line,
-    const char *path, int mode, const char *contents)
+    const char *path, int mode, int csize, const void *contents)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
 	/* TODO: Rework this to set file mode as well. */
@@ -1521,8 +1541,13 @@
 		return (0);
 	}
 	if (contents !=3D NULL) {
-		if (strlen(contents)
-		    !=3D fwrite(contents, 1, strlen(contents), f)) {
+		size_t wsize;
+
+		if (csize < 0)
+			wsize =3D strlen(contents);
+		else
+			wsize =3D (size_t)csize;
+		if (wsize !=3D fwrite(contents, 1, wsize, f)) {
 			fclose(f);
 			failure_start(file, line,
 			    "Could not write file %s", path);
@@ -1542,10 +1567,16 @@
 		return (0);
 	}
 	if (contents !=3D NULL) {
-		if ((ssize_t)strlen(contents)
-		    !=3D write(fd, contents, strlen(contents))) {
+		ssize_t wsize;
+
+		if (csize < 0)
+			wsize =3D (ssize_t)strlen(contents);
+		else
+			wsize =3D (ssize_t)csize;
+		if (wsize !=3D write(fd, contents, wsize)) {
 			close(fd);
-			failure_start(file, line, "Could not write to %s", path);
+			failure_start(file, line,
+			    "Could not write to %s", path);
 			failure_finish(NULL);
 			return (0);
 		}
@@ -1716,6 +1747,52 @@
 #endif /* defined(_WIN32) && !defined(__CYGWIN__) */
 }
=20
+/* Set nodump, report failures. */
+int
+assertion_nodump(const char *file, int line, const char *pathname)
+{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+	int r;
+
+	assertion_count(file, line);
+	r =3D chflags(pathname, UF_NODUMP);
+	if (r < 0) {
+		failure_start(file, line, "Can't set nodump %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS=
)\
+	 && defined(EXT2_NODUMP_FL)
+	int fd, r, flags;
+
+	assertion_count(file, line);
+	fd =3D open(pathname, O_RDONLY | O_NONBLOCK);
+	if (fd < 0) {
+		failure_start(file, line, "Can't open %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0) {
+		failure_start(file, line, "Can't get flags %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	flags |=3D EXT2_NODUMP_FL;
+	r =3D ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+	if (r < 0) {
+		failure_start(file, line, "Can't set nodump %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	close(fd);
+#else
+	(void)pathname; /* UNUSED */
+	assertion_count(file, line);
+#endif
+	return (1);
+}
+
 /*
  *
  *  UTILITIES for use by tests.
@@ -1744,7 +1821,7 @@
 		return (value);
=20
 	++tested;
-	assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+	assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
 	/* Note: Cygwin has its own symlink() emulation that does not
 	 * use the Win32 CreateSymbolicLink() function. */
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1794,6 +1871,70 @@
 }
=20
 /*
+ * Can this filesystem handle nodump flags.
+ */
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+
+int
+canNodump(void)
+{
+	const char *path =3D "cannodumptest";
+	struct stat sb;
+
+	assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
+	if (chflags(path, UF_NODUMP) < 0)
+		return (0);
+	if (stat(path, &sb) < 0)
+		return (0);
+	if (sb.st_flags & UF_NODUMP)
+		return (1);
+	return (0);
+}
+
+#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS=
)\
+	 && defined(EXT2_NODUMP_FL)
+
+int
+canNodump(void)
+{
+	const char *path =3D "cannodumptest";
+	int fd, r, flags;
+
+	assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
+	fd =3D open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return (0);
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	flags |=3D EXT2_NODUMP_FL;
+	r =3D ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	close(fd);
+	fd =3D open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return (0);
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	close(fd);
+	if (flags & EXT2_NODUMP_FL)
+		return (1);
+	return (0);
+}
+
+#else
+
+int
+canNodump()
+{
+	return (0);
+}
+
+#endif
+
+/*
  * Sleep as needed; useful for verifying disk timestamp changes by
  * ensuring that the wall-clock time has actually changed before we
  * go back to re-read something from disk.
@@ -2236,17 +2377,77 @@
 	return strdup(buff);
 }
=20
+static int
+get_test_set(int *test_set, int limit, const char *test)
+{
+	int start, end;
+	int idx =3D 0;
+
+	if (test =3D=3D NULL) {
+		/* Default: Run all tests. */
+		for (;idx < limit; idx++)
+			test_set[idx] =3D idx;
+		return (limit);
+	}
+	if (*test >=3D '0' && *test <=3D '9') {
+		const char *vp =3D test;
+		start =3D 0;
+		while (*vp >=3D '0' && *vp <=3D '9') {
+			start *=3D 10;
+			start +=3D *vp - '0';
+			++vp;
+		}
+		if (*vp =3D=3D '\0') {
+			end =3D start;
+		} else if (*vp =3D=3D '-') {
+			++vp;
+			if (*vp =3D=3D '\0') {
+				end =3D limit - 1;
+			} else {
+				end =3D 0;
+				while (*vp >=3D '0' && *vp <=3D '9') {
+					end *=3D 10;
+					end +=3D *vp - '0';
+					++vp;
+				}
+			}
+		} else
+			return (-1);
+		if (start < 0 || end >=3D limit || start > end)
+			return (-1);
+		while (start <=3D end)
+			test_set[idx++] =3D start++;
+	} else {
+		size_t len =3D strlen(test);
+		for (start =3D 0; start < limit; ++start) {
+			const char *name =3D tests[start].name;
+			const char *p;
+
+			while ((p =3D strchr(name, test[0])) !=3D NULL) {
+				if (strncmp(p, test, len) =3D=3D 0) {
+					test_set[idx++] =3D start;
+					break;
+				} else
+					name =3D p + 1;
+			}
+
+		}
+	}
+	return ((idx =3D=3D 0)?-1:idx);
+}
+
 int
 main(int argc, char **argv)
 {
 	static const int limit =3D sizeof(tests) / sizeof(tests[0]);
-	int i =3D 0, j =3D 0, start, end, tests_run =3D 0, tests_failed =3D 0, op=
tion;
+	int test_set[sizeof(tests) / sizeof(tests[0])];
+	int i =3D 0, j =3D 0, tests_run =3D 0, tests_failed =3D 0, option;
 	time_t now;
 	char *refdir_alloc =3D NULL;
 	const char *progname;
 	char **saved_argv;
 	const char *tmp, *option_arg, *p;
-	char tmpdir[256], *pwd, *testprogdir, *tmp2 =3D NULL;
+	char tmpdir[256], *pwd, *testprogdir, *tmp2 =3D NULL, *vlevel =3D NULL;
 	char tmpdir_timestamp[256];
=20
 	(void)argc; /* UNUSED */
@@ -2332,6 +2533,19 @@
 	if (getenv(ENVBASE "_DEBUG") !=3D NULL)
 		dump_on_failure =3D 1;
=20
+	/* Allow -v to be controlled through the environment. */
+	if (getenv("_VERBOSITY_LEVEL") !=3D NULL)
+	{
+		vlevel =3D getenv("_VERBOSITY_LEVEL");
+		verbosity =3D atoi(vlevel);
+		if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL)
+		{
+			/* Unsupported verbosity levels are silently ignored */
+			vlevel =3D NULL;
+			verbosity =3D VERBOSITY_PASSFAIL;
+		}
+	}
+
 	/* Get the directory holding test files from environment. */
 	refdir =3D getenv(ENVBASE "_TEST_FILES");
=20
@@ -2379,7 +2593,8 @@
 #endif
 				break;
 			case 'q':
-				verbosity--;
+				if (!vlevel)
+					verbosity--;
 				break;
 			case 'r':
 				refdir =3D option_arg;
@@ -2388,7 +2603,8 @@
 				until_failure++;
 				break;
 			case 'v':
-				verbosity++;
+				if (!vlevel)
+					verbosity++;
 				break;
 			default:
 				fprintf(stderr, "Unrecognized option '%c'\n",
@@ -2501,78 +2717,27 @@
 	saved_argv =3D argv;
 	do {
 		argv =3D saved_argv;
-		if (*argv =3D=3D NULL) {
-			/* Default: Run all tests. */
-			for (i =3D 0; i < limit; i++) {
+		do {
+			int test_num;
+
+			test_num =3D get_test_set(test_set, limit, *argv);
+			if (test_num < 0) {
+				printf("*** INVALID Test %s\n", *argv);
+				free(refdir_alloc);
+				usage(progname);
+				return (1);
+			}
+			for (i =3D 0; i < test_num; i++) {
 				tests_run++;
-				if (test_run(i, tmpdir)) {
+				if (test_run(test_set[i], tmpdir)) {
 					tests_failed++;
 					if (until_failure)
 						goto finish;
 				}
 			}
-		} else {
-			while (*(argv) !=3D NULL) {
-				if (**argv >=3D '0' && **argv <=3D '9') {
-					char *vp =3D *argv;
-					start =3D 0;
-					while (*vp >=3D '0' && *vp <=3D '9') {
-						start *=3D 10;
-						start +=3D *vp - '0';
-						++vp;
-					}
-					if (*vp =3D=3D '\0') {
-						end =3D start;
-					} else if (*vp =3D=3D '-') {
-						++vp;
-						if (*vp =3D=3D '\0') {
-							end =3D limit - 1;
-						} else {
-							end =3D 0;
-							while (*vp >=3D '0' && *vp <=3D '9') {
-								end *=3D 10;
-								end +=3D *vp - '0';
-								++vp;
-							}
-						}
-					} else {
-						printf("*** INVALID Test %s\n", *argv);
-						free(refdir_alloc);
-						usage(progname);
-						return (1);
-					}
-					if (start < 0 || end >=3D limit || start > end) {
-						printf("*** INVALID Test %s\n", *argv);
-						free(refdir_alloc);
-						usage(progname);
-						return (1);
-					}
-				} else {
-					for (start =3D 0; start < limit; ++start) {
-						if (strcmp(*argv, tests[start].name) =3D=3D 0)
-							break;
-					}
-					end =3D start;
-					if (start >=3D limit) {
-						printf("*** INVALID Test ``%s''\n",
-						    *argv);
-						free(refdir_alloc);
-						usage(progname);
-						/* usage() never returns */
-					}
-				}
-				while (start <=3D end) {
-					tests_run++;
-					if (test_run(start, tmpdir)) {
-						tests_failed++;
-						if (until_failure)
-							goto finish;
-					}
-					++start;
-				}
+			if (*argv !=3D NULL)
 				argv++;
-			}
-		}
+		} while (*argv !=3D NULL);
 	} while (until_failure);
=20
 finish:
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/test/test=
.h
--- a/head/contrib/libarchive/cpio/test/test.h	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/libarchive/cpio/test/test.h	Fri Aug 10 14:19:25 2012 +03=
00
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/cpio/test/test.h 232153 2012-02-25 10=
:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/cpio/test/test.h 238856 2012-07-28 06=
:38:44Z mm $
  */
=20
 /* Every test program should #include "test.h" as the first thing. */
@@ -194,11 +194,15 @@
 #define assertMakeDir(dirname, mode)	\
   assertion_make_dir(__FILE__, __LINE__, dirname, mode)
 #define assertMakeFile(path, mode, contents) \
-  assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+  assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+  assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
 #define assertMakeHardlink(newfile, oldfile)	\
   assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
 #define assertMakeSymlink(newfile, linkto)	\
   assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertNodump(path)      \
+  assertion_nodump(__FILE__, __LINE__, path)
 #define assertUmask(mask)	\
   assertion_umask(__FILE__, __LINE__, mask)
 #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec)	\
@@ -241,9 +245,10 @@
 int assertion_is_reg(const char *, int, const char *, int);
 int assertion_is_symlink(const char *, int, const char *, const char *);
 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_file(const char *, int, const char *, int, int, const v=
oid *);
 int assertion_make_hardlink(const char *, int, const char *newpath, const =
char *);
 int assertion_make_symlink(const char *, int, const char *newpath, const c=
har *);
+int assertion_nodump(const char *, int, const char *);
 int assertion_non_empty_file(const char *, int, const char *);
 int assertion_text_file_contents(const char *, int, const char *buff, cons=
t char *f);
 int assertion_umask(const char *, int, int);
@@ -267,6 +272,9 @@
 /* Return true if this platform can run the "gunzip" program. */
 int canGunzip(void);
=20
+/* Return true if this filesystem can handle nodump flags. */
+int canNodump(void);
+
 /* Return true if the file has large i-node number(>0xffffffff). */
 int is_LargeInode(const char *);
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/cpio/test/test=
_pathmatch.c
--- a/head/contrib/libarchive/cpio/test/test_pathmatch.c	Mon Jul 30 11:44:1=
8 2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,243 +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 WARRANTI=
ES
- * 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 US=
E,
- * 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/contrib/libarchive/cpio/test/test_pathmatch.c 228=
763 2011-12-21 11:13:29Z mm $");
-
-#include "pathmatch.h"
-
-/*
- * Verify that the pattern matcher implements the wildcard logic specified
- * in SUSv2 for the cpio command.  This is essentially the
- * shell glob syntax:
- *   * - matches any sequence of chars, including '/'
- *   ? - matches any single char, including '/'
- *   [...] - matches any of a set of chars, '-' specifies a range,
- *        initial '!' is undefined
- *
- * The specification in SUSv2 is a bit incomplete, I assume the following:
- *   Trailing '-' in [...] is not special.
- *
- * TODO: Figure out if there's a good way to extend this to handle
- * Windows paths that use '\' as a path separator.  <sigh>
- */
-
-DEFINE_TEST(test_pathmatch)
-{
-	assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
-	assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
-	assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
-	assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
-	assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));
-
-	/* Empty pattern only matches empty string. */
-	assertEqualInt(1, lafe_pathmatch("","", 0));
-	assertEqualInt(0, lafe_pathmatch("","a", 0));
-	assertEqualInt(1, lafe_pathmatch("*","", 0));
-	assertEqualInt(1, lafe_pathmatch("*","a", 0));
-	assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
-	/* SUSv2: * matches / */
-	assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
-	assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
-	assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
-	assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0)=
);
-	assertEqualInt(0, lafe_pathmatch("?", "", 0));
-	assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
-	assertEqualInt(1, lafe_pathmatch("?", "a", 0));
-	assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
-	assertEqualInt(1, lafe_pathmatch("?", ".", 0));
-	assertEqualInt(1, lafe_pathmatch("?", "?", 0));
-	assertEqualInt(1, lafe_pathmatch("a", "a", 0));
-	assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
-	assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
-	assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
-	/* SUSv2: ? matches / */
-	assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
-	assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
-	assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
-	assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
-	assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
-	assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
-	assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));
-
-	/* Character classes */
-	assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));
-
-	/* [] matches nothing, [!] is the same as ? */
-	assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));
-
-	/* I assume: Trailing '-' is non-special. */
-	assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
-
-	/* ']' can be backslash-quoted within a character class. */
-	assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));
-
-	/* backslash-quoted chars can appear as either end of a range. */
-	assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
-	/* backslash-quoted '-' isn't special. */
-	assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
-
-	/* Leading '!' negates a character class. */
-	assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
-	assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
-	assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));
-
-	/* Backslash quotes next character. */
-	assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
-	assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
-	assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
-	assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
-	assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
-	assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
-	assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
-	assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
-	assertEqualInt(0, lafe_pathmatch("abcd\\[", "abcd\\", 0));
-
-	/*
-	 * Because '.' and '/' have special meanings, we can
-	 * identify many equivalent paths even if they're expressed
-	 * differently.  (But quoting a character with '\\' suppresses
-	 * special meanings!)
-	 */
-	assertEqualInt(0, lafe_pathmatch("a/b/", "a/bc", 0));
-	assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
-	assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
-	assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
-	assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
-	assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
-	assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
-	assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
-	assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0)=
);
-	assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0)=
);
-	assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
-	failure("\"?./\" is not the same as \"/./\"");
-	assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
-	failure("Trailing '/' should match no trailing '/'");
-	assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
-	failure("Trailing '/./' is still the same directory.");
-	assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
-	failure("Trailing '/.' is still the same directory.");
-	assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
-	assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
-	failure("Trailing '/./' is still the same directory.");
-	assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
-	failure("Trailing '/.' is still the same directory.");
-	assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));
-
-	/* Matches not anchored at beginning. */
-	assertEqualInt(0,
-	    lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
-	assertEqualInt(1,
-	    lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
-	assertEqualInt(0,
-	    lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
-	assertEqualInt(1,
-	    lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
-	assertEqualInt(0,
-	    lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
-	assertEqualInt(0,
-	    lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
-
-	/* Matches not anchored at end. */
-	assertEqualInt(0,
-	    lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(0,
-	    lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(0,
-	    lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(0,
-	    lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(1,
-	    lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
-	assertEqualInt(0,
-	    lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive.h
--- a/head/contrib/libarchive/libarchive/archive.h	Mon Jul 30 11:44:18 2012=
 +0300
+++ b/head/contrib/libarchive/libarchive/archive.h	Fri Aug 10 14:19:25 2012=
 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive/archive.h 232153 2012-02-2=
5 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive.h 238856 2012-07-2=
8 06:38:44Z mm $
  */
=20
 #ifndef ARCHIVE_H_INCLUDED
@@ -56,23 +56,14 @@
 # else
 #  define	__LA_SSIZE_T	long
 # endif
-# if defined(__BORLANDC__)
-#  define	__LA_UID_T	uid_t
-#  define	__LA_GID_T	gid_t
-# else
-#  define	__LA_UID_T	short
-#  define	__LA_GID_T	short
-# endif
 #else
-# include <unistd.h>  /* ssize_t, uid_t, and gid_t */
+# include <unistd.h>  /* ssize_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
=20
 /*
@@ -127,13 +118,13 @@
  * assert that ARCHIVE_VERSION_NUMBER >=3D 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3000003
+#define	ARCHIVE_VERSION_NUMBER 3000004
 __LA_DECL int		archive_version_number(void);
=20
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_STRING "libarchive 3.0.3"
+#define	ARCHIVE_VERSION_STRING "libarchive 3.0.4"
 __LA_DECL const char *	archive_version_string(void);
=20
 /* Declare our basic types. */
@@ -567,6 +558,8 @@
 __LA_DECL int archive_write_set_compression_xz(struct archive *);
 #endif
=20
+/* A convenience function to set the filter based on the code. */
+__LA_DECL int archive_write_add_filter(struct archive *, int filter_code);
 __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 *);
@@ -758,11 +751,42 @@
  * traversal.
  */
 __LA_DECL int	archive_read_disk_descend(struct archive *);
+__LA_DECL int	archive_read_disk_can_descend(struct archive *);
 __LA_DECL int	archive_read_disk_current_filesystem(struct archive *);
 __LA_DECL int	archive_read_disk_current_filesystem_is_synthetic(struct arc=
hive *);
 __LA_DECL int	archive_read_disk_current_filesystem_is_remote(struct archiv=
e *);
 /* Request that the access time of the entry visited by travesal be restor=
ed. */
 __LA_DECL int  archive_read_disk_set_atime_restored(struct archive *);
+/*
+ * Set behavior. The "flags" argument selects optional behavior.
+ */
+/* Request that the access time of the entry visited by travesal be restor=
ed.
+ * This is the same as archive_read_disk_set_atime_restored. */
+#define	ARCHIVE_READDISK_RESTORE_ATIME		(0x0001)
+/* Default: Do not skip an entry which has nodump flags. */
+#define	ARCHIVE_READDISK_HONOR_NODUMP		(0x0002)
+/* Default: Skip a mac resource fork file whose prefix is "._" because of
+ * using copyfile. */
+#define	ARCHIVE_READDISK_MAC_COPYFILE		(0x0004)
+/* Default: Do not traverse mount points. */
+#define	ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS	(0x0008)
+
+__LA_DECL int  archive_read_disk_set_behavior(struct archive *,
+		    int flags);
+
+/*
+ * Set archive_match object that will be used in archive_read_disk to
+ * know whether an entry should be skipped. The callback function
+ * _excluded_func will be invoked when an entry is skipped by the result
+ * of archive_match.
+ */
+__LA_DECL int	archive_read_disk_set_matching(struct archive *,
+		    struct archive *_matching, void (*_excluded_func)
+		    (struct archive *, void *, struct archive_entry *),
+		    void *_client_data);
+__LA_DECL int	archive_read_disk_set_metadata_filter_callback(struct archiv=
e *,
+		    int (*_metadata_filter_func)(struct archive *, void *,
+		    	struct archive_entry *), void *_client_data);
=20
 /*
  * Accessor functions to read/set various information in
@@ -802,14 +826,116 @@
 			    struct archive *src);
 __LA_DECL int		 archive_file_count(struct archive *);
=20
+/*
+ * ARCHIVE_MATCH API
+ */
+__LA_DECL struct archive *archive_match_new(void);
+__LA_DECL int	archive_match_free(struct archive *);
+
+/*
+ * Test if archive_entry is excluded.
+ * This is a convenience function. This is the same as calling all
+ * archive_match_path_excluded, archive_match_time_excluded
+ * and archive_match_owner_excluded.
+ */
+__LA_DECL int	archive_match_excluded(struct archive *,
+		    struct archive_entry *);
+
+/*
+ * Test if pathname is excluded. The conditions are set by following funct=
ions.
+ */
+__LA_DECL int	archive_match_path_excluded(struct archive *,
+		    struct archive_entry *);
+/* Add exclusion pathname pattern. */
+__LA_DECL int	archive_match_exclude_pattern(struct archive *, const char *=
);
+__LA_DECL int	archive_match_exclude_pattern_w(struct archive *,
+		    const wchar_t *);
+/* Add exclusion pathname pattern from file. */
+__LA_DECL int	archive_match_exclude_pattern_from_file(struct archive *,
+		    const char *, int _nullSeparator);
+__LA_DECL int	archive_match_exclude_pattern_from_file_w(struct archive *,
+		    const wchar_t *, int _nullSeparator);
+/* Add inclusion pathname pattern. */
+__LA_DECL int	archive_match_include_pattern(struct archive *, const char *=
);
+__LA_DECL int	archive_match_include_pattern_w(struct archive *,
+		    const wchar_t *);
+/* Add inclusion pathname pattern from file. */
+__LA_DECL int	archive_match_include_pattern_from_file(struct archive *,
+		    const char *, int _nullSeparator);
+__LA_DECL int	archive_match_include_pattern_from_file_w(struct archive *,
+		    const wchar_t *, int _nullSeparator);
+/*
+ * How to get statistic information for inclusion patterns.
+ */
+/* Return the amount number of unmatched inclusion patterns. */
+__LA_DECL int	archive_match_path_unmatched_inclusions(struct archive *);
+/* Return the pattern of unmatched inclusion with ARCHIVE_OK.
+ * Return ARCHIVE_EOF if there is no inclusion pattern. */
+__LA_DECL int	archive_match_path_unmatched_inclusions_next(
+		    struct archive *, const char **);
+__LA_DECL int	archive_match_path_unmatched_inclusions_next_w(
+		    struct archive *, const wchar_t **);
+
+/*
+ * Test if a file is excluded by its time stamp.
+ * The conditions are set by following functions.
+ */
+__LA_DECL int	archive_match_time_excluded(struct archive *,
+		    struct archive_entry *);
+
+/*
+ * Flags to tell a matching type of time stamps. These are used for
+ * following functinos.
+ */
+/* Time flag: mtime to be tested. */
+#define ARCHIVE_MATCH_MTIME	(0x0100)
+/* Time flag: ctime to be tested. */
+#define ARCHIVE_MATCH_CTIME	(0x0200)
+/* Comparison flag: Match the time if it is newer than. */
+#define ARCHIVE_MATCH_NEWER	(0x0001)
+/* Comparison flag: Match the time if it is older than. */
+#define ARCHIVE_MATCH_OLDER	(0x0002)
+/* Comparison flag: Match the time if it is equal to. */
+#define ARCHIVE_MATCH_EQUAL	(0x0010)
+/* Set inclusion time. */
+__LA_DECL int	archive_match_include_time(struct archive *, int _flag,
+		    time_t _sec, long _nsec);
+/* Set inclusion time by a date string. */
+__LA_DECL int	archive_match_include_date(struct archive *, int _flag,
+		    const char *_datestr);
+__LA_DECL int	archive_match_include_date_w(struct archive *, int _flag,
+		    const wchar_t *_datestr);
+/* Set inclusion time by a particluar file. */
+__LA_DECL int	archive_match_include_file_time(struct archive *,
+		    int _flag, const char *_pathname);
+__LA_DECL int	archive_match_include_file_time_w(struct archive *,
+		    int _flag, const wchar_t *_pathname);
+/* Add exclusion entry. */
+__LA_DECL int	archive_match_exclude_entry(struct archive *,
+		    int _flag, struct archive_entry *);
+
+/*
+ * Test if a file is excluded by its uid ,gid, uname or gname.
+ * The conditions are set by following functions.
+ */
+__LA_DECL int	archive_match_owner_excluded(struct archive *,
+		    struct archive_entry *);
+/* Add inclusion uid, gid, uname and gname. */
+__LA_DECL int	archive_match_include_uid(struct archive *, __LA_INT64_T);
+__LA_DECL int	archive_match_include_gid(struct archive *, __LA_INT64_T);
+__LA_DECL int	archive_match_include_uname(struct archive *, const char *);
+__LA_DECL int	archive_match_include_uname_w(struct archive *,
+		    const wchar_t *);
+__LA_DECL int	archive_match_include_gname(struct archive *, const char *);
+__LA_DECL int	archive_match_include_gname_w(struct archive *,
+		    const wchar_t *);
+
 #ifdef __cplusplus
 }
 #endif
=20
 /* These are meaningless outside of this header. */
 #undef __LA_DECL
-#undef __LA_GID_T
-#undef __LA_UID_T
=20
 /* These need to remain defined because they're used in the
  * callback type definitions.  XXX Fix this.  This is ugly. XXX */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_acl.c
--- a/head/contrib/libarchive/libarchive/archive_acl.c	Mon Jul 30 11:44:18 =
2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_acl.c	Fri Aug 10 14:19:25 =
2012 +0300
@@ -422,8 +422,11 @@
 	*permset =3D acl->acl_p->permset;
 	*tag =3D acl->acl_p->tag;
 	*id =3D acl->acl_p->id;
-	if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) !=3D 0)
+	if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) !=3D 0) {
+		if (errno =3D=3D ENOMEM)
+			return (ARCHIVE_FATAL);
 		*name =3D NULL;
+	}
 	acl->acl_p =3D acl->acl_p->next;
 	return (ARCHIVE_OK);
 }
@@ -441,7 +444,7 @@
 	const wchar_t *prefix;
 	wchar_t separator;
 	struct archive_acl_entry *ap;
-	int id;
+	int id, r;
 	wchar_t *wp;
=20
 	if (acl->acl_text_w !=3D NULL) {
@@ -461,9 +464,11 @@
 				length +=3D 8; /* "default:" */
 			length +=3D 5; /* tag name */
 			length +=3D 1; /* colon */
-			if (archive_mstring_get_wcs(a, &ap->name, &wname) =3D=3D 0 &&
-			    wname !=3D NULL)
+			r =3D archive_mstring_get_wcs(a, &ap->name, &wname);
+			if (r =3D=3D 0 && wname !=3D NULL)
 				length +=3D wcslen(wname);
+			else if (r < 0 && errno =3D=3D ENOMEM)
+				return (NULL);
 			else
 				length +=3D sizeof(uid_t) * 3 + 1;
 			length ++; /* colon */
@@ -487,7 +492,7 @@
 	/* Now, allocate the string and actually populate it. */
 	wp =3D acl->acl_text_w =3D (wchar_t *)malloc(length * sizeof(wchar_t));
 	if (wp =3D=3D NULL)
-		__archive_errx(1, "No memory to generate the text version of the ACL");
+		return (NULL);
 	count =3D 0;
 	if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) !=3D 0) {
 		append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
@@ -502,16 +507,19 @@
=20
 		ap =3D acl->acl_head;
 		while (ap !=3D NULL) {
-			if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) !=3D 0 &&
-				archive_mstring_get_wcs(a, &ap->name, &wname) =3D=3D 0) {
-				*wp++ =3D separator;
-				if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
-					id =3D ap->id;
-				else
-					id =3D -1;
-				append_entry_w(&wp, NULL, ap->tag, wname,
-				    ap->permset, id);
-				count++;
+			if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) !=3D 0) {
+				r =3D archive_mstring_get_wcs(a, &ap->name, &wname);
+				if (r =3D=3D 0) {
+					*wp++ =3D separator;
+					if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+						id =3D ap->id;
+					else
+						id =3D -1;
+					append_entry_w(&wp, NULL, ap->tag, wname,
+					    ap->permset, id);
+					count++;
+				} else if (r < 0 && errno =3D=3D ENOMEM)
+					return (NULL);
 			}
 			ap =3D ap->next;
 		}
@@ -526,17 +534,20 @@
 		ap =3D acl->acl_head;
 		count =3D 0;
 		while (ap !=3D NULL) {
-			if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) !=3D 0 &&
-				archive_mstring_get_wcs(a, &ap->name, &wname) =3D=3D 0) {
-				if (count > 0)
-					*wp++ =3D separator;
-				if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
-					id =3D ap->id;
-				else
-					id =3D -1;
-				append_entry_w(&wp, prefix, ap->tag,
-				    wname, ap->permset, id);
-				count ++;
+			if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) !=3D 0) {
+				r =3D archive_mstring_get_wcs(a, &ap->name, &wname);
+				if (r =3D=3D 0) {
+					if (count > 0)
+						*wp++ =3D separator;
+					if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+						id =3D ap->id;
+					else
+						id =3D -1;
+					append_entry_w(&wp, prefix, ap->tag,
+					    wname, ap->permset, id);
+					count ++;
+				} else if (r < 0 && errno =3D=3D ENOMEM)
+					return (NULL);
 			}
 			ap =3D ap->next;
 		}
@@ -675,7 +686,7 @@
 	/* Now, allocate the string and actually populate it. */
 	p =3D acl->acl_text =3D (char *)malloc(length);
 	if (p =3D=3D NULL)
-		__archive_errx(1, "No memory to generate the text version of the ACL");
+		return (-1);
 	count =3D 0;
 	if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) !=3D 0) {
 		append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_check_magic.c
--- a/head/contrib/libarchive/libarchive/archive_check_magic.c	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_check_magic.c	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_check_magic=
.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_check_magic=
.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -94,6 +94,7 @@
 	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");
+	case ARCHIVE_MATCH_MAGIC:	return ("archive_match");
 	default:			return NULL;
 	}
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_endian.h
--- a/head/contrib/libarchive/libarchive/archive_endian.h	Mon Jul 30 11:44:=
18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_endian.h	Fri Aug 10 14:19:=
25 2012 +0300
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/contrib/libarchive/libarchive/archive_endian.h 228763 20=
11-12-21 11:13:29Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_endian.h 238856 20=
12-07-28 06:38:44Z mm $
  *
  * Borrowed from FreeBSD's <sys/endian.h>
  */
@@ -126,8 +126,8 @@
 {
 	unsigned char *p =3D (unsigned char *)pp;
=20
-	archive_be32enc(p, u >> 32);
-	archive_be32enc(p + 4, u & 0xffffffff);
+	archive_be32enc(p, (uint32_t)(u >> 32));
+	archive_be32enc(p + 4, (uint32_t)(u & 0xffffffff));
 }
=20
 static inline void
@@ -155,8 +155,8 @@
 {
 	unsigned char *p =3D (unsigned char *)pp;
=20
-	archive_le32enc(p, u & 0xffffffff);
-	archive_le32enc(p + 4, u >> 32);
+	archive_le32enc(p, (uint32_t)(u & 0xffffffff));
+	archive_le32enc(p + 4, (uint32_t)(u >> 32));
 }
=20
 #endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry.3
--- a/head/contrib/libarchive/libarchive/archive_entry.3	Mon Jul 30 11:44:1=
8 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry.3	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -23,9 +23,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_entry.3 232153 20=
12-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_entry.3 238856 20=
12-07-28 06:38:44Z mm $
 .\"
-.Dd Feburary 22, 2010
+.Dd Feburary 2, 2012
 .Dt ARCHIVE_ENTRY 3
 .Os
 .Sh NAME
@@ -34,6 +34,8 @@
 .Nm archive_entry_free ,
 .Nm archive_entry_new ,
 .Nd functions for managing archive entry descriptions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft "struct archive_entry *"
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry.c
--- a/head/contrib/libarchive/libarchive/archive_entry.c	Mon Jul 30 11:44:1=
8 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry.c	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_entry.c 232=
153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_entry.c 238=
856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -375,8 +375,11 @@
 	char *p;
=20
 	if (archive_mstring_get_mbs(entry->archive,
-	    &entry->ae_fflags_text, &f) =3D=3D 0 && f !=3D NULL)
-		return (f);
+	    &entry->ae_fflags_text, &f) =3D=3D 0) {
+		if (f !=3D NULL)
+			return (f);
+	} else if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
=20
 	if (entry->ae_fflags_set =3D=3D 0  &&  entry->ae_fflags_clear =3D=3D 0)
 		return (NULL);
@@ -390,6 +393,8 @@
 	if (archive_mstring_get_mbs(entry->archive,
 	    &entry->ae_fflags_text, &f) =3D=3D 0)
 		return (f);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -405,6 +410,8 @@
 	const char *p;
 	if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) =3D=3D =
0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -414,6 +421,8 @@
 	const wchar_t *p;
 	if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) =3D=3D =
0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -428,9 +437,13 @@
 archive_entry_hardlink(struct archive_entry *entry)
 {
 	const char *p;
-	if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_mbs(
+	if ((entry->ae_set & AE_SET_HARDLINK) =3D=3D 0)
+		return (NULL);
+	if (archive_mstring_get_mbs(
 	    entry->archive, &entry->ae_hardlink, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -438,9 +451,13 @@
 archive_entry_hardlink_w(struct archive_entry *entry)
 {
 	const wchar_t *p;
-	if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_wcs(
+	if ((entry->ae_set & AE_SET_HARDLINK) =3D=3D 0)
+		return (NULL);
+	if (archive_mstring_get_wcs(
 	    entry->archive, &entry->ae_hardlink, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -511,6 +528,8 @@
 	if (archive_mstring_get_mbs(
 	    entry->archive, &entry->ae_pathname, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -521,6 +540,8 @@
 	if (archive_mstring_get_wcs(
 	    entry->archive, &entry->ae_pathname, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -584,6 +605,8 @@
 	if (archive_mstring_get_mbs(
 	    entry->archive, &entry->ae_sourcepath, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -601,9 +624,13 @@
 archive_entry_symlink(struct archive_entry *entry)
 {
 	const char *p;
-	if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_mbs(
+	if ((entry->ae_set & AE_SET_SYMLINK) =3D=3D 0)
+		return (NULL);
+	if (archive_mstring_get_mbs(
 	    entry->archive, &entry->ae_symlink, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -611,9 +638,13 @@
 archive_entry_symlink_w(struct archive_entry *entry)
 {
 	const wchar_t *p;
-	if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_wcs(
+	if ((entry->ae_set & AE_SET_SYMLINK) =3D=3D 0)
+		return (NULL);
+	if (archive_mstring_get_wcs(
 	    entry->archive, &entry->ae_symlink, &p) =3D=3D 0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -641,6 +672,8 @@
 	const char *p;
 	if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) =3D=3D =
0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -650,6 +683,8 @@
 	const wchar_t *p;
 	if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) =3D=3D =
0)
 		return (p);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (NULL);
 }
=20
@@ -730,6 +765,8 @@
 	if (archive_mstring_update_utf8(entry->archive,
 	    &entry->ae_gname, name) =3D=3D 0)
 		return (1);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (0);
 }
=20
@@ -796,6 +833,8 @@
 	if (archive_mstring_update_utf8(entry->archive,
 	    &entry->ae_hardlink, target) =3D=3D 0)
 		return (1);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (0);
 }
=20
@@ -932,7 +971,11 @@
 	else
 		r =3D archive_mstring_update_utf8(entry->archive,
 		    &entry->ae_hardlink, target);
-	return ((r =3D=3D 0)? 1: 0);
+	if (r =3D=3D 0)
+		return (1);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
+	return (0);
 }
=20
 int
@@ -1005,6 +1048,8 @@
 	if (archive_mstring_update_utf8(entry->archive,
 	    &entry->ae_pathname, name) =3D=3D 0)
 		return (1);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (0);
 }
=20
@@ -1115,6 +1160,8 @@
 	if (archive_mstring_update_utf8(entry->archive,
 	    &entry->ae_symlink, linkname) =3D=3D 0)
 		return (1);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (0);
 }
=20
@@ -1164,6 +1211,8 @@
 	if (archive_mstring_update_utf8(entry->archive,
 	    &entry->ae_uname, name) =3D=3D 0)
 		return (1);
+	if (errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
 	return (0);
 }
=20
@@ -1269,7 +1318,12 @@
 archive_entry_acl_next(struct archive_entry *entry, int want_type, int *ty=
pe,
     int *permset, int *tag, int *id, const char **name)
 {
-	return archive_acl_next(entry->archive, &entry->acl, want_type, type, per=
mset, tag, id, name);
+	int r;
+	r =3D archive_acl_next(entry->archive, &entry->acl, want_type, type,
+		permset, tag, id, name);
+	if (r =3D=3D ARCHIVE_FATAL && errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
+	return (r);
 }
=20
 /*
@@ -1279,7 +1333,11 @@
 const wchar_t *
 archive_entry_acl_text_w(struct archive_entry *entry, int flags)
 {
-	return archive_acl_text_w(entry->archive, &entry->acl, flags);
+	const wchar_t *r;
+	r =3D archive_acl_text_w(entry->archive, &entry->acl, flags);
+	if (r =3D=3D NULL && errno =3D=3D ENOMEM)
+		__archive_errx(1, "No memory");
+	return (r);
 }
=20
 const char *
@@ -1288,7 +1346,7 @@
 	const char *p;
 	if (archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL) !=3D 0
 	    && errno =3D=3D ENOMEM)
-		return (NULL);
+		__archive_errx(1, "No memory");
 	return (p);
 }
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry.h
--- a/head/contrib/libarchive/libarchive/archive_entry.h	Mon Jul 30 11:44:1=
8 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry.h	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -22,14 +22,14 @@
  * (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/contrib/libarchive/libarchive/archive_entry.h 232153 201=
2-02-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_entry.h 238856 201=
2-07-28 06:38:44Z mm $
  */
=20
 #ifndef ARCHIVE_ENTRY_H_INCLUDED
 #define	ARCHIVE_ENTRY_H_INCLUDED
=20
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3000003
+#define	ARCHIVE_VERSION_NUMBER 3000004
=20
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -47,21 +47,9 @@
 #include <windows.h>
 #endif
=20
-/* Get appropriate definitions of standard POSIX-style types. */
-/* These should match the types used in 'struct stat' */
+/* Get a suitable 64-bit integer type. */
 #if defined(_WIN32) && !defined(__CYGWIN__)
-#define	__LA_INT64_T	__int64
-# if defined(__BORLANDC__)
-#  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  /* 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
+# define	__LA_INT64_T	__int64
 #else
 #include <unistd.h>
 # if defined(_SCO_DS)
@@ -69,19 +57,19 @@
 # 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
+#endif
+
+/* Get a suitable definition for mode_t */
+#if ARCHIVE_VERSION_NUMBER >=3D 3999000
+/* Switch to plain 'int' for libarchive 4.0.  It's less broken than 'mode_=
t' */
+# define	__LA_MODE_T	int
+#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
+# define	__LA_MODE_T	unsigned short
+#else
 # define	__LA_MODE_T	mode_t
 #endif
=20
 /*
- * Remove this for libarchive 3.2, since ino_t is no longer used.
- */
-#define	__LA_INO_T	ino_t
-
-
-/*
  * On Windows, define LIBARCHIVE_STATIC if you're building or using a
  * .lib.  The default here assumes you're building a DLL.  Only
  * libarchive source should ever define __LIBARCHIVE_BUILD.
@@ -149,14 +137,18 @@
  * portable values to platform-native values when entries are read from
  * or written to disk.
  */
-#define	AE_IFMT		0170000
-#define	AE_IFREG	0100000
-#define	AE_IFLNK	0120000
-#define	AE_IFSOCK	0140000
-#define	AE_IFCHR	0020000
-#define	AE_IFBLK	0060000
-#define	AE_IFDIR	0040000
-#define	AE_IFIFO	0010000
+/*
+ * In libarchive 4.0, we can drop the casts here.
+ * They're needed to work around Borland C's broken mode_t.
+ */
+#define AE_IFMT		((__LA_MODE_T)0170000)
+#define AE_IFREG	((__LA_MODE_T)0100000)
+#define AE_IFLNK	((__LA_MODE_T)0120000)
+#define AE_IFSOCK	((__LA_MODE_T)0140000)
+#define AE_IFCHR	((__LA_MODE_T)0020000)
+#define AE_IFBLK	((__LA_MODE_T)0060000)
+#define AE_IFDIR	((__LA_MODE_T)0040000)
+#define AE_IFIFO	((__LA_MODE_T)0010000)
=20
 /*
  * Basic object manipulation
@@ -321,7 +313,10 @@
  * manipulate archives on systems different than the ones they were
  * created on.
  *
- * TODO: On Linux, provide both stat32 and stat64 versions of these functi=
ons.
+ * TODO: On Linux and other LFS systems, provide both stat32 and
+ * stat64 versions of these functions and all of the macro glue so
+ * that archive_entry_stat is magically defined to
+ * archive_entry_stat32 or archive_entry_stat64 as appropriate.
  */
 __LA_DECL const struct stat	*archive_entry_stat(struct archive_entry *);
 __LA_DECL void	archive_entry_copy_stat(struct archive_entry *, const struc=
t stat *);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_acl.3
--- a/head/contrib/libarchive/libarchive/archive_entry_acl.3	Mon Jul 30 11:=
44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_acl.3	Fri Aug 10 14:=
19:25 2012 +0300
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 21, 2010
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY_ACL 3
 .Os
 .Sh NAME
@@ -35,6 +35,8 @@
 .Nm archive_entry_acl_reset ,
 .Nm archive_entry_acl_text_w
 .Nd functions for manipulating Access Control Lists in archive entry descr=
iptions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft void
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_link_resolver.c
--- a/head/contrib/libarchive/libarchive/archive_entry_link_resolver.c	Mon =
Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_link_resolver.c	Fri =
Aug 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_entry_link_=
resolver.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_entry_link_=
resolver.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -362,7 +362,7 @@
 	if (res->number_entries > res->number_buckets * 2)
 		grow_hash(res);
=20
-	hash =3D archive_entry_dev(entry) ^ archive_entry_ino64(entry);
+	hash =3D (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry));
 	bucket =3D hash & (res->number_buckets - 1);
=20
 	/* If we could allocate the entry, record it. */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_linkify.3
--- a/head/contrib/libarchive/libarchive/archive_entry_linkify.3	Mon Jul 30=
 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_linkify.3	Fri Aug 10=
 14:19:25 2012 +0300
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 20, 2010
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY_LINKIFY 3
 .Os
 .Sh NAME
@@ -33,7 +33,7 @@
 .Nm archive_entry_linkify
 .Nd hardlink resolver functions
 .Sh LIBRARY
-.Lb libarchive
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft struct archive_entry_linkresolver *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_paths.3
--- a/head/contrib/libarchive/libarchive/archive_entry_paths.3	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_paths.3	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 22, 2010
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY_PATHS 3
 .Os
 .Sh NAME
@@ -51,6 +51,8 @@
 .Nm archive_entry_copy_symlink_w ,
 .Nm archve_entry_update_symlink_utf8
 .Nd functions for manipulating path names in archive entry descriptions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft const char *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_perms.3
--- a/head/contrib/libarchive/libarchive/archive_entry_perms.3	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_perms.3	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 22, 2010
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY_PERMS 3
 .Os
 .Sh NAME
@@ -52,6 +52,8 @@
 .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 LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft gid_t
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_stat.3
--- a/head/contrib/libarchive/libarchive/archive_entry_stat.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_stat.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -22,8 +22,8 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd May 12, 2008
-.Dt ARCHIVE_ENTRY 3
+.Dd February 2, 2012
+.Dt ARCHIVE_ENTRY_STAT 3
 .Os
 .Sh NAME
 .Nm archive_entry_stat ,
@@ -56,6 +56,8 @@
 .Nm archive_entry_rdevminor ,
 .Nm archive_entry_set_rdevminor ,
 .Nd accessor functions for manipulating archive entry descriptions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft const struct stat *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_stat.c
--- a/head/contrib/libarchive/libarchive/archive_entry_stat.c	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_stat.c	Fri Aug 10 14=
:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_entry_stat.=
c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_entry_stat.=
c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -70,12 +70,12 @@
 	st->st_ctime =3D archive_entry_ctime(entry);
 	st->st_mtime =3D archive_entry_mtime(entry);
 	st->st_dev =3D archive_entry_dev(entry);
-	st->st_gid =3D archive_entry_gid(entry);
-	st->st_uid =3D archive_entry_uid(entry);
-	st->st_ino =3D archive_entry_ino64(entry);
+	st->st_gid =3D (gid_t)archive_entry_gid(entry);
+	st->st_uid =3D (uid_t)archive_entry_uid(entry);
+	st->st_ino =3D (ino_t)archive_entry_ino64(entry);
 	st->st_nlink =3D archive_entry_nlink(entry);
 	st->st_rdev =3D archive_entry_rdev(entry);
-	st->st_size =3D archive_entry_size(entry);
+	st->st_size =3D (off_t)archive_entry_size(entry);
 	st->st_mode =3D archive_entry_mode(entry);
=20
 	/*
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_entry_time.3
--- a/head/contrib/libarchive/libarchive/archive_entry_time.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_entry_time.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -23,9 +23,9 @@
 .\" 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:2=
2 kientzle Exp $
+.\" $FreeBSD$
 .\"
-.Dd February 21, 2010
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY_TIME 3
 .Os
 .Sh NAME
@@ -50,6 +50,8 @@
 .Nm archive_entry_set_mtime ,
 .Nm archive_entry_unset_mtime ,
 .Nd functions for manipulating times in archive entry descriptions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive_entry.h
 .Ft time_t
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_getdate.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/archive_getdate.c	Fri Aug 10 14:19=
:25 2012 +0300
@@ -0,0 +1,1037 @@
+/*
+ * This code is in the public domain and has no copyright.
+ *
+ * This is a plain C recursive-descent translation of an old
+ * public-domain YACC grammar that has been used for parsing dates in
+ * very many open-source projects.
+ *
+ * Since the original authors were generous enough to donate their
+ * work to the public domain, I feel compelled to match their
+ * generosity.
+ *
+ * Tim Kientzle, February 2009.
+ */
+
+/*
+ * Header comment from original getdate.y:
+ */
+
+/*
+**  Originally written by Steven M. Bellovin <smb at research.att.com> while
+**  at the University of North Carolina at Chapel Hill.  Later tweaked by
+**  a couple of people on Usenet.  Completely overhauled by Rich $alz
+**  <rsalz at bbn.com> and Jim Berets <jberets at bbn.com> in August, 1990;
+**
+**  This grammar has 10 shift/reduce conflicts.
+**
+**  This code is in the public domain and has no copyright.
+*/
+
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/* This file defines a single public function. */
+time_t __archive_get_date(time_t now, char *);
+
+/* Basic time units. */
+#define	EPOCH		1970
+#define	MINUTE		(60L)
+#define	HOUR		(60L * MINUTE)
+#define	DAY		(24L * HOUR)
+
+/* Daylight-savings mode:  on, off, or not yet known. */
+enum DSTMODE { DSTon, DSToff, DSTmaybe };
+/* Meridian:  am or pm. */
+enum { tAM, tPM };
+/* Token types returned by nexttoken() */
+enum { tAGO =3D 260, tDAY, tDAYZONE, tAMPM, tMONTH, tMONTH_UNIT, tSEC_UNIT,
+       tUNUMBER, tZONE, tDST };
+struct token { int token; time_t value; };
+
+/*
+ * Parser state.
+ */
+struct gdstate {
+	struct token *tokenp; /* Pointer to next token. */
+	/* HaveXxxx counts how many of this kind of phrase we've seen;
+	 * it's a fatal error to have more than one time, zone, day,
+	 * or date phrase. */
+	int	HaveYear;
+	int	HaveMonth;
+	int	HaveDay;
+	int	HaveWeekDay; /* Day of week */
+	int	HaveTime; /* Hour/minute/second */
+	int	HaveZone; /* timezone and/or DST info */
+	int	HaveRel; /* time offset; we can have more than one */
+	/* Absolute time values. */
+	time_t	Timezone;  /* Seconds offset from GMT */
+	time_t	Day;
+	time_t	Hour;
+	time_t	Minutes;
+	time_t	Month;
+	time_t	Seconds;
+	time_t	Year;
+	/* DST selection */
+	enum DSTMODE	DSTmode;
+	/* Day of week accounting, e.g., "3rd Tuesday" */
+	time_t	DayOrdinal; /* "3" in "3rd Tuesday" */
+	time_t	DayNumber; /* "Tuesday" in "3rd Tuesday" */
+	/* Relative time values: hour/day/week offsets are measured in
+	 * seconds, month/year are counted in months. */
+	time_t	RelMonth;
+	time_t	RelSeconds;
+};
+
+/*
+ * A series of functions that recognize certain common time phrases.
+ * Each function returns 1 if it managed to make sense of some of the
+ * tokens, zero otherwise.
+ */
+
+/*
+ *  hour:minute or hour:minute:second with optional AM, PM, or numeric
+ *  timezone offset
+ */
+static int
+timephrase(struct gdstate *gds)
+{
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D ':'
+	    && gds->tokenp[2].token =3D=3D tUNUMBER
+	    && gds->tokenp[3].token =3D=3D ':'
+	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
+		/* "12:14:18" or "22:08:07" */
+		++gds->HaveTime;
+		gds->Hour =3D gds->tokenp[0].value;
+		gds->Minutes =3D gds->tokenp[2].value;
+		gds->Seconds =3D gds->tokenp[4].value;
+		gds->tokenp +=3D 5;
+	}
+	else if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D ':'
+	    && gds->tokenp[2].token =3D=3D tUNUMBER) {
+		/* "12:14" or "22:08" */
+		++gds->HaveTime;
+		gds->Hour =3D gds->tokenp[0].value;
+		gds->Minutes =3D gds->tokenp[2].value;
+		gds->Seconds =3D 0;
+		gds->tokenp +=3D 3;
+	}
+	else if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D tAMPM) {
+		/* "7" is a time if it's followed by "am" or "pm" */
+		++gds->HaveTime;
+		gds->Hour =3D gds->tokenp[0].value;
+		gds->Minutes =3D gds->Seconds =3D 0;
+		/* We'll handle the AM/PM below. */
+		gds->tokenp +=3D 1;
+	} else {
+		/* We can't handle this. */
+		return 0;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tAMPM) {
+		/* "7:12pm", "12:20:13am" */
+		if (gds->Hour =3D=3D 12)
+			gds->Hour =3D 0;
+		if (gds->tokenp[0].value =3D=3D tPM)
+			gds->Hour +=3D 12;
+		gds->tokenp +=3D 1;
+	}
+	if (gds->tokenp[0].token =3D=3D '+'
+	    && gds->tokenp[1].token =3D=3D tUNUMBER) {
+		/* "7:14+0700" */
+		gds->HaveZone++;
+		gds->DSTmode =3D DSToff;
+		gds->Timezone =3D - ((gds->tokenp[1].value / 100) * HOUR
+		    + (gds->tokenp[1].value % 100) * MINUTE);
+		gds->tokenp +=3D 2;
+	}
+	if (gds->tokenp[0].token =3D=3D '-'
+	    && gds->tokenp[1].token =3D=3D tUNUMBER) {
+		/* "19:14:12-0530" */
+		gds->HaveZone++;
+		gds->DSTmode =3D DSToff;
+		gds->Timezone =3D + ((gds->tokenp[1].value / 100) * HOUR
+		    + (gds->tokenp[1].value % 100) * MINUTE);
+		gds->tokenp +=3D 2;
+	}
+	return 1;
+}
+
+/*
+ * Timezone name, possibly including DST.
+ */
+static int
+zonephrase(struct gdstate *gds)
+{
+	if (gds->tokenp[0].token =3D=3D tZONE
+	    && gds->tokenp[1].token =3D=3D tDST) {
+		gds->HaveZone++;
+		gds->Timezone =3D gds->tokenp[0].value;
+		gds->DSTmode =3D DSTon;
+		gds->tokenp +=3D 1;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tZONE) {
+		gds->HaveZone++;
+		gds->Timezone =3D gds->tokenp[0].value;
+		gds->DSTmode =3D DSToff;
+		gds->tokenp +=3D 1;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tDAYZONE) {
+		gds->HaveZone++;
+		gds->Timezone =3D gds->tokenp[0].value;
+		gds->DSTmode =3D DSTon;
+		gds->tokenp +=3D 1;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Year/month/day in various combinations.
+ */
+static int
+datephrase(struct gdstate *gds)
+{
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D '/'
+	    && gds->tokenp[2].token =3D=3D tUNUMBER
+	    && gds->tokenp[3].token =3D=3D '/'
+	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
+		gds->HaveYear++;
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		if (gds->tokenp[0].value >=3D 13) {
+			/* First number is big:  2004/01/29, 99/02/17 */
+			gds->Year =3D gds->tokenp[0].value;
+			gds->Month =3D gds->tokenp[2].value;
+			gds->Day =3D gds->tokenp[4].value;
+		} else if ((gds->tokenp[4].value >=3D 13)
+		    || (gds->tokenp[2].value >=3D 13)) {
+			/* Last number is big:  01/07/98 */
+			/* Middle number is big:  01/29/04 */
+			gds->Month =3D gds->tokenp[0].value;
+			gds->Day =3D gds->tokenp[2].value;
+			gds->Year =3D gds->tokenp[4].value;
+		} else {
+			/* No significant clues: 02/03/04 */
+			gds->Month =3D gds->tokenp[0].value;
+			gds->Day =3D gds->tokenp[2].value;
+			gds->Year =3D gds->tokenp[4].value;
+		}
+		gds->tokenp +=3D 5;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D '/'
+	    && gds->tokenp[2].token =3D=3D tUNUMBER) {
+		/* "1/15" */
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		gds->Month =3D gds->tokenp[0].value;
+		gds->Day =3D gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D '-'
+	    && gds->tokenp[2].token =3D=3D tUNUMBER
+	    && gds->tokenp[3].token =3D=3D '-'
+	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
+		/* ISO 8601 format.  yyyy-mm-dd.  */
+		gds->HaveYear++;
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		gds->Year =3D gds->tokenp[0].value;
+		gds->Month =3D gds->tokenp[2].value;
+		gds->Day =3D gds->tokenp[4].value;
+		gds->tokenp +=3D 5;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D '-'
+	    && gds->tokenp[2].token =3D=3D tMONTH
+	    && gds->tokenp[3].token =3D=3D '-'
+	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
+		gds->HaveYear++;
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		if (gds->tokenp[0].value > 31) {
+			/* e.g. 1992-Jun-17 */
+			gds->Year =3D gds->tokenp[0].value;
+			gds->Month =3D gds->tokenp[2].value;
+			gds->Day =3D gds->tokenp[4].value;
+		} else {
+			/* e.g. 17-JUN-1992.  */
+			gds->Day =3D gds->tokenp[0].value;
+			gds->Month =3D gds->tokenp[2].value;
+			gds->Year =3D gds->tokenp[4].value;
+		}
+		gds->tokenp +=3D 5;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tMONTH
+	    && gds->tokenp[1].token =3D=3D tUNUMBER
+	    && gds->tokenp[2].token =3D=3D ','
+	    && gds->tokenp[3].token =3D=3D tUNUMBER) {
+		/* "June 17, 2001" */
+		gds->HaveYear++;
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		gds->Month =3D gds->tokenp[0].value;
+		gds->Day =3D gds->tokenp[1].value;
+		gds->Year =3D gds->tokenp[3].value;
+		gds->tokenp +=3D 4;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tMONTH
+	    && gds->tokenp[1].token =3D=3D tUNUMBER) {
+		/* "May 3" */
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		gds->Month =3D gds->tokenp[0].value;
+		gds->Day =3D gds->tokenp[1].value;
+		gds->tokenp +=3D 2;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D tMONTH
+	    && gds->tokenp[2].token =3D=3D tUNUMBER) {
+		/* "12 Sept 1997" */
+		gds->HaveYear++;
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		gds->Day =3D gds->tokenp[0].value;
+		gds->Month =3D gds->tokenp[1].value;
+		gds->Year =3D gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D tMONTH) {
+		/* "12 Sept" */
+		gds->HaveMonth++;
+		gds->HaveDay++;
+		gds->Day =3D gds->tokenp[0].value;
+		gds->Month =3D gds->tokenp[1].value;
+		gds->tokenp +=3D 2;
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Relative time phrase: "tomorrow", "yesterday", "+1 hour", etc.
+ */
+static int
+relunitphrase(struct gdstate *gds)
+{
+	if (gds->tokenp[0].token =3D=3D '-'
+	    && gds->tokenp[1].token =3D=3D tUNUMBER
+	    && gds->tokenp[2].token =3D=3D tSEC_UNIT) {
+		/* "-3 hours" */
+		gds->HaveRel++;
+		gds->RelSeconds -=3D gds->tokenp[1].value * gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D '+'
+	    && gds->tokenp[1].token =3D=3D tUNUMBER
+	    && gds->tokenp[2].token =3D=3D tSEC_UNIT) {
+		/* "+1 minute" */
+		gds->HaveRel++;
+		gds->RelSeconds +=3D gds->tokenp[1].value * gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D tSEC_UNIT) {
+		/* "1 day" */
+		gds->HaveRel++;
+		gds->RelSeconds +=3D gds->tokenp[1].value * gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D '-'
+	    && gds->tokenp[1].token =3D=3D tUNUMBER
+	    && gds->tokenp[2].token =3D=3D tMONTH_UNIT) {
+		/* "-3 months" */
+		gds->HaveRel++;
+		gds->RelMonth -=3D gds->tokenp[1].value * gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D '+'
+	    && gds->tokenp[1].token =3D=3D tUNUMBER
+	    && gds->tokenp[2].token =3D=3D tMONTH_UNIT) {
+		/* "+5 years" */
+		gds->HaveRel++;
+		gds->RelMonth +=3D gds->tokenp[1].value * gds->tokenp[2].value;
+		gds->tokenp +=3D 3;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+	    && gds->tokenp[1].token =3D=3D tMONTH_UNIT) {
+		/* "2 years" */
+		gds->HaveRel++;
+		gds->RelMonth +=3D gds->tokenp[0].value * gds->tokenp[1].value;
+		gds->tokenp +=3D 2;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D tSEC_UNIT) {
+		/* "now", "tomorrow" */
+		gds->HaveRel++;
+		gds->RelSeconds +=3D gds->tokenp[0].value;
+		++gds->tokenp;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D tMONTH_UNIT) {
+		/* "month" */
+		gds->HaveRel++;
+		gds->RelMonth +=3D gds->tokenp[0].value;
+		gds->tokenp +=3D 1;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Day of the week specification.
+ */
+static int
+dayphrase(struct gdstate *gds)
+{
+	if (gds->tokenp[0].token =3D=3D tDAY) {
+		/* "tues", "wednesday," */
+		gds->HaveWeekDay++;
+		gds->DayOrdinal =3D 1;
+		gds->DayNumber =3D gds->tokenp[0].value;
+		gds->tokenp +=3D 1;
+		if (gds->tokenp[0].token =3D=3D ',')
+			gds->tokenp +=3D 1;
+		return 1;
+	}
+	if (gds->tokenp[0].token =3D=3D tUNUMBER
+		&& gds->tokenp[1].token =3D=3D tDAY) {
+		/* "second tues" "3 wed" */
+		gds->HaveWeekDay++;
+		gds->DayOrdinal =3D gds->tokenp[0].value;
+		gds->DayNumber =3D gds->tokenp[1].value;
+		gds->tokenp +=3D 2;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Try to match a phrase using one of the above functions.
+ * This layer also deals with a couple of generic issues.
+ */
+static int
+phrase(struct gdstate *gds)
+{
+	if (timephrase(gds))
+		return 1;
+	if (zonephrase(gds))
+		return 1;
+	if (datephrase(gds))
+		return 1;
+	if (dayphrase(gds))
+		return 1;
+	if (relunitphrase(gds)) {
+		if (gds->tokenp[0].token =3D=3D tAGO) {
+			gds->RelSeconds =3D -gds->RelSeconds;
+			gds->RelMonth =3D -gds->RelMonth;
+			gds->tokenp +=3D 1;
+		}
+		return 1;
+	}
+
+	/* Bare numbers sometimes have meaning. */
+	if (gds->tokenp[0].token =3D=3D tUNUMBER) {
+		if (gds->HaveTime && !gds->HaveYear && !gds->HaveRel) {
+			gds->HaveYear++;
+			gds->Year =3D gds->tokenp[0].value;
+			gds->tokenp +=3D 1;
+			return 1;
+		}
+
+		if(gds->tokenp[0].value > 10000) {
+			/* "20040301" */
+			gds->HaveYear++;
+			gds->HaveMonth++;
+			gds->HaveDay++;
+			gds->Day=3D (gds->tokenp[0].value)%100;
+			gds->Month=3D (gds->tokenp[0].value/100)%100;
+			gds->Year =3D gds->tokenp[0].value/10000;
+			gds->tokenp +=3D 1;
+			return 1;
+		}
+
+		if (gds->tokenp[0].value < 24) {
+			gds->HaveTime++;
+			gds->Hour =3D gds->tokenp[0].value;
+			gds->Minutes =3D 0;
+			gds->Seconds =3D 0;
+			gds->tokenp +=3D 1;
+			return 1;
+		}
+
+		if ((gds->tokenp[0].value / 100 < 24)
+		    && (gds->tokenp[0].value % 100 < 60)) {
+			/* "513" is same as "5:13" */
+			gds->Hour =3D gds->tokenp[0].value / 100;
+			gds->Minutes =3D gds->tokenp[0].value % 100;
+			gds->Seconds =3D 0;
+			gds->tokenp +=3D 1;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * A dictionary of time words.
+ */
+static struct LEXICON {
+	size_t		abbrev;
+	const char	*name;
+	int		type;
+	time_t		value;
+} const TimeWords[] =3D {
+	/* am/pm */
+	{ 0, "am",		tAMPM,	tAM },
+	{ 0, "pm",		tAMPM,	tPM },
+
+	/* Month names. */
+	{ 3, "january",		tMONTH,  1 },
+	{ 3, "february",	tMONTH,  2 },
+	{ 3, "march",		tMONTH,  3 },
+	{ 3, "april",		tMONTH,  4 },
+	{ 3, "may",		tMONTH,  5 },
+	{ 3, "june",		tMONTH,  6 },
+	{ 3, "july",		tMONTH,  7 },
+	{ 3, "august",		tMONTH,  8 },
+	{ 3, "september",	tMONTH,  9 },
+	{ 3, "october",		tMONTH, 10 },
+	{ 3, "november",	tMONTH, 11 },
+	{ 3, "december",	tMONTH, 12 },
+
+	/* Days of the week. */
+	{ 2, "sunday",		tDAY, 0 },
+	{ 3, "monday",		tDAY, 1 },
+	{ 2, "tuesday",		tDAY, 2 },
+	{ 3, "wednesday",	tDAY, 3 },
+	{ 2, "thursday",	tDAY, 4 },
+	{ 2, "friday",		tDAY, 5 },
+	{ 2, "saturday",	tDAY, 6 },
+
+	/* Timezones: Offsets are in seconds. */
+	{ 0, "gmt",  tZONE,     0*HOUR }, /* Greenwich Mean */
+	{ 0, "ut",   tZONE,     0*HOUR }, /* Universal (Coordinated) */
+	{ 0, "utc",  tZONE,     0*HOUR },
+	{ 0, "wet",  tZONE,     0*HOUR }, /* Western European */
+	{ 0, "bst",  tDAYZONE,  0*HOUR }, /* British Summer */
+	{ 0, "wat",  tZONE,     1*HOUR }, /* West Africa */
+	{ 0, "at",   tZONE,     2*HOUR }, /* Azores */
+	/* { 0, "bst", tZONE, 3*HOUR }, */ /* Brazil Standard: Conflict */
+	/* { 0, "gst", tZONE, 3*HOUR }, */ /* Greenland Standard: Conflict*/
+	{ 0, "nft",  tZONE,     3*HOUR+30*MINUTE }, /* Newfoundland */
+	{ 0, "nst",  tZONE,     3*HOUR+30*MINUTE }, /* Newfoundland Standard */
+	{ 0, "ndt",  tDAYZONE,  3*HOUR+30*MINUTE }, /* Newfoundland Daylight */
+	{ 0, "ast",  tZONE,     4*HOUR }, /* Atlantic Standard */
+	{ 0, "adt",  tDAYZONE,  4*HOUR }, /* Atlantic Daylight */
+	{ 0, "est",  tZONE,     5*HOUR }, /* Eastern Standard */
+	{ 0, "edt",  tDAYZONE,  5*HOUR }, /* Eastern Daylight */
+	{ 0, "cst",  tZONE,     6*HOUR }, /* Central Standard */
+	{ 0, "cdt",  tDAYZONE,  6*HOUR }, /* Central Daylight */
+	{ 0, "mst",  tZONE,     7*HOUR }, /* Mountain Standard */
+	{ 0, "mdt",  tDAYZONE,  7*HOUR }, /* Mountain Daylight */
+	{ 0, "pst",  tZONE,     8*HOUR }, /* Pacific Standard */
+	{ 0, "pdt",  tDAYZONE,  8*HOUR }, /* Pacific Daylight */
+	{ 0, "yst",  tZONE,     9*HOUR }, /* Yukon Standard */
+	{ 0, "ydt",  tDAYZONE,  9*HOUR }, /* Yukon Daylight */
+	{ 0, "hst",  tZONE,     10*HOUR }, /* Hawaii Standard */
+	{ 0, "hdt",  tDAYZONE,  10*HOUR }, /* Hawaii Daylight */
+	{ 0, "cat",  tZONE,     10*HOUR }, /* Central Alaska */
+	{ 0, "ahst", tZONE,     10*HOUR }, /* Alaska-Hawaii Standard */
+	{ 0, "nt",   tZONE,     11*HOUR }, /* Nome */
+	{ 0, "idlw", tZONE,     12*HOUR }, /* Intl Date Line West */
+	{ 0, "cet",  tZONE,     -1*HOUR }, /* Central European */
+	{ 0, "met",  tZONE,     -1*HOUR }, /* Middle European */
+	{ 0, "mewt", tZONE,     -1*HOUR }, /* Middle European Winter */
+	{ 0, "mest", tDAYZONE,  -1*HOUR }, /* Middle European Summer */
+	{ 0, "swt",  tZONE,     -1*HOUR }, /* Swedish Winter */
+	{ 0, "sst",  tDAYZONE,  -1*HOUR }, /* Swedish Summer */
+	{ 0, "fwt",  tZONE,     -1*HOUR }, /* French Winter */
+	{ 0, "fst",  tDAYZONE,  -1*HOUR }, /* French Summer */
+	{ 0, "eet",  tZONE,     -2*HOUR }, /* Eastern Eur, USSR Zone 1 */
+	{ 0, "bt",   tZONE,     -3*HOUR }, /* Baghdad, USSR Zone 2 */
+	{ 0, "it",   tZONE,     -3*HOUR-30*MINUTE },/* Iran */
+	{ 0, "zp4",  tZONE,     -4*HOUR }, /* USSR Zone 3 */
+	{ 0, "zp5",  tZONE,     -5*HOUR }, /* USSR Zone 4 */
+	{ 0, "ist",  tZONE,     -5*HOUR-30*MINUTE },/* Indian Standard */
+	{ 0, "zp6",  tZONE,     -6*HOUR }, /* USSR Zone 5 */
+	/* { 0, "nst",  tZONE, -6.5*HOUR }, */ /* North Sumatra: Conflict */
+	/* { 0, "sst", tZONE, -7*HOUR }, */ /* So Sumatra, USSR 6: Conflict */
+	{ 0, "wast", tZONE,     -7*HOUR }, /* West Australian Standard */
+	{ 0, "wadt", tDAYZONE,  -7*HOUR }, /* West Australian Daylight */
+	{ 0, "jt",   tZONE,     -7*HOUR-30*MINUTE },/* Java (3pm in Cronusland!)*/
+	{ 0, "cct",  tZONE,     -8*HOUR }, /* China Coast, USSR Zone 7 */
+	{ 0, "jst",  tZONE,     -9*HOUR }, /* Japan Std, USSR Zone 8 */
+	{ 0, "cast", tZONE,     -9*HOUR-30*MINUTE },/* Ctrl Australian Std */
+	{ 0, "cadt", tDAYZONE,  -9*HOUR-30*MINUTE },/* Ctrl Australian Daylt */
+	{ 0, "east", tZONE,     -10*HOUR }, /* Eastern Australian Std */
+	{ 0, "eadt", tDAYZONE,  -10*HOUR }, /* Eastern Australian Daylt */
+	{ 0, "gst",  tZONE,     -10*HOUR }, /* Guam Std, USSR Zone 9 */
+	{ 0, "nzt",  tZONE,     -12*HOUR }, /* New Zealand */
+	{ 0, "nzst", tZONE,     -12*HOUR }, /* New Zealand Standard */
+	{ 0, "nzdt", tDAYZONE,  -12*HOUR }, /* New Zealand Daylight */
+	{ 0, "idle", tZONE,     -12*HOUR }, /* Intl Date Line East */
+
+	{ 0, "dst",  tDST,		0 },
+
+	/* Time units. */
+	{ 4, "years",		tMONTH_UNIT,	12 },
+	{ 5, "months",		tMONTH_UNIT,	1 },
+	{ 9, "fortnights",	tSEC_UNIT,	14 * DAY },
+	{ 4, "weeks",		tSEC_UNIT,	7 * DAY },
+	{ 3, "days",		tSEC_UNIT,	DAY },
+	{ 4, "hours",		tSEC_UNIT,	HOUR },
+	{ 3, "minutes",		tSEC_UNIT,	MINUTE },
+	{ 3, "seconds",		tSEC_UNIT,	1 },
+
+	/* Relative-time words. */
+	{ 0, "tomorrow",	tSEC_UNIT,	DAY },
+	{ 0, "yesterday",	tSEC_UNIT,	-DAY },
+	{ 0, "today",		tSEC_UNIT,	0 },
+	{ 0, "now",		tSEC_UNIT,	0 },
+	{ 0, "last",		tUNUMBER,	-1 },
+	{ 0, "this",		tSEC_UNIT,	0 },
+	{ 0, "next",		tUNUMBER,	2 },
+	{ 0, "first",		tUNUMBER,	1 },
+	{ 0, "1st",		tUNUMBER,	1 },
+/*	{ 0, "second",		tUNUMBER,	2 }, */
+	{ 0, "2nd",		tUNUMBER,	2 },
+	{ 0, "third",		tUNUMBER,	3 },
+	{ 0, "3rd",		tUNUMBER,	3 },
+	{ 0, "fourth",		tUNUMBER,	4 },
+	{ 0, "4th",		tUNUMBER,	4 },
+	{ 0, "fifth",		tUNUMBER,	5 },
+	{ 0, "5th",		tUNUMBER,	5 },
+	{ 0, "sixth",		tUNUMBER,	6 },
+	{ 0, "seventh",		tUNUMBER,	7 },
+	{ 0, "eighth",		tUNUMBER,	8 },
+	{ 0, "ninth",		tUNUMBER,	9 },
+	{ 0, "tenth",		tUNUMBER,	10 },
+	{ 0, "eleventh",	tUNUMBER,	11 },
+	{ 0, "twelfth",		tUNUMBER,	12 },
+	{ 0, "ago",		tAGO,		1 },
+
+	/* Military timezones. */
+	{ 0, "a",	tZONE,	1*HOUR },
+	{ 0, "b",	tZONE,	2*HOUR },
+	{ 0, "c",	tZONE,	3*HOUR },
+	{ 0, "d",	tZONE,	4*HOUR },
+	{ 0, "e",	tZONE,	5*HOUR },
+	{ 0, "f",	tZONE,	6*HOUR },
+	{ 0, "g",	tZONE,	7*HOUR },
+	{ 0, "h",	tZONE,	8*HOUR },
+	{ 0, "i",	tZONE,	9*HOUR },
+	{ 0, "k",	tZONE,	10*HOUR },
+	{ 0, "l",	tZONE,	11*HOUR },
+	{ 0, "m",	tZONE,	12*HOUR },
+	{ 0, "n",	tZONE,	-1*HOUR },
+	{ 0, "o",	tZONE,	-2*HOUR },
+	{ 0, "p",	tZONE,	-3*HOUR },
+	{ 0, "q",	tZONE,	-4*HOUR },
+	{ 0, "r",	tZONE,	-5*HOUR },
+	{ 0, "s",	tZONE,	-6*HOUR },
+	{ 0, "t",	tZONE,	-7*HOUR },
+	{ 0, "u",	tZONE,	-8*HOUR },
+	{ 0, "v",	tZONE,	-9*HOUR },
+	{ 0, "w",	tZONE,	-10*HOUR },
+	{ 0, "x",	tZONE,	-11*HOUR },
+	{ 0, "y",	tZONE,	-12*HOUR },
+	{ 0, "z",	tZONE,	0*HOUR },
+
+	/* End of table. */
+	{ 0, NULL,	0,	0 }
+};
+
+/*
+ * Year is either:
+ *  =3D A number from 0 to 99, which means a year from 1970 to 2069, or
+ *  =3D The actual year (>=3D100).
+ */
+static time_t
+Convert(time_t Month, time_t Day, time_t Year,
+	time_t Hours, time_t Minutes, time_t Seconds,
+	time_t Timezone, enum DSTMODE DSTmode)
+{
+	static int DaysInMonth[12] =3D {
+		31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+	};
+	time_t	Julian;
+	int	i;
+
+	if (Year < 69)
+		Year +=3D 2000;
+	else if (Year < 100)
+		Year +=3D 1900;
+	DaysInMonth[1] =3D Year % 4 =3D=3D 0 && (Year % 100 !=3D 0 || Year % 400 =
=3D=3D 0)
+	    ? 29 : 28;
+	/* Checking for 2038 bogusly assumes that time_t is 32 bits.  But
+	   I'm too lazy to try to check for time_t overflow in another way.  */
+	if (Year < EPOCH || Year > 2038
+	    || Month < 1 || Month > 12
+	    /* Lint fluff:  "conversion from long may lose accuracy" */
+	    || Day < 1 || Day > DaysInMonth[(int)--Month]
+	    || Hours < 0 || Hours > 23
+	    || Minutes < 0 || Minutes > 59
+	    || Seconds < 0 || Seconds > 59)
+		return -1;
+
+	Julian =3D Day - 1;
+	for (i =3D 0; i < Month; i++)
+		Julian +=3D DaysInMonth[i];
+	for (i =3D EPOCH; i < Year; i++)
+		Julian +=3D 365 + (i % 4 =3D=3D 0);
+	Julian *=3D DAY;
+	Julian +=3D Timezone;
+	Julian +=3D Hours * HOUR + Minutes * MINUTE + Seconds;
+	if (DSTmode =3D=3D DSTon
+	    || (DSTmode =3D=3D DSTmaybe && localtime(&Julian)->tm_isdst))
+		Julian -=3D HOUR;
+	return Julian;
+}
+
+
+static time_t
+DSTcorrect(time_t Start, time_t Future)
+{
+	time_t	StartDay;
+	time_t	FutureDay;
+
+	StartDay =3D (localtime(&Start)->tm_hour + 1) % 24;
+	FutureDay =3D (localtime(&Future)->tm_hour + 1) % 24;
+	return (Future - Start) + (StartDay - FutureDay) * HOUR;
+}
+
+
+static time_t
+RelativeDate(time_t Start, time_t zone, int dstmode,
+    time_t DayOrdinal, time_t DayNumber)
+{
+	struct tm	*tm;
+	time_t	t, now;
+
+	t =3D Start - zone;
+	tm =3D gmtime(&t);
+	now =3D Start;
+	now +=3D DAY * ((DayNumber - tm->tm_wday + 7) % 7);
+	now +=3D 7 * DAY * (DayOrdinal <=3D 0 ? DayOrdinal : DayOrdinal - 1);
+	if (dstmode =3D=3D DSTmaybe)
+		return DSTcorrect(Start, now);
+	return now - Start;
+}
+
+
+static time_t
+RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
+{
+	struct tm	*tm;
+	time_t	Month;
+	time_t	Year;
+
+	if (RelMonth =3D=3D 0)
+		return 0;
+	tm =3D localtime(&Start);
+	Month =3D 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
+	Year =3D Month / 12;
+	Month =3D Month % 12 + 1;
+	return DSTcorrect(Start,
+	    Convert(Month, (time_t)tm->tm_mday, Year,
+		(time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
+		Timezone, DSTmaybe));
+}
+
+/*
+ * Tokenizer.
+ */
+static int
+nexttoken(char **in, time_t *value)
+{
+	char	c;
+	char	buff[64];
+
+	for ( ; ; ) {
+		while (isspace((unsigned char)**in))
+			++*in;
+
+		/* Skip parenthesized comments. */
+		if (**in =3D=3D '(') {
+			int Count =3D 0;
+			do {
+				c =3D *(*in)++;
+				if (c =3D=3D '\0')
+					return c;
+				if (c =3D=3D '(')
+					Count++;
+				else if (c =3D=3D ')')
+					Count--;
+			} while (Count > 0);
+			continue;
+		}
+
+		/* Try the next token in the word table first. */
+		/* This allows us to match "2nd", for example. */
+		{
+			char *src =3D *in;
+			const struct LEXICON *tp;
+			unsigned i =3D 0;
+
+			/* Force to lowercase and strip '.' characters. */
+			while (*src !=3D '\0'
+			    && (isalnum((unsigned char)*src) || *src =3D=3D '.')
+			    && i < sizeof(buff)-1) {
+				if (*src !=3D '.') {
+					if (isupper((unsigned char)*src))
+						buff[i++] =3D tolower((unsigned char)*src);
+					else
+						buff[i++] =3D *src;
+				}
+				src++;
+			}
+			buff[i] =3D '\0';
+
+			/*
+			 * Find the first match.  If the word can be
+			 * abbreviated, make sure we match at least
+			 * the minimum abbreviation.
+			 */
+			for (tp =3D TimeWords; tp->name; tp++) {
+				size_t abbrev =3D tp->abbrev;
+				if (abbrev =3D=3D 0)
+					abbrev =3D strlen(tp->name);
+				if (strlen(buff) >=3D abbrev
+				    && strncmp(tp->name, buff, strlen(buff))
+				    	=3D=3D 0) {
+					/* Skip over token. */
+					*in =3D src;
+					/* Return the match. */
+					*value =3D tp->value;
+					return tp->type;
+				}
+			}
+		}
+
+		/*
+		 * Not in the word table, maybe it's a number.  Note:
+		 * Because '-' and '+' have other special meanings, I
+		 * don't deal with signed numbers here.
+		 */
+		if (isdigit((unsigned char)(c =3D **in))) {
+			for (*value =3D 0; isdigit((unsigned char)(c =3D *(*in)++)); )
+				*value =3D 10 * *value + c - '0';
+			(*in)--;
+			return (tUNUMBER);
+		}
+
+		return *(*in)++;
+	}
+}
+
+#define	TM_YEAR_ORIGIN 1900
+
+/* Yield A - B, measured in seconds.  */
+static long
+difftm (struct tm *a, struct tm *b)
+{
+	int ay =3D a->tm_year + (TM_YEAR_ORIGIN - 1);
+	int by =3D b->tm_year + (TM_YEAR_ORIGIN - 1);
+	int days =3D (
+		/* difference in day of year */
+		a->tm_yday - b->tm_yday
+		/* + intervening leap days */
+		+  ((ay >> 2) - (by >> 2))
+		-  (ay/100 - by/100)
+		+  ((ay/100 >> 2) - (by/100 >> 2))
+		/* + difference in years * 365 */
+		+  (long)(ay-by) * 365
+		);
+	return (days * DAY + (a->tm_hour - b->tm_hour) * HOUR
+	    + (a->tm_min - b->tm_min) * MINUTE
+	    + (a->tm_sec - b->tm_sec));
+}
+
+/*
+ *
+ * The public function.
+ *
+ * TODO: tokens[] array should be dynamically sized.
+ */
+time_t
+__archive_get_date(time_t now, char *p)
+{
+	struct token	tokens[256];
+	struct gdstate	_gds;
+	struct token	*lasttoken;
+	struct gdstate	*gds;
+	struct tm	local, *tm;
+	struct tm	gmt, *gmt_ptr;
+	time_t		Start;
+	time_t		tod;
+	long		tzone;
+
+	/* Clear out the parsed token array. */
+	memset(tokens, 0, sizeof(tokens));
+	/* Initialize the parser state. */
+	memset(&_gds, 0, sizeof(_gds));
+	gds =3D &_gds;
+
+	/* Look up the current time. */
+	memset(&local, 0, sizeof(local));
+	tm =3D localtime (&now);
+	if (tm =3D=3D NULL)
+		return -1;
+	local =3D *tm;
+
+	/* Look up UTC if we can and use that to determine the current
+	 * timezone offset. */
+	memset(&gmt, 0, sizeof(gmt));
+	gmt_ptr =3D gmtime (&now);
+	if (gmt_ptr !=3D NULL) {
+		/* Copy, in case localtime and gmtime use the same buffer. */
+		gmt =3D *gmt_ptr;
+	}
+	if (gmt_ptr !=3D NULL)
+		tzone =3D difftm (&gmt, &local);
+	else
+		/* This system doesn't understand timezones; fake it. */
+		tzone =3D 0;
+	if(local.tm_isdst)
+		tzone +=3D HOUR;
+
+	/* Tokenize the input string. */
+	lasttoken =3D tokens;
+	while ((lasttoken->token =3D nexttoken(&p, &lasttoken->value)) !=3D 0) {
+		++lasttoken;
+		if (lasttoken > tokens + 255)
+			return -1;
+	}
+	gds->tokenp =3D tokens;
+
+	/* Match phrases until we run out of input tokens. */
+	while (gds->tokenp < lasttoken) {
+		if (!phrase(gds))
+			return -1;
+	}
+
+	/* Use current local timezone if none was specified. */
+	if (!gds->HaveZone) {
+		gds->Timezone =3D tzone;
+		gds->DSTmode =3D DSTmaybe;
+	}
+
+	/* If a timezone was specified, use that for generating the default
+	 * time components instead of the local timezone. */
+	if (gds->HaveZone && gmt_ptr !=3D NULL) {
+		now -=3D gds->Timezone;
+		gmt_ptr =3D gmtime (&now);
+		if (gmt_ptr !=3D NULL)
+			local =3D *gmt_ptr;
+		now +=3D gds->Timezone;
+	}
+
+	if (!gds->HaveYear)
+		gds->Year =3D local.tm_year + 1900;
+	if (!gds->HaveMonth)
+		gds->Month =3D local.tm_mon + 1;
+	if (!gds->HaveDay)
+		gds->Day =3D local.tm_mday;
+	/* Note: No default for hour/min/sec; a specifier that just
+	 * gives date always refers to 00:00 on that date. */
+
+	/* If we saw more than one time, timezone, weekday, year, month,
+	 * or day, then give up. */
+	if (gds->HaveTime > 1 || gds->HaveZone > 1 || gds->HaveWeekDay > 1
+	    || gds->HaveYear > 1 || gds->HaveMonth > 1 || gds->HaveDay > 1)
+		return -1;
+
+	/* Compute an absolute time based on whatever absolute information
+	 * we collected. */
+	if (gds->HaveYear || gds->HaveMonth || gds->HaveDay
+	    || gds->HaveTime || gds->HaveWeekDay) {
+		Start =3D Convert(gds->Month, gds->Day, gds->Year,
+		    gds->Hour, gds->Minutes, gds->Seconds,
+		    gds->Timezone, gds->DSTmode);
+		if (Start < 0)
+			return -1;
+	} else {
+		Start =3D now;
+		if (!gds->HaveRel)
+			Start -=3D local.tm_hour * HOUR + local.tm_min * MINUTE
+			    + local.tm_sec;
+	}
+
+	/* Add the relative offset. */
+	Start +=3D gds->RelSeconds;
+	Start +=3D RelativeMonth(Start, gds->Timezone, gds->RelMonth);
+
+	/* Adjust for day-of-week offsets. */
+	if (gds->HaveWeekDay
+	    && !(gds->HaveYear || gds->HaveMonth || gds->HaveDay)) {
+		tod =3D RelativeDate(Start, gds->Timezone,
+		    gds->DSTmode, gds->DayOrdinal, gds->DayNumber);
+		Start +=3D tod;
+	}
+
+	/* -1 is an error indicator, so return 0 instead of -1 if
+	 * that's the actual time. */
+	return Start =3D=3D -1 ? 0 : Start;
+}
+
+
+#if	defined(TEST)
+
+/* ARGSUSED */
+int
+main(int argc, char **argv)
+{
+    time_t	d;
+
+    while (*++argv !=3D NULL) {
+	    (void)printf("Input: %s\n", *argv);
+	    d =3D get_date(*argv);
+	    if (d =3D=3D -1)
+		    (void)printf("Bad format - couldn't convert.\n");
+	    else
+		    (void)printf("Output: %s\n", ctime(&d));
+    }
+    exit(0);
+    /* NOTREACHED */
+}
+#endif	/* defined(TEST) */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_match.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/archive_match.c	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -0,0 +1,1836 @@
+/*-
+ * Copyright (c) 2003-2007 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_entry.h"
+#include "archive_pathmatch.h"
+#include "archive_rb.h"
+#include "archive_string.h"
+
+struct match {
+	struct match		*next;
+	int			 matches;
+	struct archive_mstring	 pattern;
+};
+
+struct match_list {
+	struct match		*first;
+	struct match		**last;
+	int			 count;
+	int			 unmatched_count;
+	struct match		*unmatched_next;
+	int			 unmatched_eof;
+};
+
+struct match_file {
+	struct archive_rb_node	 node;
+	struct match_file	*next;
+	struct archive_mstring	 pathname;
+	int			 flag;
+	time_t			 mtime_sec;
+	long			 mtime_nsec;
+	time_t			 ctime_sec;
+	long			 ctime_nsec;
+};
+
+struct entry_list {
+	struct match_file	*first;
+	struct match_file	**last;
+	int			 count;
+};
+
+struct id_array {
+	size_t			 size;/* Allocated size */
+	size_t			 count;
+	int64_t			*ids;
+};
+
+#define PATTERN_IS_SET		1
+#define TIME_IS_SET		2
+#define ID_IS_SET		4
+
+struct archive_match {
+	struct archive		 archive;
+
+	/* exclusion/inclusion set flag. */
+	int			 setflag;
+
+	/*
+	 * Matching filename patterns.
+	 */
+	struct match_list	 exclusions;
+	struct match_list	 inclusions;
+
+	/*
+	 * Matching time stamps.
+	 */
+	time_t			 now;
+	int			 newer_mtime_filter;
+	time_t			 newer_mtime_sec;
+	long			 newer_mtime_nsec;
+	int			 newer_ctime_filter;
+	time_t			 newer_ctime_sec;
+	long			 newer_ctime_nsec;
+	int			 older_mtime_filter;
+	time_t			 older_mtime_sec;
+	long			 older_mtime_nsec;
+	int			 older_ctime_filter;
+	time_t			 older_ctime_sec;
+	long			 older_ctime_nsec;
+	/*
+	 * Matching time stamps with its filename.
+	 */
+	struct archive_rb_tree	 exclusion_tree;
+	struct entry_list 	 exclusion_entry_list;
+
+	/*
+	 * Matching file owners.
+	 */
+	struct id_array 	 inclusion_uids;
+	struct id_array 	 inclusion_gids;
+	struct match_list	 inclusion_unames;
+	struct match_list	 inclusion_gnames;
+};
+
+static int	add_pattern_from_file(struct archive_match *,
+		    struct match_list *, int, const void *, int);
+static int	add_entry(struct archive_match *, int,
+		    struct archive_entry *);
+static int	add_owner_id(struct archive_match *, struct id_array *,
+		    int64_t);
+static int	add_owner_name(struct archive_match *, struct match_list *,
+		    int, const void *);
+static int	add_pattern_mbs(struct archive_match *, struct match_list *,
+		    const char *);
+static int	add_pattern_wcs(struct archive_match *, struct match_list *,
+		    const wchar_t *);
+static int	cmp_key_mbs(const struct archive_rb_node *, const void *);
+static int	cmp_key_wcs(const struct archive_rb_node *, const void *);
+static int	cmp_node_mbs(const struct archive_rb_node *,
+		    const struct archive_rb_node *);
+static int	cmp_node_wcs(const struct archive_rb_node *,
+		    const struct archive_rb_node *);
+static void	entry_list_add(struct entry_list *, struct match_file *);
+static void	entry_list_free(struct entry_list *);
+static void	entry_list_init(struct entry_list *);
+static int	error_nomem(struct archive_match *);
+static void	match_list_add(struct match_list *, struct match *);
+static void	match_list_free(struct match_list *);
+static void	match_list_init(struct match_list *);
+static int	match_list_unmatched_inclusions_next(struct archive_match *,
+		    struct match_list *, int, const void **);
+static int	match_owner_id(struct id_array *, int64_t);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static int	match_owner_name_mbs(struct archive_match *,
+		    struct match_list *, const char *);
+#else
+static int	match_owner_name_wcs(struct archive_match *,
+		    struct match_list *, const wchar_t *);
+#endif
+static int	match_path_exclusion(struct archive_match *,
+		    struct match *, int, const void *);
+static int	match_path_inclusion(struct archive_match *,
+		    struct match *, int, const void *);
+static int	owner_excluded(struct archive_match *,
+		    struct archive_entry *);
+static int	path_excluded(struct archive_match *, int, const void *);
+static int	set_timefilter(struct archive_match *, int, time_t, long,
+		    time_t, long);
+static int	set_timefilter_pathname_mbs(struct archive_match *,
+		    int, const char *);
+static int	set_timefilter_pathname_wcs(struct archive_match *,
+		    int, const wchar_t *);
+static int	set_timefilter_date(struct archive_match *, int, const char *);
+static int	set_timefilter_date_w(struct archive_match *, int,
+		    const wchar_t *);
+static int	time_excluded(struct archive_match *,
+		    struct archive_entry *);
+static int	validate_time_flag(struct archive *, int, const char *);
+
+time_t __archive_get_date(time_t now, const char *);
+#define get_date __archive_get_date
+
+static const struct archive_rb_tree_ops rb_ops_mbs =3D {
+	cmp_node_mbs, cmp_key_mbs
+};
+
+static const struct archive_rb_tree_ops rb_ops_wcs =3D {
+	cmp_node_wcs, cmp_key_wcs
+};
+
+/*
+ * The matching logic here needs to be re-thought.  I started out to
+ * try to mimic gtar's matching logic, but it's not entirely
+ * consistent.  In particular 'tar -t' and 'tar -x' interpret patterns
+ * on the command line as anchored, but --exclude doesn't.
+ */
+
+static int
+error_nomem(struct archive_match *a)
+{
+	archive_set_error(&(a->archive), ENOMEM, "No memory");
+	a->archive.state =3D ARCHIVE_STATE_FATAL;
+	return (ARCHIVE_FATAL);
+}
+
+/*
+ * Create an ARCHIVE_MATCH object.
+ */
+struct archive *
+archive_match_new(void)
+{
+	struct archive_match *a;
+
+	a =3D (struct archive_match *)calloc(1, sizeof(*a));
+	if (a =3D=3D NULL)
+		return (NULL);
+	a->archive.magic =3D ARCHIVE_MATCH_MAGIC;
+	a->archive.state =3D ARCHIVE_STATE_NEW;
+	match_list_init(&(a->inclusions));
+	match_list_init(&(a->exclusions));
+	__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
+	entry_list_init(&(a->exclusion_entry_list));
+	match_list_init(&(a->inclusion_unames));
+	match_list_init(&(a->inclusion_gnames));
+	time(&a->now);
+	return (&(a->archive));
+}
+
+/*
+ * Free an ARCHIVE_MATCH object.
+ */
+int
+archive_match_free(struct archive *_a)
+{
+	struct archive_match *a;
+
+	if (_a =3D=3D NULL)
+		return (ARCHIVE_OK);
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_match_free");
+	a =3D (struct archive_match *)_a;
+	match_list_free(&(a->inclusions));
+	match_list_free(&(a->exclusions));
+	entry_list_free(&(a->exclusion_entry_list));
+	free(a->inclusion_uids.ids);
+	free(a->inclusion_gids.ids);
+	match_list_free(&(a->inclusion_unames));
+	match_list_free(&(a->inclusion_gnames));
+	free(a);
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Convenience function to perform all exclusion tests.
+ *
+ * Returns 1 if archive entry is excluded.
+ * Returns 0 if archive entry is not excluded.
+ * Returns <0 if something error happened.
+ */
+int
+archive_match_excluded(struct archive *_a, struct archive_entry *entry)
+{
+	struct archive_match *a;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_excluded_ae");
+
+	a =3D (struct archive_match *)_a;
+	if (entry =3D=3D NULL) {
+		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
+		return (ARCHIVE_FAILED);
+	}
+
+	r =3D 0;
+	if (a->setflag & PATTERN_IS_SET) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+		r =3D path_excluded(a, 0, archive_entry_pathname_w(entry));
+#else
+		r =3D path_excluded(a, 1, archive_entry_pathname(entry));
+#endif
+		if (r !=3D 0)
+			return (r);
+	}
+
+	if (a->setflag & TIME_IS_SET) {
+		r =3D time_excluded(a, entry);
+		if (r !=3D 0)
+			return (r);
+	}
+
+	if (a->setflag & ID_IS_SET)
+		r =3D owner_excluded(a, entry);
+	return (r);
+}
+
+/*
+ * Utility functions to manage exclusion/inclusion patterns
+ */
+
+int
+archive_match_exclude_pattern(struct archive *_a, const char *pattern)
+{
+	struct archive_match *a;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern");
+	a =3D (struct archive_match *)_a;
+
+	if (pattern =3D=3D NULL || *pattern =3D=3D '\0') {
+		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
+		return (ARCHIVE_FAILED);
+	}
+	if ((r =3D add_pattern_mbs(a, &(a->exclusions), pattern)) !=3D ARCHIVE_OK)
+		return (r);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_match_exclude_pattern_w(struct archive *_a, const wchar_t *pattern)
+{
+	struct archive_match *a;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_w");
+	a =3D (struct archive_match *)_a;
+
+	if (pattern =3D=3D NULL || *pattern =3D=3D L'\0') {
+		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
+		return (ARCHIVE_FAILED);
+	}
+	if ((r =3D add_pattern_wcs(a, &(a->exclusions), pattern)) !=3D ARCHIVE_OK)
+		return (r);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_match_exclude_pattern_from_file(struct archive *_a,
+    const char *pathname, int nullSeparator)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file");
+	a =3D (struct archive_match *)_a;
+
+	return add_pattern_from_file(a, &(a->exclusions), 1, pathname,
+		nullSeparator);
+}
+
+int
+archive_match_exclude_pattern_from_file_w(struct archive *_a,
+    const wchar_t *pathname, int nullSeparator)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file_w");
+	a =3D (struct archive_match *)_a;
+
+	return add_pattern_from_file(a, &(a->exclusions), 0, pathname,
+		nullSeparator);
+}
+
+int
+archive_match_include_pattern(struct archive *_a, const char *pattern)
+{
+	struct archive_match *a;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_pattern");
+	a =3D (struct archive_match *)_a;
+
+	if (pattern =3D=3D NULL || *pattern =3D=3D '\0') {
+		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
+		return (ARCHIVE_FAILED);
+	}
+	if ((r =3D add_pattern_mbs(a, &(a->inclusions), pattern)) !=3D ARCHIVE_OK)
+		return (r);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_match_include_pattern_w(struct archive *_a, const wchar_t *pattern)
+{
+	struct archive_match *a;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_pattern_w");
+	a =3D (struct archive_match *)_a;
+
+	if (pattern =3D=3D NULL || *pattern =3D=3D L'\0') {
+		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
+		return (ARCHIVE_FAILED);
+	}
+	if ((r =3D add_pattern_wcs(a, &(a->inclusions), pattern)) !=3D ARCHIVE_OK)
+		return (r);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_match_include_pattern_from_file(struct archive *_a,
+    const char *pathname, int nullSeparator)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file");
+	a =3D (struct archive_match *)_a;
+
+	return add_pattern_from_file(a, &(a->inclusions), 1, pathname,
+		nullSeparator);
+}
+
+int
+archive_match_include_pattern_from_file_w(struct archive *_a,
+    const wchar_t *pathname, int nullSeparator)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file_w");
+	a =3D (struct archive_match *)_a;
+
+	return add_pattern_from_file(a, &(a->inclusions), 0, pathname,
+		nullSeparator);
+}
+
+/*
+ * Test functions for pathname patterns.
+ *
+ * Returns 1 if archive entry is excluded.
+ * Returns 0 if archive entry is not excluded.
+ * Returns <0 if something error happened.
+ */
+int
+archive_match_path_excluded(struct archive *_a,
+    struct archive_entry *entry)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_path_excluded");
+
+	a =3D (struct archive_match *)_a;
+	if (entry =3D=3D NULL) {
+		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* If we don't have exclusion/inclusion pattern set at all,
+	 * the entry is always not excluded. */
+	if ((a->setflag & PATTERN_IS_SET) =3D=3D 0)
+		return (0);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	return (path_excluded(a, 0, archive_entry_pathname_w(entry)));
+#else
+	return (path_excluded(a, 1, archive_entry_pathname(entry)));
+#endif
+}
+
+/*
+ * Utilty functions to get statistic information for inclusion patterns.
+ */
+int
+archive_match_path_unmatched_inclusions(struct archive *_a)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
+	a =3D (struct archive_match *)_a;
+
+	return (a->inclusions.unmatched_count);
+}
+
+int
+archive_match_path_unmatched_inclusions_next(struct archive *_a,
+    const char **_p)
+{
+	struct archive_match *a;
+	const void *v;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next");
+	a =3D (struct archive_match *)_a;
+
+	r =3D match_list_unmatched_inclusions_next(a, &(a->inclusions), 1, &v);
+	*_p =3D (const char *)v;
+	return (r);
+}
+
+int
+archive_match_path_unmatched_inclusions_next_w(struct archive *_a,
+    const wchar_t **_p)
+{
+	struct archive_match *a;
+	const void *v;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next_w");
+	a =3D (struct archive_match *)_a;
+
+	r =3D match_list_unmatched_inclusions_next(a, &(a->inclusions), 0, &v);
+	*_p =3D (const wchar_t *)v;
+	return (r);
+}
+
+/*
+ * Add inclusion/exclusion patterns.
+ */
+static int
+add_pattern_mbs(struct archive_match *a, struct match_list *list,
+    const char *pattern)
+{
+	struct match *match;
+	size_t len;
+
+	match =3D calloc(1, sizeof(*match));
+	if (match =3D=3D NULL)
+		return (error_nomem(a));
+	/* Both "foo/" and "foo" should match "foo/bar". */
+	len =3D strlen(pattern);
+	if (len && pattern[len - 1] =3D=3D '/')
+		--len;
+	archive_mstring_copy_mbs_len(&(match->pattern), pattern, len);
+	match_list_add(list, match);
+	a->setflag |=3D PATTERN_IS_SET;
+	return (ARCHIVE_OK);
+}
+
+static int
+add_pattern_wcs(struct archive_match *a, struct match_list *list,
+    const wchar_t *pattern)
+{
+	struct match *match;
+	size_t len;
+
+	match =3D calloc(1, sizeof(*match));
+	if (match =3D=3D NULL)
+		return (error_nomem(a));
+	/* Both "foo/" and "foo" should match "foo/bar". */
+	len =3D wcslen(pattern);
+	if (len && pattern[len - 1] =3D=3D L'/')
+		--len;
+	archive_mstring_copy_wcs_len(&(match->pattern), pattern, len);
+	match_list_add(list, match);
+	a->setflag |=3D PATTERN_IS_SET;
+	return (ARCHIVE_OK);
+}
+
+static int
+add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
+    int mbs, const void *pathname, int nullSeparator)
+{
+	struct archive *ar;
+	struct archive_entry *ae;
+	struct archive_string as;
+	const void *buff;
+	size_t size;
+	int64_t offset;
+	int r;
+
+	ar =3D archive_read_new();=20
+	if (ar =3D=3D NULL) {
+		archive_set_error(&(a->archive), ENOMEM, "No memory");
+		return (ARCHIVE_FATAL);
+	}
+	r =3D archive_read_support_format_raw(ar);
+	if (r !=3D ARCHIVE_OK) {
+		archive_copy_error(&(a->archive), ar);
+		archive_read_free(ar);
+		return (r);
+	}
+	if (mbs)
+		r =3D archive_read_open_filename(ar, pathname, 512*20);
+	else
+		r =3D archive_read_open_filename_w(ar, pathname, 512*20);
+	if (r !=3D ARCHIVE_OK) {
+		archive_copy_error(&(a->archive), ar);
+		archive_read_free(ar);
+		return (r);
+	}
+	r =3D archive_read_next_header(ar, &ae);
+	if (r !=3D ARCHIVE_OK) {
+		archive_copy_error(&(a->archive), ar);
+		archive_read_free(ar);
+		return (r);
+	}
+
+	archive_string_init(&as);
+
+	while ((r =3D archive_read_data_block(ar, &buff, &size, &offset))
+	    =3D=3D ARCHIVE_OK) {
+		const char *b =3D (const char *)buff;
+
+		while (size) {
+			const char *s =3D (const char *)b;
+			size_t length =3D 0;
+			int found_separator =3D 0;
+
+			while (length < size) {
+				if (nullSeparator) {
+					if (*b =3D=3D '\0') {
+						found_separator =3D 1;
+						break;
+					}
+				} else {
+			            	if (*b =3D=3D 0x0d || *b =3D=3D 0x0a) {
+						found_separator =3D 1;
+						break;
+					}
+				}
+				b++;
+				length++;
+			}
+			if (!found_separator) {
+				archive_strncat(&as, s, length);
+				/* Read next data block. */
+				break;
+			}
+			b++;
+			size -=3D length + 1;
+			archive_strncat(&as, s, length);
+
+			/* If the line is not empty, add the pattern. */
+			if (archive_strlen(&as) > 0) {
+				/* Add pattern. */
+				r =3D add_pattern_mbs(a, mlist, as.s);
+				if (r !=3D ARCHIVE_OK) {
+					archive_read_free(ar);
+					archive_string_free(&as);
+					return (r);
+				}
+				archive_string_empty(&as);
+			}
+		}
+	}
+
+	/* If something error happend, report it immediately. */=20
+	if (r < ARCHIVE_OK) {
+		archive_copy_error(&(a->archive), ar);
+		archive_read_free(ar);
+		archive_string_free(&as);
+		return (r);
+	}
+
+	/* If the line is not empty, add the pattern. */
+	if (r =3D=3D ARCHIVE_EOF && archive_strlen(&as) > 0) {
+		/* Add pattern. */
+		r =3D add_pattern_mbs(a, mlist, as.s);
+		if (r !=3D ARCHIVE_OK) {
+			archive_read_free(ar);
+			archive_string_free(&as);
+			return (r);
+		}
+	}
+	archive_read_free(ar);
+	archive_string_free(&as);
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Test if pathname is excluded by inclusion/exclusion patterns.
+ */
+static int
+path_excluded(struct archive_match *a, int mbs, const void *pathname)
+{
+	struct match *match;
+	struct match *matched;
+	int r;
+
+	if (a =3D=3D 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 =3D NULL;
+	for (match =3D a->inclusions.first; match !=3D NULL;
+	    match =3D match->next){
+		if (match->matches =3D=3D 0 &&
+		    (r =3D match_path_inclusion(a, match, mbs, pathname)) !=3D 0) {
+			if (r < 0)
+				return (r);
+			a->inclusions.unmatched_count--;
+			match->matches++;
+			matched =3D match;
+		}
+	}
+
+	/* Exclusions take priority */
+	for (match =3D a->exclusions.first; match !=3D NULL;
+	    match =3D match->next){
+		r =3D match_path_exclusion(a, match, mbs, pathname);
+		if (r)
+			return (r);
+	}
+
+	/* It's not excluded and we found an inclusion above, so it's
+	 * included. */
+	if (matched !=3D NULL)
+		return (0);
+
+
+	/* We didn't find an unmatched inclusion, check the remaining ones. */
+	for (match =3D a->inclusions.first; match !=3D NULL;
+	    match =3D match->next){
+		/* We looked at previously-unmatched inclusions already. */
+		if (match->matches > 0 &&
+		    (r =3D match_path_inclusion(a, match, mbs, pathname)) !=3D 0) {
+			if (r < 0)
+				return (r);
+			match->matches++;
+			return (0);
+		}
+	}
+
+	/* If there were inclusions, default is to exclude. */
+	if (a->inclusions.first !=3D NULL)
+	    return (1);
+
+	/* No explicit inclusions, default is to match. */
+	return (0);
+}
+
+/*
+ * This is a little odd, but it matches the default behavior of
+ * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
+ *
+ */
+static int
+match_path_exclusion(struct archive_match *a, struct match *m,
+    int mbs, const void *pn)
+{
+	int flag =3D PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END;
+	int r;
+
+	if (mbs) {
+		const char *p;
+		r =3D archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
+		if (r =3D=3D 0)
+			return (archive_pathmatch(p, (const char *)pn, flag));
+	} else {
+		const wchar_t *p;
+		r =3D archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
+		if (r =3D=3D 0)
+			return (archive_pathmatch_w(p, (const wchar_t *)pn,
+				flag));
+	}
+	if (errno =3D=3D ENOMEM)
+		return (error_nomem(a));
+	return (0);
+}
+
+/*
+ * Again, mimic gtar:  inclusions are always anchored (have to match
+ * the beginning of the path) even though exclusions are not anchored.
+ */
+static int
+match_path_inclusion(struct archive_match *a, struct match *m,
+    int mbs, const void *pn)
+{
+	int flag =3D PATHMATCH_NO_ANCHOR_END;
+	int r;
+
+	if (mbs) {
+		const char *p;
+		r =3D archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
+		if (r =3D=3D 0)
+			return (archive_pathmatch(p, (const char *)pn, flag));
+	} else {
+		const wchar_t *p;
+		r =3D archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
+		if (r =3D=3D 0)
+			return (archive_pathmatch_w(p, (const wchar_t *)pn,
+				flag));
+	}
+	if (errno =3D=3D ENOMEM)
+		return (error_nomem(a));
+	return (0);
+}
+
+static void
+match_list_init(struct match_list *list)
+{
+	list->first =3D NULL;
+	list->last =3D &(list->first);
+	list->count =3D 0;
+}
+
+static void
+match_list_free(struct match_list *list)
+{
+	struct match *p, *q;
+
+	for (p =3D list->first; p !=3D NULL; ) {
+		q =3D p;
+		p =3D p->next;
+		archive_mstring_clean(&(q->pattern));
+		free(q);
+	}
+}
+
+static void
+match_list_add(struct match_list *list, struct match *m)
+{
+	*list->last =3D m;
+	list->last =3D &(m->next);
+	list->count++;
+	list->unmatched_count++;
+}
+
+static int
+match_list_unmatched_inclusions_next(struct archive_match *a,
+    struct match_list *list, int mbs, const void **vp)
+{
+	struct match *m;
+
+	*vp =3D NULL;
+	if (list->unmatched_eof) {
+		list->unmatched_eof =3D 0;
+		return (ARCHIVE_EOF);
+	}
+	if (list->unmatched_next =3D=3D NULL) {
+		if (list->unmatched_count =3D=3D 0)
+			return (ARCHIVE_EOF);
+		list->unmatched_next =3D list->first;
+	}
+
+	for (m =3D list->unmatched_next; m !=3D NULL; m =3D m->next) {
+		int r;
+
+		if (m->matches)
+			continue;
+		if (mbs) {
+			const char *p;
+			r =3D archive_mstring_get_mbs(&(a->archive),
+				&(m->pattern), &p);
+			if (r < 0 && errno =3D=3D ENOMEM)
+				return (error_nomem(a));
+			if (p =3D=3D NULL)
+				p =3D "";
+			*vp =3D p;
+		} else {
+			const wchar_t *p;
+			r =3D archive_mstring_get_wcs(&(a->archive),
+				&(m->pattern), &p);
+			if (r < 0 && errno =3D=3D ENOMEM)
+				return (error_nomem(a));
+			if (p =3D=3D NULL)
+				p =3D L"";
+			*vp =3D p;
+		}
+		list->unmatched_next =3D m->next;
+		if (list->unmatched_next =3D=3D NULL)
+			/* To return EOF next time. */
+			list->unmatched_eof =3D 1;
+		return (ARCHIVE_OK);
+	}
+	list->unmatched_next =3D NULL;
+	return (ARCHIVE_EOF);
+}
+
+/*
+ * Utility functions to manage inclusion timestamps.
+ */
+int
+archive_match_include_time(struct archive *_a, int flag, time_t sec,
+    long nsec)
+{
+	int r;
+
+	r =3D validate_time_flag(_a, flag, "archive_match_include_time");
+	if (r !=3D ARCHIVE_OK)
+		return (r);
+	return set_timefilter((struct archive_match *)_a, flag,
+			sec, nsec, sec, nsec);
+}
+
+int
+archive_match_include_date(struct archive *_a, int flag,
+    const char *datestr)
+{
+	int r;
+
+	r =3D validate_time_flag(_a, flag, "archive_match_include_date");
+	if (r !=3D ARCHIVE_OK)
+		return (r);
+	return set_timefilter_date((struct archive_match *)_a, flag, datestr);
+}
+
+int
+archive_match_include_date_w(struct archive *_a, int flag,
+    const wchar_t *datestr)
+{
+	int r;
+
+	r =3D validate_time_flag(_a, flag, "archive_match_include_date_w");
+	if (r !=3D ARCHIVE_OK)
+		return (r);
+
+	return set_timefilter_date_w((struct archive_match *)_a, flag, datestr);
+}
+
+int
+archive_match_include_file_time(struct archive *_a, int flag,
+    const char *pathname)
+{
+	int r;
+
+	r =3D validate_time_flag(_a, flag, "archive_match_include_file_time");
+	if (r !=3D ARCHIVE_OK)
+		return (r);
+	return set_timefilter_pathname_mbs((struct archive_match *)_a,
+			flag, pathname);
+}
+
+int
+archive_match_include_file_time_w(struct archive *_a, int flag,
+    const wchar_t *pathname)
+{
+	int r;
+
+	r =3D validate_time_flag(_a, flag, "archive_match_include_file_time_w");
+	if (r !=3D ARCHIVE_OK)
+		return (r);
+	return set_timefilter_pathname_wcs((struct archive_match *)_a,
+			flag, pathname);
+}
+
+int
+archive_match_exclude_entry(struct archive *_a, int flag,
+    struct archive_entry *entry)
+{
+	struct archive_match *a;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_time_include_entry");
+	a =3D (struct archive_match *)_a;
+
+	if (entry =3D=3D NULL) {
+		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
+		return (ARCHIVE_FAILED);
+	}
+	r =3D validate_time_flag(_a, flag, "archive_match_exclude_entry");
+	if (r !=3D ARCHIVE_OK)
+		return (r);
+	return (add_entry(a, flag, entry));
+}
+
+/*
+ * Test function for time stamps.
+ *
+ * Returns 1 if archive entry is excluded.
+ * Returns 0 if archive entry is not excluded.
+ * Returns <0 if something error happened.
+ */
+int
+archive_match_time_excluded(struct archive *_a,
+    struct archive_entry *entry)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_time_excluded_ae");
+
+	a =3D (struct archive_match *)_a;
+	if (entry =3D=3D NULL) {
+		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* If we don't have inclusion time set at all, the entry is always
+	 * not excluded. */
+	if ((a->setflag & TIME_IS_SET) =3D=3D 0)
+		return (0);
+	return (time_excluded(a, entry));
+}
+
+static int
+validate_time_flag(struct archive *_a, int flag, const char *_fn)
+{
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, _fn);
+
+	/* Check a type of time. */
+	if (flag &
+	   ((~(ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) & 0xff00)) {
+		archive_set_error(_a, EINVAL, "Invalid time flag");
+		return (ARCHIVE_FAILED);
+	}
+	if ((flag & (ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) =3D=3D 0) {
+		archive_set_error(_a, EINVAL, "No time flag");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* Check a type of comparison. */
+	if (flag &
+	   ((~(ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
+			| ARCHIVE_MATCH_EQUAL)) & 0x00ff)) {
+		archive_set_error(_a, EINVAL, "Invalid comparison flag");
+		return (ARCHIVE_FAILED);
+	}
+	if ((flag & (ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
+	    | ARCHIVE_MATCH_EQUAL)) =3D=3D 0) {
+		archive_set_error(_a, EINVAL, "No comparison flag");
+		return (ARCHIVE_FAILED);
+	}
+
+	return (ARCHIVE_OK);
+}
+
+#define JUST_EQUAL(t) (((t) &  (ARCHIVE_MATCH_EQUAL |\
+	ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER)) =3D=3D ARCHIVE_MATCH_EQUAL)
+static int
+set_timefilter(struct archive_match *a, int timetype,
+    time_t mtime_sec, long mtime_nsec, time_t ctime_sec, long ctime_nsec)
+{
+	if (timetype & ARCHIVE_MATCH_MTIME) {
+		if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
+			a->newer_mtime_filter =3D timetype;
+			a->newer_mtime_sec =3D mtime_sec;
+			a->newer_mtime_nsec =3D mtime_nsec;
+			a->setflag |=3D TIME_IS_SET;
+		}
+		if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
+			a->older_mtime_filter =3D timetype;
+			a->older_mtime_sec =3D mtime_sec;
+			a->older_mtime_nsec =3D mtime_nsec;
+			a->setflag |=3D TIME_IS_SET;
+		}
+	}
+	if (timetype & ARCHIVE_MATCH_CTIME) {
+		if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
+			a->newer_ctime_filter =3D timetype;
+			a->newer_ctime_sec =3D ctime_sec;
+			a->newer_ctime_nsec =3D ctime_nsec;
+			a->setflag |=3D TIME_IS_SET;
+		}
+		if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
+			a->older_ctime_filter =3D timetype;
+			a->older_ctime_sec =3D ctime_sec;
+			a->older_ctime_nsec =3D ctime_nsec;
+			a->setflag |=3D TIME_IS_SET;
+		}
+	}
+	return (ARCHIVE_OK);
+}
+
+static int
+set_timefilter_date(struct archive_match *a, int timetype, const char *dat=
estr)
+{
+	time_t t;
+
+	if (datestr =3D=3D NULL || *datestr =3D=3D '\0') {
+		archive_set_error(&(a->archive), EINVAL, "date is empty");
+		return (ARCHIVE_FAILED);
+	}
+	t =3D get_date(a->now, datestr);
+	if (t =3D=3D (time_t)-1) {
+		archive_set_error(&(a->archive), EINVAL, "invalid date string");
+		return (ARCHIVE_FAILED);
+	}
+	return set_timefilter(a, timetype, t, 0, t, 0);
+}
+
+static int
+set_timefilter_date_w(struct archive_match *a, int timetype,
+    const wchar_t *datestr)
+{
+	struct archive_string as;
+	time_t t;
+
+	if (datestr =3D=3D NULL || *datestr =3D=3D L'\0') {
+		archive_set_error(&(a->archive), EINVAL, "date is empty");
+		return (ARCHIVE_FAILED);
+	}
+
+	archive_string_init(&as);
+	if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) {
+		archive_string_free(&as);
+		if (errno =3D=3D ENOMEM)
+			return (error_nomem(a));
+		archive_set_error(&(a->archive), -1,
+		    "Failed to convert WCS to MBS");
+		return (ARCHIVE_FAILED);
+	}
+	t =3D get_date(a->now, as.s);
+	archive_string_free(&as);
+	if (t =3D=3D (time_t)-1) {
+		archive_set_error(&(a->archive), EINVAL, "invalid date string");
+		return (ARCHIVE_FAILED);
+	}
+	return set_timefilter(a, timetype, t, 0, t, 0);
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static int
+set_timefilter_find_data(struct archive_match *a, int timetype,
+    DWORD ftLastWriteTime_dwHighDateTime, DWORD ftLastWriteTime_dwLowDateT=
ime,
+    DWORD ftCreationTime_dwHighDateTime, DWORD ftCreationTime_dwLowDateTim=
e)
+{
+	ULARGE_INTEGER utc;
+	time_t ctime_sec, mtime_sec;
+	long ctime_ns, mtime_ns;
+
+	utc.HighPart =3D ftCreationTime_dwHighDateTime;
+	utc.LowPart =3D ftCreationTime_dwLowDateTime;
+	if (utc.QuadPart >=3D EPOC_TIME) {
+		utc.QuadPart -=3D EPOC_TIME;
+		ctime_sec =3D (time_t)(utc.QuadPart / 10000000);
+		ctime_ns =3D (long)(utc.QuadPart % 10000000) * 100;
+	} else {
+		ctime_sec =3D 0;
+		ctime_ns =3D 0;
+	}
+	utc.HighPart =3D ftLastWriteTime_dwHighDateTime;
+	utc.LowPart =3D ftLastWriteTime_dwLowDateTime;
+	if (utc.QuadPart >=3D EPOC_TIME) {
+		utc.QuadPart -=3D EPOC_TIME;
+		mtime_sec =3D (time_t)(utc.QuadPart / 10000000);
+		mtime_ns =3D (long)(utc.QuadPart % 10000000) * 100;
+	} else {
+		mtime_sec =3D 0;
+		mtime_ns =3D 0;
+	}
+	return set_timefilter(a, timetype,
+			mtime_sec, mtime_ns, ctime_sec, ctime_ns);
+}
+
+static int
+set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
+    const char *path)
+{
+	/* NOTE: stat() on Windows cannot handle nano seconds. */
+	HANDLE h;
+	WIN32_FIND_DATA d;
+
+	if (path =3D=3D NULL || *path =3D=3D '\0') {
+		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+		return (ARCHIVE_FAILED);
+	}
+	h =3D FindFirstFileA(path, &d);
+	if (h =3D=3D INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		archive_set_error(&(a->archive), errno,
+		    "Failed to FindFirstFileA");
+		return (ARCHIVE_FAILED);
+	}
+	FindClose(h);
+	return set_timefilter_find_data(a, timetype,
+	    d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
+	    d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
+}
+
+static int
+set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
+    const wchar_t *path)
+{
+	HANDLE h;
+	WIN32_FIND_DATAW d;
+
+	if (path =3D=3D NULL || *path =3D=3D L'\0') {
+		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+		return (ARCHIVE_FAILED);
+	}
+	h =3D FindFirstFileW(path, &d);
+	if (h =3D=3D INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		archive_set_error(&(a->archive), errno,
+		    "Failed to FindFirstFile");
+		return (ARCHIVE_FAILED);
+	}
+	FindClose(h);
+	return set_timefilter_find_data(a, timetype,
+	    d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
+	    d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
+}
+
+#else /* _WIN32 && !__CYGWIN__ */
+
+static int
+set_timefilter_stat(struct archive_match *a, int timetype, struct stat *st)
+{
+	struct archive_entry *ae;
+	time_t ctime_sec, mtime_sec;
+	long ctime_ns, mtime_ns;
+
+	ae =3D archive_entry_new();
+	if (ae =3D=3D NULL)
+		return (error_nomem(a));
+	archive_entry_copy_stat(ae, st);
+	ctime_sec =3D archive_entry_ctime(ae);
+	ctime_ns =3D archive_entry_ctime_nsec(ae);
+	mtime_sec =3D archive_entry_mtime(ae);
+	mtime_ns =3D archive_entry_mtime_nsec(ae);
+	archive_entry_free(ae);
+	return set_timefilter(a, timetype, mtime_sec, mtime_ns,
+			ctime_sec, ctime_ns);
+}
+
+static int
+set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
+    const char *path)
+{
+	struct stat st;
+
+	if (path =3D=3D NULL || *path =3D=3D '\0') {
+		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+		return (ARCHIVE_FAILED);
+	}
+	if (stat(path, &st) !=3D 0) {
+		archive_set_error(&(a->archive), errno, "Failed to stat()");
+		return (ARCHIVE_FAILED);
+	}
+	return (set_timefilter_stat(a, timetype, &st));
+}
+
+static int
+set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
+    const wchar_t *path)
+{
+	struct archive_string as;
+	int r;
+
+	if (path =3D=3D NULL || *path =3D=3D L'\0') {
+		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* Convert WCS filename to MBS filename. */
+	archive_string_init(&as);
+	if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) {
+		archive_string_free(&as);
+		if (errno =3D=3D ENOMEM)
+			return (error_nomem(a));
+		archive_set_error(&(a->archive), -1,
+		    "Failed to convert WCS to MBS");
+		return (ARCHIVE_FAILED);
+	}
+
+	r =3D set_timefilter_pathname_mbs(a, timetype, as.s);
+	archive_string_free(&as);
+
+	return (r);
+}
+#endif /* _WIN32 && !__CYGWIN__ */
+
+/*
+ * Call back funtions for archive_rb.
+ */
+static int
+cmp_node_mbs(const struct archive_rb_node *n1,
+    const struct archive_rb_node *n2)
+{
+	struct match_file *f1 =3D (struct match_file *)(uintptr_t)n1;
+	struct match_file *f2 =3D (struct match_file *)(uintptr_t)n2;
+	const char *p1, *p2;
+
+	archive_mstring_get_mbs(NULL, &(f1->pathname), &p1);
+	archive_mstring_get_mbs(NULL, &(f2->pathname), &p2);
+	if (p1 =3D=3D NULL)
+		return (1);
+	if (p2 =3D=3D NULL)
+		return (-1);
+	return (strcmp(p1, p2));
+}
+       =20
+static int
+cmp_key_mbs(const struct archive_rb_node *n, const void *key)
+{
+	struct match_file *f =3D (struct match_file *)(uintptr_t)n;
+	const char *p;
+
+	archive_mstring_get_mbs(NULL, &(f->pathname), &p);
+	if (p =3D=3D NULL)
+		return (-1);
+	return (strcmp(p, (const char *)key));
+}
+
+static int
+cmp_node_wcs(const struct archive_rb_node *n1,
+    const struct archive_rb_node *n2)
+{
+	struct match_file *f1 =3D (struct match_file *)(uintptr_t)n1;
+	struct match_file *f2 =3D (struct match_file *)(uintptr_t)n2;
+	const wchar_t *p1, *p2;
+
+	archive_mstring_get_wcs(NULL, &(f1->pathname), &p1);
+	archive_mstring_get_wcs(NULL, &(f2->pathname), &p2);
+	if (p1 =3D=3D NULL)
+		return (1);
+	if (p2 =3D=3D NULL)
+		return (-1);
+	return (wcscmp(p1, p2));
+}
+       =20
+static int
+cmp_key_wcs(const struct archive_rb_node *n, const void *key)
+{
+	struct match_file *f =3D (struct match_file *)(uintptr_t)n;
+	const wchar_t *p;
+
+	archive_mstring_get_wcs(NULL, &(f->pathname), &p);
+	if (p =3D=3D NULL)
+		return (-1);
+	return (wcscmp(p, (const wchar_t *)key));
+}
+
+static void
+entry_list_init(struct entry_list *list)
+{
+	list->first =3D NULL;
+	list->last =3D &(list->first);
+	list->count =3D 0;
+}
+
+static void
+entry_list_free(struct entry_list *list)
+{
+	struct match_file *p, *q;
+
+	for (p =3D list->first; p !=3D NULL; ) {
+		q =3D p;
+		p =3D p->next;
+		archive_mstring_clean(&(q->pathname));
+		free(q);
+	}
+}
+
+static void
+entry_list_add(struct entry_list *list, struct match_file *file)
+{
+	*list->last =3D file;
+	list->last =3D &(file->next);
+	list->count++;
+}
+
+static int
+add_entry(struct archive_match *a, int flag,
+    struct archive_entry *entry)
+{
+	struct match_file *f;
+	const void *pathname;
+	int r;
+
+	f =3D calloc(1, sizeof(*f));
+	if (f =3D=3D NULL)
+		return (error_nomem(a));
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	pathname =3D archive_entry_pathname_w(entry);
+	if (pathname =3D=3D NULL) {
+		free(f);
+		archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
+		return (ARCHIVE_FAILED);
+	}
+	archive_mstring_copy_wcs(&(f->pathname), pathname);
+	a->exclusion_tree.rbt_ops =3D &rb_ops_wcs;
+#else
+	pathname =3D archive_entry_pathname(entry);
+	if (pathname =3D=3D NULL) {
+		free(f);
+		archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
+		return (ARCHIVE_FAILED);
+	}
+	archive_mstring_copy_mbs(&(f->pathname), pathname);
+	a->exclusion_tree.rbt_ops =3D &rb_ops_mbs;
+#endif
+	f->flag =3D flag;
+	f->mtime_sec =3D archive_entry_mtime(entry);
+	f->mtime_nsec =3D archive_entry_mtime_nsec(entry);
+	f->ctime_sec =3D archive_entry_ctime(entry);
+	f->ctime_nsec =3D archive_entry_ctime_nsec(entry);
+	r =3D __archive_rb_tree_insert_node(&(a->exclusion_tree), &(f->node));
+	if (!r) {
+		struct match_file *f2;
+
+		/* Get the duplicated file. */
+		f2 =3D (struct match_file *)__archive_rb_tree_find_node(
+			&(a->exclusion_tree), pathname);
+
+		/*
+		 * We always overwrite comparison condision.
+		 * If you do not want to overwrite it, you should not
+		 * call archive_match_exclude_entry(). We cannot know
+		 * what behavior you really expect since overwriting
+		 * condition might be different with the flag.
+		 */
+		if (f2 !=3D NULL) {
+			f2->flag =3D f->flag;
+			f2->mtime_sec =3D f->mtime_sec;
+			f2->mtime_nsec =3D f->mtime_nsec;
+			f2->ctime_sec =3D f->ctime_sec;
+			f2->ctime_nsec =3D f->ctime_nsec;
+		}
+		/* Release the duplicated file. */
+		archive_mstring_clean(&(f->pathname));
+		free(f);
+		return (ARCHIVE_OK);
+	}
+	entry_list_add(&(a->exclusion_entry_list), f);
+	a->setflag |=3D TIME_IS_SET;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Test if entry is excluded by its timestamp.
+ */
+static int
+time_excluded(struct archive_match *a, struct archive_entry *entry)
+{
+	struct match_file *f;
+	const void *pathname;
+	time_t sec;
+	long nsec;
+
+	/*
+	 * If this file/dir is excluded by a time comparison, skip it.
+	 */
+	if (a->newer_ctime_filter) {
+		/* If ctime is not set, use mtime instead. */
+		if (archive_entry_ctime_is_set(entry))
+			sec =3D archive_entry_ctime(entry);
+		else
+			sec =3D archive_entry_mtime(entry);
+		if (sec < a->newer_ctime_sec)
+			return (1); /* Too old, skip it. */
+		if (sec =3D=3D a->newer_ctime_sec) {
+			if (archive_entry_ctime_is_set(entry))
+				nsec =3D archive_entry_ctime_nsec(entry);
+			else
+				nsec =3D archive_entry_mtime_nsec(entry);
+			if (nsec < a->newer_ctime_nsec)
+				return (1); /* Too old, skip it. */
+			if (nsec =3D=3D a->newer_ctime_nsec &&
+			    (a->newer_ctime_filter & ARCHIVE_MATCH_EQUAL)
+			      =3D=3D 0)
+				return (1); /* Equal, skip it. */
+		}
+	}
+	if (a->older_ctime_filter) {
+		/* If ctime is not set, use mtime instead. */
+		if (archive_entry_ctime_is_set(entry))
+			sec =3D archive_entry_ctime(entry);
+		else
+			sec =3D archive_entry_mtime(entry);
+		if (sec > a->older_ctime_sec)
+			return (1); /* Too new, skip it. */
+		if (sec =3D=3D a->older_ctime_sec) {
+			if (archive_entry_ctime_is_set(entry))
+				nsec =3D archive_entry_ctime_nsec(entry);
+			else
+				nsec =3D archive_entry_mtime_nsec(entry);
+			if (nsec > a->older_ctime_nsec)
+				return (1); /* Too new, skip it. */
+			if (nsec =3D=3D a->older_ctime_nsec &&
+			    (a->older_ctime_filter & ARCHIVE_MATCH_EQUAL)
+			      =3D=3D 0)
+				return (1); /* Eeual, skip it. */
+		}
+	}
+	if (a->newer_mtime_filter) {
+		sec =3D archive_entry_mtime(entry);
+		if (sec < a->newer_mtime_sec)
+			return (1); /* Too old, skip it. */
+		if (sec =3D=3D a->newer_mtime_sec) {
+			nsec =3D archive_entry_mtime_nsec(entry);
+			if (nsec < a->newer_mtime_nsec)
+				return (1); /* Too old, skip it. */
+			if (nsec =3D=3D a->newer_mtime_nsec &&
+			    (a->newer_mtime_filter & ARCHIVE_MATCH_EQUAL)
+			       =3D=3D 0)
+				return (1); /* Equal, skip it. */
+		}
+	}
+	if (a->older_mtime_filter) {
+		sec =3D archive_entry_mtime(entry);
+		if (sec > a->older_mtime_sec)
+			return (1); /* Too new, skip it. */
+		nsec =3D archive_entry_mtime_nsec(entry);
+		if (sec =3D=3D a->older_mtime_sec) {
+			if (nsec > a->older_mtime_nsec)
+				return (1); /* Too new, skip it. */
+			if (nsec =3D=3D a->older_mtime_nsec &&
+			    (a->older_mtime_filter & ARCHIVE_MATCH_EQUAL)
+			       =3D=3D 0)
+				return (1); /* Equal, skip it. */
+		}
+	}
+
+	/* If there is no excluson list, include the file. */
+	if (a->exclusion_entry_list.count =3D=3D 0)
+		return (0);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	pathname =3D archive_entry_pathname_w(entry);
+	a->exclusion_tree.rbt_ops =3D &rb_ops_wcs;
+#else
+	pathname =3D archive_entry_pathname(entry);
+	a->exclusion_tree.rbt_ops =3D &rb_ops_mbs;
+#endif
+	if (pathname =3D=3D NULL)
+		return (0);
+
+	f =3D (struct match_file *)__archive_rb_tree_find_node(
+		&(a->exclusion_tree), pathname);
+	/* If the file wasn't rejected, include it. */
+	if (f =3D=3D NULL)
+		return (0);
+
+	if (f->flag & ARCHIVE_MATCH_CTIME) {
+		sec =3D archive_entry_ctime(entry);
+		if (f->ctime_sec > sec) {
+			if (f->flag & ARCHIVE_MATCH_OLDER)
+				return (1);
+		} else if (f->ctime_sec < sec) {
+			if (f->flag & ARCHIVE_MATCH_NEWER)
+				return (1);
+		} else {
+			nsec =3D archive_entry_ctime_nsec(entry);
+			if (f->ctime_nsec > nsec) {
+				if (f->flag & ARCHIVE_MATCH_OLDER)
+					return (1);
+			} else if (f->ctime_nsec < nsec) {
+				if (f->flag & ARCHIVE_MATCH_NEWER)
+					return (1);
+			} else if (f->flag & ARCHIVE_MATCH_EQUAL)
+				return (1);
+		}
+	}
+	if (f->flag & ARCHIVE_MATCH_MTIME) {
+		sec =3D archive_entry_mtime(entry);
+		if (f->mtime_sec > sec) {
+			if (f->flag & ARCHIVE_MATCH_OLDER)
+				return (1);
+		} else if (f->mtime_sec < sec) {
+			if (f->flag & ARCHIVE_MATCH_NEWER)
+				return (1);
+		} else {
+			nsec =3D archive_entry_mtime_nsec(entry);
+			if (f->mtime_nsec > nsec) {
+				if (f->flag & ARCHIVE_MATCH_OLDER)
+					return (1);
+			} else if (f->mtime_nsec < nsec) {
+				if (f->flag & ARCHIVE_MATCH_NEWER)
+					return (1);
+			} else if (f->flag & ARCHIVE_MATCH_EQUAL)
+				return (1);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Utility functions to manage inclusion owners
+ */
+
+int
+archive_match_include_uid(struct archive *_a, int64_t uid)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_uid");
+	a =3D (struct archive_match *)_a;
+	return (add_owner_id(a, &(a->inclusion_uids), uid));
+}
+
+int
+archive_match_include_gid(struct archive *_a, int64_t gid)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_gid");
+	a =3D (struct archive_match *)_a;
+	return (add_owner_id(a, &(a->inclusion_gids), gid));
+}
+
+int
+archive_match_include_uname(struct archive *_a, const char *uname)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_uname");
+	a =3D (struct archive_match *)_a;
+	return (add_owner_name(a, &(a->inclusion_unames), 1, uname));
+}
+
+int
+archive_match_include_uname_w(struct archive *_a, const wchar_t *uname)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_uname_w");
+	a =3D (struct archive_match *)_a;
+	return (add_owner_name(a, &(a->inclusion_unames), 0, uname));
+}
+
+int
+archive_match_include_gname(struct archive *_a, const char *gname)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_gname");
+	a =3D (struct archive_match *)_a;
+	return (add_owner_name(a, &(a->inclusion_gnames), 1, gname));
+}
+
+int
+archive_match_include_gname_w(struct archive *_a, const wchar_t *gname)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_include_gname_w");
+	a =3D (struct archive_match *)_a;
+	return (add_owner_name(a, &(a->inclusion_gnames), 0, gname));
+}
+
+/*
+ * Test function for owner(uid, gid, uname, gname).
+ *
+ * Returns 1 if archive entry is excluded.
+ * Returns 0 if archive entry is not excluded.
+ * Returns <0 if something error happened.
+ */
+int
+archive_match_owner_excluded(struct archive *_a,
+    struct archive_entry *entry)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_id_excluded_ae");
+
+	a =3D (struct archive_match *)_a;
+	if (entry =3D=3D NULL) {
+		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* If we don't have inclusion id set at all, the entry is always
+	 * not excluded. */
+	if ((a->setflag & ID_IS_SET) =3D=3D 0)
+		return (0);
+	return (owner_excluded(a, entry));
+}
+
+static int
+add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
+{
+	unsigned i;
+
+	if (ids->count + 1 >=3D ids->size) {
+		if (ids->size =3D=3D 0)
+			ids->size =3D 8;
+		else
+			ids->size *=3D 2;
+		ids->ids =3D realloc(ids->ids, sizeof(*ids->ids) * ids->size);
+		if (ids->ids =3D=3D NULL)
+			return (error_nomem(a));
+	}
+
+	/* Find an insert point. */
+	for (i =3D 0; i < ids->count; i++) {
+		if (ids->ids[i] >=3D id)
+			break;
+	}
+
+	/* Add oowner id. */
+	if (i =3D=3D ids->count)
+		ids->ids[ids->count++] =3D id;
+	else if (ids->ids[i] !=3D id) {
+		memmove(&(ids->ids[i+1]), &(ids->ids[i]),
+		    (ids->count - i) * sizeof(ids->ids[0]));
+		ids->ids[i] =3D id;
+		ids->count++;
+	}
+	a->setflag |=3D ID_IS_SET;
+	return (ARCHIVE_OK);
+}
+
+static int
+match_owner_id(struct id_array *ids, int64_t id)
+{
+	unsigned b, m, t;
+
+	t =3D 0;
+	b =3D ids->count;
+	while (t < b) {
+		m =3D (t + b)>>1;
+		if (ids->ids[m] =3D=3D id)
+			return (1);
+		if (ids->ids[m] < id)
+			t =3D m + 1;
+		else
+			b =3D m;
+	}
+	return (0);
+}
+
+static int
+add_owner_name(struct archive_match *a, struct match_list *list,
+    int mbs, const void *name)
+{
+	struct match *match;
+
+	match =3D calloc(1, sizeof(*match));
+	if (match =3D=3D NULL)
+		return (error_nomem(a));
+	if (mbs)
+		archive_mstring_copy_mbs(&(match->pattern), name);
+	else
+		archive_mstring_copy_wcs(&(match->pattern), name);
+	match_list_add(list, match);
+	a->setflag |=3D ID_IS_SET;
+	return (ARCHIVE_OK);
+}
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static int
+match_owner_name_mbs(struct archive_match *a, struct match_list *list,
+    const char *name)
+{
+	struct match *m;
+	const char *p;
+
+	if (name =3D=3D NULL || *name =3D=3D '\0')
+		return (0);
+	for (m =3D list->first; m; m =3D m->next) {
+		if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p)
+		    < 0 && errno =3D=3D ENOMEM)
+			return (error_nomem(a));
+		if (p !=3D NULL && strcmp(p, name) =3D=3D 0) {
+			m->matches++;
+			return (1);
+		}
+	}
+	return (0);
+}
+#else
+static int
+match_owner_name_wcs(struct archive_match *a, struct match_list *list,
+    const wchar_t *name)
+{
+	struct match *m;
+	const wchar_t *p;
+
+	if (name =3D=3D NULL || *name =3D=3D L'\0')
+		return (0);
+	for (m =3D list->first; m; m =3D m->next) {
+		if (archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p)
+		    < 0 && errno =3D=3D ENOMEM)
+			return (error_nomem(a));
+		if (p !=3D NULL && wcscmp(p, name) =3D=3D 0) {
+			m->matches++;
+			return (1);
+		}
+	}
+	return (0);
+}
+#endif
+
+/*
+ * Test if entry is excluded by uid, gid, uname or gname.
+ */
+static int
+owner_excluded(struct archive_match *a, struct archive_entry *entry)
+{
+	int r;
+
+	if (a->inclusion_uids.count) {
+		if (!match_owner_id(&(a->inclusion_uids),
+		    archive_entry_uid(entry)))
+			return (1);
+	}
+
+	if (a->inclusion_gids.count) {
+		if (!match_owner_id(&(a->inclusion_gids),
+		    archive_entry_gid(entry)))
+			return (1);
+	}
+
+	if (a->inclusion_unames.count) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+		r =3D match_owner_name_wcs(a, &(a->inclusion_unames),
+			archive_entry_uname_w(entry));
+#else
+		r =3D match_owner_name_mbs(a, &(a->inclusion_unames),
+			archive_entry_uname(entry));
+#endif
+		if (!r)
+			return (1);
+		else if (r < 0)
+			return (r);
+	}
+
+	if (a->inclusion_gnames.count) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+		r =3D match_owner_name_wcs(a, &(a->inclusion_gnames),
+			archive_entry_gname_w(entry));
+#else
+		r =3D match_owner_name_mbs(a, &(a->inclusion_gnames),
+			archive_entry_gname(entry));
+#endif
+		if (!r)
+			return (1);
+		else if (r < 0)
+			return (r);
+	}
+	return (0);
+}
+
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_pathmatch.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/archive_pathmatch.c	Fri Aug 10 14:=
19:25 2012 +0300
@@ -0,0 +1,459 @@
+/*-
+ * 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
+ *    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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#include "archive_pathmatch.h"
+
+/*
+ * Check whether a character 'c' is matched by a list specification [...]:
+ *    * Leading '!' or '^' negates the class.
+ *    * <char>-<char> is a range of characters
+ *    * \<char> removes any special meaning for <char>
+ *
+ * Some interesting boundary cases:
+ *   a-d-e is one range (a-d) followed by two single characters - and e.
+ *   \a-\d is same as a-d
+ *   a\-d is three single characters: a, d, -
+ *   Trailing - is not special (so [a-] is two characters a and -).
+ *   Initial - is not special ([a-] is same as [-a] is same as [\\-a])
+ *   This function never sees a trailing \.
+ *   [] always fails
+ *   [!] always succeeds
+ */
+static int
+pm_list(const char *start, const char *end, const char c, int flags)
+{
+	const char *p =3D start;
+	char rangeStart =3D '\0', nextRangeStart;
+	int match =3D 1, nomatch =3D 0;
+
+	/* This will be used soon... */
+	(void)flags; /* UNUSED */
+
+	/* If this is a negated class, return success for nomatch. */
+	if ((*p =3D=3D '!' || *p =3D=3D '^') && p < end) {
+		match =3D 0;
+		nomatch =3D 1;
+		++p;
+	}
+
+	while (p < end) {
+		nextRangeStart =3D '\0';
+		switch (*p) {
+		case '-':
+			/* Trailing or initial '-' is not special. */
+			if ((rangeStart =3D=3D '\0') || (p =3D=3D end - 1)) {
+				if (*p =3D=3D c)
+					return (match);
+			} else {
+				char rangeEnd =3D *++p;
+				if (rangeEnd =3D=3D '\\')
+					rangeEnd =3D *++p;
+				if ((rangeStart <=3D c) && (c <=3D rangeEnd))
+					return (match);
+			}
+			break;
+		case '\\':
+			++p;
+			/* Fall through */
+		default:
+			if (*p =3D=3D c)
+				return (match);
+			nextRangeStart =3D *p; /* Possible start of range. */
+		}
+		rangeStart =3D nextRangeStart;
+		++p;
+	}
+	return (nomatch);
+}
+
+static int
+pm_list_w(const wchar_t *start, const wchar_t *end, const wchar_t c, int f=
lags)
+{
+	const wchar_t *p =3D start;
+	wchar_t rangeStart =3D L'\0', nextRangeStart;
+	int match =3D 1, nomatch =3D 0;
+
+	/* This will be used soon... */
+	(void)flags; /* UNUSED */
+
+	/* If this is a negated class, return success for nomatch. */
+	if ((*p =3D=3D L'!' || *p =3D=3D L'^') && p < end) {
+		match =3D 0;
+		nomatch =3D 1;
+		++p;
+	}
+
+	while (p < end) {
+		nextRangeStart =3D L'\0';
+		switch (*p) {
+		case L'-':
+			/* Trailing or initial '-' is not special. */
+			if ((rangeStart =3D=3D L'\0') || (p =3D=3D end - 1)) {
+				if (*p =3D=3D c)
+					return (match);
+			} else {
+				wchar_t rangeEnd =3D *++p;
+				if (rangeEnd =3D=3D L'\\')
+					rangeEnd =3D *++p;
+				if ((rangeStart <=3D c) && (c <=3D rangeEnd))
+					return (match);
+			}
+			break;
+		case L'\\':
+			++p;
+			/* Fall through */
+		default:
+			if (*p =3D=3D c)
+				return (match);
+			nextRangeStart =3D *p; /* Possible start of range. */
+		}
+		rangeStart =3D nextRangeStart;
+		++p;
+	}
+	return (nomatch);
+}
+
+/*
+ * If s is pointing to "./", ".//", "./././" or the like, skip it.
+ */
+static const char *
+pm_slashskip(const char *s) {
+	while ((*s =3D=3D '/')
+	    || (s[0] =3D=3D '.' && s[1] =3D=3D '/')
+	    || (s[0] =3D=3D '.' && s[1] =3D=3D '\0'))
+		++s;
+	return (s);
+}
+
+static const wchar_t *
+pm_slashskip_w(const wchar_t *s) {
+	while ((*s =3D=3D L'/')
+	    || (s[0] =3D=3D L'.' && s[1] =3D=3D L'/')
+	    || (s[0] =3D=3D L'.' && s[1] =3D=3D L'\0'))
+		++s;
+	return (s);
+}
+
+static int
+pm(const char *p, const char *s, int flags)
+{
+	const char *end;
+
+	/*
+	 * Ignore leading './', './/', '././', etc.
+	 */
+	if (s[0] =3D=3D '.' && s[1] =3D=3D '/')
+		s =3D pm_slashskip(s + 1);
+	if (p[0] =3D=3D '.' && p[1] =3D=3D '/')
+		p =3D pm_slashskip(p + 1);
+
+	for (;;) {
+		switch (*p) {
+		case '\0':
+			if (s[0] =3D=3D '/') {
+				if (flags & PATHMATCH_NO_ANCHOR_END)
+					return (1);
+				/* "dir" =3D=3D "dir/" =3D=3D "dir/." */
+				s =3D pm_slashskip(s);
+			}
+			return (*s =3D=3D '\0');
+		case '?':
+			/* ? always succeeds, unless we hit end of 's' */
+			if (*s =3D=3D '\0')
+				return (0);
+			break;
+		case '*':
+			/* "*" =3D=3D "**" =3D=3D "***" ... */
+			while (*p =3D=3D '*')
+				++p;
+			/* Trailing '*' always succeeds. */
+			if (*p =3D=3D '\0')
+				return (1);
+			while (*s) {
+				if (archive_pathmatch(p, s, flags))
+					return (1);
+				++s;
+			}
+			return (0);
+		case '[':
+			/*
+			 * Find the end of the [...] character class,
+			 * ignoring \] that might occur within the class.
+			 */
+			end =3D p + 1;
+			while (*end !=3D '\0' && *end !=3D ']') {
+				if (*end =3D=3D '\\' && end[1] !=3D '\0')
+					++end;
+				++end;
+			}
+			if (*end =3D=3D ']') {
+				/* We found [...], try to match it. */
+				if (!pm_list(p + 1, end, *s, flags))
+					return (0);
+				p =3D end; /* Jump to trailing ']' char. */
+				break;
+			} else
+				/* No final ']', so just match '['. */
+				if (*p !=3D *s)
+					return (0);
+			break;
+		case '\\':
+			/* Trailing '\\' matches itself. */
+			if (p[1] =3D=3D '\0') {
+				if (*s !=3D '\\')
+					return (0);
+			} else {
+				++p;
+				if (*p !=3D *s)
+					return (0);
+			}
+			break;
+		case '/':
+			if (*s !=3D '/' && *s !=3D '\0')
+				return (0);
+			/* Note: pattern "/\./" won't match "/";
+			 * pm_slashskip() correctly stops at backslash. */
+			p =3D pm_slashskip(p);
+			s =3D pm_slashskip(s);
+			if (*p =3D=3D '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
+				return (1);
+			--p; /* Counteract the increment below. */
+			--s;
+			break;
+		case '$':
+			/* '$' is special only at end of pattern and only
+			 * if PATHMATCH_NO_ANCHOR_END is specified. */
+			if (p[1] =3D=3D '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
+				/* "dir" =3D=3D "dir/" =3D=3D "dir/." */
+				return (*pm_slashskip(s) =3D=3D '\0');
+			}
+			/* Otherwise, '$' is not special. */
+			/* FALL THROUGH */
+		default:
+			if (*p !=3D *s)
+				return (0);
+			break;
+		}
+		++p;
+		++s;
+	}
+}
+
+static int
+pm_w(const wchar_t *p, const wchar_t *s, int flags)
+{
+	const wchar_t *end;
+
+	/*
+	 * Ignore leading './', './/', '././', etc.
+	 */
+	if (s[0] =3D=3D L'.' && s[1] =3D=3D L'/')
+		s =3D pm_slashskip_w(s + 1);
+	if (p[0] =3D=3D L'.' && p[1] =3D=3D L'/')
+		p =3D pm_slashskip_w(p + 1);
+
+	for (;;) {
+		switch (*p) {
+		case L'\0':
+			if (s[0] =3D=3D L'/') {
+				if (flags & PATHMATCH_NO_ANCHOR_END)
+					return (1);
+				/* "dir" =3D=3D "dir/" =3D=3D "dir/." */
+				s =3D pm_slashskip_w(s);
+			}
+			return (*s =3D=3D L'\0');
+		case L'?':
+			/* ? always succeeds, unless we hit end of 's' */
+			if (*s =3D=3D L'\0')
+				return (0);
+			break;
+		case L'*':
+			/* "*" =3D=3D "**" =3D=3D "***" ... */
+			while (*p =3D=3D L'*')
+				++p;
+			/* Trailing '*' always succeeds. */
+			if (*p =3D=3D L'\0')
+				return (1);
+			while (*s) {
+				if (archive_pathmatch_w(p, s, flags))
+					return (1);
+				++s;
+			}
+			return (0);
+		case L'[':
+			/*
+			 * Find the end of the [...] character class,
+			 * ignoring \] that might occur within the class.
+			 */
+			end =3D p + 1;
+			while (*end !=3D L'\0' && *end !=3D L']') {
+				if (*end =3D=3D L'\\' && end[1] !=3D L'\0')
+					++end;
+				++end;
+			}
+			if (*end =3D=3D L']') {
+				/* We found [...], try to match it. */
+				if (!pm_list_w(p + 1, end, *s, flags))
+					return (0);
+				p =3D end; /* Jump to trailing ']' char. */
+				break;
+			} else
+				/* No final ']', so just match '['. */
+				if (*p !=3D *s)
+					return (0);
+			break;
+		case L'\\':
+			/* Trailing '\\' matches itself. */
+			if (p[1] =3D=3D L'\0') {
+				if (*s !=3D L'\\')
+					return (0);
+			} else {
+				++p;
+				if (*p !=3D *s)
+					return (0);
+			}
+			break;
+		case L'/':
+			if (*s !=3D L'/' && *s !=3D L'\0')
+				return (0);
+			/* Note: pattern "/\./" won't match "/";
+			 * pm_slashskip() correctly stops at backslash. */
+			p =3D pm_slashskip_w(p);
+			s =3D pm_slashskip_w(s);
+			if (*p =3D=3D L'\0' && (flags & PATHMATCH_NO_ANCHOR_END))
+				return (1);
+			--p; /* Counteract the increment below. */
+			--s;
+			break;
+		case L'$':
+			/* '$' is special only at end of pattern and only
+			 * if PATHMATCH_NO_ANCHOR_END is specified. */
+			if (p[1] =3D=3D L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
+				/* "dir" =3D=3D "dir/" =3D=3D "dir/." */
+				return (*pm_slashskip_w(s) =3D=3D L'\0');
+			}
+			/* Otherwise, '$' is not special. */
+			/* FALL THROUGH */
+		default:
+			if (*p !=3D *s)
+				return (0);
+			break;
+		}
+		++p;
+		++s;
+	}
+}
+
+/* Main entry point. */
+int
+__archive_pathmatch(const char *p, const char *s, int flags)
+{
+	/* Empty pattern only matches the empty string. */
+	if (p =3D=3D NULL || *p =3D=3D '\0')
+		return (s =3D=3D NULL || *s =3D=3D '\0');
+
+	/* Leading '^' anchors the start of the pattern. */
+	if (*p =3D=3D '^') {
+		++p;
+		flags &=3D ~PATHMATCH_NO_ANCHOR_START;
+	}
+
+	if (*p =3D=3D '/' && *s !=3D '/')
+		return (0);
+
+	/* Certain patterns and file names anchor implicitly. */
+	if (*p =3D=3D '*' || *p =3D=3D '/' || *p =3D=3D '/') {
+		while (*p =3D=3D '/')
+			++p;
+		while (*s =3D=3D '/')
+			++s;
+		return (pm(p, s, flags));
+	}
+
+	/* If start is unanchored, try to match start of each path element. */
+	if (flags & PATHMATCH_NO_ANCHOR_START) {
+		for ( ; s !=3D NULL; s =3D strchr(s, '/')) {
+			if (*s =3D=3D '/')
+				s++;
+			if (pm(p, s, flags))
+				return (1);
+		}
+		return (0);
+	}
+
+	/* Default: Match from beginning. */
+	return (pm(p, s, flags));
+}
+
+int
+__archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
+{
+	/* Empty pattern only matches the empty string. */
+	if (p =3D=3D NULL || *p =3D=3D L'\0')
+		return (s =3D=3D NULL || *s =3D=3D L'\0');
+
+	/* Leading '^' anchors the start of the pattern. */
+	if (*p =3D=3D L'^') {
+		++p;
+		flags &=3D ~PATHMATCH_NO_ANCHOR_START;
+	}
+
+	if (*p =3D=3D L'/' && *s !=3D L'/')
+		return (0);
+
+	/* Certain patterns and file names anchor implicitly. */
+	if (*p =3D=3D L'*' || *p =3D=3D L'/' || *p =3D=3D L'/') {
+		while (*p =3D=3D L'/')
+			++p;
+		while (*s =3D=3D L'/')
+			++s;
+		return (pm_w(p, s, flags));
+	}
+
+	/* If start is unanchored, try to match start of each path element. */
+	if (flags & PATHMATCH_NO_ANCHOR_START) {
+		for ( ; s !=3D NULL; s =3D wcschr(s, L'/')) {
+			if (*s =3D=3D L'/')
+				s++;
+			if (pm_w(p, s, flags))
+				return (1);
+		}
+		return (0);
+	}
+
+	/* Default: Match from beginning. */
+	return (pm_w(p, s, flags));
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_pathmatch.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/archive_pathmatch.h	Fri Aug 10 14:=
19:25 2012 +0300
@@ -0,0 +1,52 @@
+/*-
+ * 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
+ *    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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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
+#ifndef __LIBARCHIVE_TEST
+#error This header is only to be used internally to libarchive.
+#endif
+#endif
+
+#ifndef ARCHIVE_PATHMATCH_H
+#define ARCHIVE_PATHMATCH_H
+
+/* Don't anchor at beginning unless the pattern starts with "^" */
+#define PATHMATCH_NO_ANCHOR_START	1
+/* Don't anchor at end unless the pattern ends with "$" */
+#define PATHMATCH_NO_ANCHOR_END 	2
+
+/* Note that "^" and "$" are not special unless you set the corresponding
+ * flag above. */
+
+int __archive_pathmatch(const char *p, const char *s, int flags);
+int __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags);
+
+#define archive_pathmatch(p, s, f)	__archive_pathmatch(p, s, f)
+#define archive_pathmatch_w(p, s, f)	__archive_pathmatch_w(p, s, f)
+
+#endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_ppmd7.c
--- a/head/contrib/libarchive/libarchive/archive_ppmd7.c	Mon Jul 30 11:44:1=
8 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_ppmd7.c	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -415,7 +415,7 @@
     upState.Freq =3D (Byte)(1 + ((2 * cf <=3D s0) ? (5 * cf > s0) : ((2 * =
cf + 3 * s0 - 1) / (2 * s0))));
   }
=20
-  do
+  while (numPs !=3D 0)
   {
     /* Create Child */
     CTX_PTR c1; /* =3D AllocContext(p); */
@@ -435,7 +435,6 @@
     SetSuccessor(ps[--numPs], REF(c1));
     c =3D c1;
   }
-  while (numPs !=3D 0);
  =20
   return c;
 }
@@ -778,7 +777,7 @@
       if(p->Range >=3D p->Bottom)
         break;
       else
-        p->Range =3D -p->Low & (p->Bottom - 1);
+        p->Range =3D ((uint32_t)(-(int32_t)p->Low)) & (p->Bottom - 1);
     }
     p->Code =3D (p->Code << 8) | p->Stream->Read((void *)p->Stream);
     p->Range <<=3D 8;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_private.h
--- a/head/contrib/libarchive/libarchive/archive_private.h	Mon Jul 30 11:44=
:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_private.h	Fri Aug 10 14:19=
:25 2012 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive/archive_private.h 232153 2=
012-02-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_private.h 238856 2=
012-07-28 06:38:44Z mm $
  */
=20
 #ifndef __LIBARCHIVE_BUILD
@@ -50,6 +50,7 @@
 #define	ARCHIVE_READ_MAGIC	(0xdeb0c5U)
 #define	ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
 #define	ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
+#define	ARCHIVE_MATCH_MAGIC	(0xcad11c9U)
=20
 #define	ARCHIVE_STATE_NEW	1U
 #define	ARCHIVE_STATE_HEADER	2U
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read.3
--- a/head/contrib/libarchive/libarchive/archive_read.3	Mon Jul 30 11:44:18=
 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read.3	Fri Aug 10 14:19:25=
 2012 +0300
@@ -22,14 +22,16 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_read.3 232153 201=
2-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_read.3 238856 201=
2-07-28 06:38:44Z mm $
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ 3
 .Os
 .Sh NAME
 .Nm archive_read
 .Nd functions for reading streaming archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Sh DESCRIPTION
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read.c
--- a/head/contrib/libarchive/libarchive/archive_read.c	Mon Jul 30 11:44:18=
 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read.c	Fri Aug 10 14:19:25=
 2012 +0300
@@ -32,7 +32,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read.c 2321=
53 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read.c 2388=
56 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -201,7 +201,6 @@
 			request -=3D get;
 			total +=3D get;
 		}
-		return total;
 	} else if (self->archive->client.seeker !=3D NULL
 		&& request > 64 * 1024) {
 		/* If the client provided a seeker but not a skipper,
@@ -638,8 +637,8 @@
 			len =3D s;
 		} else if (a->read_data_output_offset <
 		    a->read_data_offset) {
-			len =3D a->read_data_offset -
-			    a->read_data_output_offset;
+			len =3D (size_t)(a->read_data_offset -
+			    a->read_data_output_offset);
 		} else
 			len =3D 0;
=20
@@ -1231,7 +1230,7 @@
=20
 	/* Use up the copy buffer first. */
 	if (filter->avail > 0) {
-		min =3D minimum(request, (int64_t)filter->avail);
+		min =3D (size_t)minimum(request, (int64_t)filter->avail);
 		filter->next +=3D min;
 		filter->avail -=3D min;
 		request -=3D min;
@@ -1241,7 +1240,7 @@
=20
 	/* Then use up the client buffer. */
 	if (filter->client_avail > 0) {
-		min =3D minimum(request, (int64_t)filter->client_avail);
+		min =3D (size_t)minimum(request, (int64_t)filter->client_avail);
 		filter->client_next +=3D min;
 		filter->client_avail -=3D min;
 		request -=3D min;
@@ -1283,7 +1282,7 @@
 		if (bytes_read >=3D request) {
 			filter->client_next =3D
 			    ((const char *)filter->client_buff) + request;
-			filter->client_avail =3D bytes_read - request;
+			filter->client_avail =3D (size_t)(bytes_read - request);
 			filter->client_total =3D bytes_read;
 			total_bytes_skipped +=3D request;
 			filter->position +=3D request;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_data.3
--- a/head/contrib/libarchive/libarchive/archive_read_data.3	Mon Jul 30 11:=
44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_data.3	Fri Aug 10 14:=
19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 22, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_DATA 3
 .Os
 .Sh NAME
@@ -33,6 +33,8 @@
 .Nm archive_read_data_skip ,
 .Nm archive_read_data_into_fd
 .Nd functions for reading streaming archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft ssize_t
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_disk.3
--- a/head/contrib/libarchive/libarchive/archive_read_disk.3	Mon Jul 30 11:=
44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_disk.3	Fri Aug 10 14:=
19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_read_disk.3 23215=
3 2012-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_read_disk.3 23885=
6 2012-07-28 06:38:44Z mm $
 .\"
-.Dd March 10, 2009
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_DISK 3
 .Os
 .Sh NAME
@@ -42,6 +42,8 @@
 .Nm archive_read_finish ,
 .Nm archive_read_free
 .Nd functions for reading objects from disk
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft struct archive *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_disk_entry_from_file.c
--- a/head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.=
c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.=
c	Fri Aug 10 14:19:25 2012 +0300
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2003-2009 Tim Kientzle
- * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_disk_e=
ntry_from_file.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_disk_e=
ntry_from_file.c 238909 2012-07-30 14:47:35Z mm $");
=20
 /* This is the tree-walking code for POSIX systems. */
 #if !defined(_WIN32) || defined(__CYGWIN__)
@@ -73,6 +73,9 @@
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
+#ifdef HAVE_LINUX_TYPES_H
+#include <linux/types.h>
+#endif
 #ifdef HAVE_LINUX_FIEMAP_H
 #include <linux/fiemap.h>
 #endif
@@ -111,14 +114,14 @@
 #define	ACL_GET_PERM acl_get_perm_np
 #endif
=20
-static int setup_acls_posix1e(struct archive_read_disk *,
-    struct archive_entry *, int fd);
+static int setup_acls(struct archive_read_disk *,
+    struct archive_entry *, int *fd);
 static int setup_mac_metadata(struct archive_read_disk *,
-    struct archive_entry *, int fd);
+    struct archive_entry *, int *fd);
 static int setup_xattrs(struct archive_read_disk *,
-    struct archive_entry *, int fd);
+    struct archive_entry *, int *fd);
 static int setup_sparse(struct archive_read_disk *,
-    struct archive_entry *, int fd);
+    struct archive_entry *, int *fd);
=20
 int
 archive_read_disk_entry_from_file(struct archive *_a,
@@ -187,8 +190,13 @@
 	 * 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 =3D open(path, O_RDONLY | O_NONBLOCK);
+		if (fd < 0) {
+			if (a->tree !=3D NULL)
+				fd =3D a->open_on_current_dir(a->tree, path,
+					O_RDONLY | O_NONBLOCK);
+			else
+				fd =3D open(path, O_RDONLY | O_NONBLOCK);
+		}
 		if (fd >=3D 0) {
 			unsigned long stflags;
 			r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
@@ -210,13 +218,21 @@
 			    "Couldn't read link data");
 			return (ARCHIVE_FAILED);
 		}
+		if (a->tree !=3D NULL) {
 #ifdef HAVE_READLINKAT
-		if (a->entry_wd_fd >=3D 0)
-			lnklen =3D readlinkat(a->entry_wd_fd, path,
-			    linkbuffer, linkbuffer_len);
-		else
+			lnklen =3D readlinkat(a->tree_current_dir_fd(a->tree),
+			    path, linkbuffer, linkbuffer_len);
+#else
+			if (a->tree_enter_working_dir(a->tree) !=3D 0) {
+				archive_set_error(&a->archive, errno,
+				    "Couldn't read link data");
+				free(linkbuffer);
+				return (ARCHIVE_FAILED);
+			}
+			lnklen =3D readlink(path, linkbuffer, linkbuffer_len);
 #endif /* HAVE_READLINKAT */
-		lnklen =3D readlink(path, linkbuffer, linkbuffer_len);
+		} else
+			lnklen =3D readlink(path, linkbuffer, linkbuffer_len);
 		if (lnklen < 0) {
 			archive_set_error(&a->archive, errno,
 			    "Couldn't read link data");
@@ -229,14 +245,16 @@
 	}
 #endif /* HAVE_READLINK || HAVE_READLINKAT */
=20
-	r =3D setup_acls_posix1e(a, entry, fd);
-	r1 =3D setup_xattrs(a, entry, fd);
+	r =3D setup_acls(a, entry, &fd);
+	r1 =3D setup_xattrs(a, entry, &fd);
 	if (r1 < r)
 		r =3D r1;
-	r1 =3D setup_mac_metadata(a, entry, fd);
-	if (r1 < r)
-		r =3D r1;
-	r1 =3D setup_sparse(a, entry, fd);
+	if (a->enable_copyfile) {
+		r1 =3D setup_mac_metadata(a, entry, &fd);
+		if (r1 < r)
+			r =3D r1;
+	}
+	r1 =3D setup_sparse(a, entry, &fd);
 	if (r1 < r)
 		r =3D r1;
=20
@@ -262,7 +280,7 @@
  */
 static int
 setup_mac_metadata(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	int tempfd =3D -1;
 	int copyfile_flags =3D COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
@@ -272,6 +290,7 @@
 	int have_attrs;
 	const char *name, *tempdir, *tempfile =3D NULL;
=20
+	(void)fd; /* UNUSED */
 	name =3D archive_entry_sourcepath(entry);
 	if (name =3D=3D NULL)
 		name =3D archive_entry_pathname(entry);
@@ -281,6 +300,14 @@
 		return (ARCHIVE_WARN);
 	}
=20
+	if (a->tree !=3D NULL) {
+		if (a->tree_enter_working_dir(a->tree) !=3D 0) {
+			archive_set_error(&a->archive, errno,
+				    "Couldn't change dir");
+				return (ARCHIVE_FAILED);
+		}
+	}
+
 	/* Short-circuit if there's nothing to do. */
 	have_attrs =3D copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
 	if (have_attrs =3D=3D -1) {
@@ -351,7 +378,7 @@
  */
 static int
 setup_mac_metadata(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	(void)a; /* UNUSED */
 	(void)entry; /* UNUSED */
@@ -362,15 +389,16 @@
=20
=20
 #ifdef HAVE_POSIX_ACL
-static void setup_acl_posix1e(struct archive_read_disk *a,
+static int translate_acl(struct archive_read_disk *a,
     struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
=20
 static int
-setup_acls_posix1e(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+setup_acls(struct archive_read_disk *a,
+    struct archive_entry *entry, int *fd)
 {
 	const char	*accpath;
 	acl_t		 acl;
+	int		r;
=20
 	accpath =3D archive_entry_sourcepath(entry);
 	if (accpath =3D=3D NULL)
@@ -378,9 +406,38 @@
=20
 	archive_entry_acl_clear(entry);
=20
+	/* Try NFS4 ACL first. */
+	if (*fd >=3D 0)
+		acl =3D acl_get_fd(*fd);
+#if HAVE_ACL_GET_LINK_NP
+	else if (!a->follow_symlinks)
+		acl =3D acl_get_link_np(accpath, ACL_TYPE_NFS4);
+#else
+	else if ((!a->follow_symlinks)
+	    && (archive_entry_filetype(entry) =3D=3D AE_IFLNK))
+		/* We can't get the ACL of a symlink, so we assume it can't
+		   have one. */
+		acl =3D NULL;
+#endif
+	else
+		acl =3D acl_get_file(accpath, ACL_TYPE_NFS4);
+#if HAVE_ACL_IS_TRIVIAL_NP
+	/* Ignore "trivial" ACLs that just mirror the file mode. */
+	acl_is_trivial_np(acl, &r);
+	if (r) {
+		acl_free(acl);
+		acl =3D NULL;
+	}
+#endif
+	if (acl !=3D NULL) {
+		translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+		acl_free(acl);
+		return (ARCHIVE_OK);
+	}
+
 	/* Retrieve access ACL from file. */
-	if (fd >=3D 0)
-		acl =3D acl_get_fd(fd);
+	if (*fd >=3D 0)
+		acl =3D acl_get_fd(*fd);
 #if HAVE_ACL_GET_LINK_NP
 	else if (!a->follow_symlinks)
 		acl =3D acl_get_link_np(accpath, ACL_TYPE_ACCESS);
@@ -394,7 +451,7 @@
 	else
 		acl =3D acl_get_file(accpath, ACL_TYPE_ACCESS);
 	if (acl !=3D NULL) {
-		setup_acl_posix1e(a, entry, acl,
+		translate_acl(a, entry, acl,
 		    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
 		acl_free(acl);
 	}
@@ -403,7 +460,7 @@
 	if (S_ISDIR(archive_entry_mode(entry))) {
 		acl =3D acl_get_file(accpath, ACL_TYPE_DEFAULT);
 		if (acl !=3D NULL) {
-			setup_acl_posix1e(a, entry, acl,
+			translate_acl(a, entry, acl,
 			    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
 			acl_free(acl);
 		}
@@ -412,68 +469,181 @@
 }
=20
 /*
- * Translate POSIX.1e ACL into libarchive internal structure.
+ * Translate system ACL into libarchive internal structure.
  */
-static void
-setup_acl_posix1e(struct archive_read_disk *a,
-    struct archive_entry *entry, acl_t acl, int archive_entry_acl_type)
+
+static struct {
+        int archive_perm;
+        int platform_perm;
+} acl_perm_map[] =3D {
+        {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+        {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
+        {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+        {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
+        {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
+        {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
+        {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
+        {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
+        {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
+        {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
+        {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
+        {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
+        {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
+        {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
+        {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
+        {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
+        {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
+        {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
+        {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+};
+
+static struct {
+        int archive_inherit;
+        int platform_inherit;
+} acl_inherit_map[] =3D {
+        {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
+	{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
+	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INH=
ERIT},
+	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
+};
+
+static int
+translate_acl(struct archive_read_disk *a,
+    struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
 {
 	acl_tag_t	 acl_tag;
+	acl_entry_type_t acl_type;
+	acl_flagset_t	 acl_flagset;
 	acl_entry_t	 acl_entry;
 	acl_permset_t	 acl_permset;
+	int		 brand, i, r, entry_acl_type;
 	int		 s, ae_id, ae_tag, ae_perm;
 	const char	*ae_name;
=20
+
+	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
+	// Make sure the "brand" on this ACL is consistent
+	// with the default_entry_acl_type bits provided.
+	acl_get_brand_np(acl, &brand);
+	switch (brand) {
+	case ACL_BRAND_POSIX:
+		switch (default_entry_acl_type) {
+		case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+		case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+			entry_acl_type =3D default_entry_acl_type;
+			break;
+		default:
+			// XXX set warning message?
+			return ARCHIVE_FAILED;
+		}
+		break;
+	case ACL_BRAND_NFS4:
+		if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+			// XXX set warning message?
+			return ARCHIVE_FAILED;
+		}
+		break;
+	default:
+		// XXX set warning message?
+		return ARCHIVE_FAILED;
+		break;
+	}
+
+
 	s =3D acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
 	while (s =3D=3D 1) {
 		ae_id =3D -1;
 		ae_name =3D NULL;
+		ae_perm =3D 0;
=20
 		acl_get_tag_type(acl_entry, &acl_tag);
-		if (acl_tag =3D=3D ACL_USER) {
+		switch (acl_tag) {
+		case ACL_USER:
 			ae_id =3D (int)*(uid_t *)acl_get_qualifier(acl_entry);
 			ae_name =3D archive_read_disk_uname(&a->archive, ae_id);
 			ae_tag =3D ARCHIVE_ENTRY_ACL_USER;
-		} else if (acl_tag =3D=3D ACL_GROUP) {
+			break;
+		case ACL_GROUP:
 			ae_id =3D (int)*(gid_t *)acl_get_qualifier(acl_entry);
 			ae_name =3D archive_read_disk_gname(&a->archive, ae_id);
 			ae_tag =3D ARCHIVE_ENTRY_ACL_GROUP;
-		} else if (acl_tag =3D=3D ACL_MASK) {
+			break;
+		case ACL_MASK:
 			ae_tag =3D ARCHIVE_ENTRY_ACL_MASK;
-		} else if (acl_tag =3D=3D ACL_USER_OBJ) {
+			break;
+		case ACL_USER_OBJ:
 			ae_tag =3D ARCHIVE_ENTRY_ACL_USER_OBJ;
-		} else if (acl_tag =3D=3D ACL_GROUP_OBJ) {
+			break;
+		case ACL_GROUP_OBJ:
 			ae_tag =3D ARCHIVE_ENTRY_ACL_GROUP_OBJ;
-		} else if (acl_tag =3D=3D ACL_OTHER) {
+			break;
+		case ACL_OTHER:
 			ae_tag =3D ARCHIVE_ENTRY_ACL_OTHER;
-		} else {
+			break;
+		case ACL_EVERYONE:
+			ae_tag =3D ARCHIVE_ENTRY_ACL_EVERYONE;
+			break;
+		default:
 			/* Skip types that libarchive can't support. */
+			s =3D acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
 			continue;
 		}
=20
+		// XXX acl type maps to allow/deny/audit/YYYY bits
+		// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
+		// non-NFSv4 ACLs
+		entry_acl_type =3D default_entry_acl_type;
+		r =3D acl_get_entry_type_np(acl_entry, &acl_type);
+		if (r =3D=3D 0) {
+			switch (acl_type) {
+			case ACL_ENTRY_TYPE_ALLOW:
+				entry_acl_type =3D ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+				break;
+			case ACL_ENTRY_TYPE_DENY:
+				entry_acl_type =3D ARCHIVE_ENTRY_ACL_TYPE_DENY;
+				break;
+			case ACL_ENTRY_TYPE_AUDIT:
+				entry_acl_type =3D ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
+				break;
+			case ACL_ENTRY_TYPE_ALARM:
+				entry_acl_type =3D ARCHIVE_ENTRY_ACL_TYPE_ALARM;
+				break;
+			}
+		}
+
+		/*
+		 * Libarchive stores "flag" (NFSv4 inheritance bits)
+		 * in the ae_perm bitmap.
+		 */
+		acl_get_flagset_np(acl_entry, &acl_flagset);
+                for (i =3D 0; i < (int)(sizeof(acl_inherit_map) / sizeof(a=
cl_inherit_map[0])); ++i) {
+			if (acl_get_flag_np(acl_flagset,
+					    acl_inherit_map[i].platform_inherit))
+				ae_perm |=3D acl_inherit_map[i].archive_inherit;
+
+                }
+
 		acl_get_permset(acl_entry, &acl_permset);
-		ae_perm =3D 0;
-		/*
-		 * acl_get_perm() is spelled differently on different
-		 * platforms; see above.
-		 */
-		if (ACL_GET_PERM(acl_permset, ACL_EXECUTE))
-			ae_perm |=3D ARCHIVE_ENTRY_ACL_EXECUTE;
-		if (ACL_GET_PERM(acl_permset, ACL_READ))
-			ae_perm |=3D ARCHIVE_ENTRY_ACL_READ;
-		if (ACL_GET_PERM(acl_permset, ACL_WRITE))
-			ae_perm |=3D ARCHIVE_ENTRY_ACL_WRITE;
+                for (i =3D 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_=
perm_map[0])); ++i) {
+			/*
+			 * acl_get_perm() is spelled differently on different
+			 * platforms; see above.
+			 */
+			if (ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm))
+				ae_perm |=3D acl_perm_map[i].archive_perm;
+		}
=20
-		archive_entry_acl_add_entry(entry,
-		    archive_entry_acl_type, ae_perm, ae_tag,
-		    ae_id, ae_name);
+		archive_entry_acl_add_entry(entry, entry_acl_type,
+					    ae_perm, ae_tag,
+					    ae_id, ae_name);
=20
 		s =3D acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
 	}
+	return (ARCHIVE_OK);
 }
 #else
 static int
-setup_acls_posix1e(struct archive_read_disk *a,
+setup_acls(struct archive_read_disk *a,
     struct archive_entry *entry, int fd)
 {
 	(void)a;      /* UNUSED */
@@ -568,7 +738,7 @@
=20
 static int
 setup_xattrs(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	char *list, *p;
 	const char *path;
@@ -578,16 +748,30 @@
 	if (path =3D=3D NULL)
 		path =3D archive_entry_pathname(entry);
=20
+	if (*fd < 0 && a->tree !=3D NULL) {
+		if (a->follow_symlinks ||
+		    archive_entry_filetype(entry) !=3D AE_IFLNK)
+			*fd =3D a->open_on_current_dir(a->tree, path,
+				O_RDONLY | O_NONBLOCK);
+		if (*fd < 0) {
+			if (a->tree_enter_working_dir(a->tree) !=3D 0) {
+				archive_set_error(&a->archive, errno,
+				    "Couldn't access %s", path);
+				return (ARCHIVE_FAILED);
+			}
+		}
+	}
+
 #if HAVE_FLISTXATTR
-	if (fd >=3D 0)
-		list_size =3D flistxattr(fd, NULL, 0);
+	if (*fd >=3D 0)
+		list_size =3D flistxattr(*fd, NULL, 0);
 	else if (!a->follow_symlinks)
 		list_size =3D llistxattr(path, NULL, 0);
 	else
 		list_size =3D listxattr(path, NULL, 0);
 #elif HAVE_FLISTEA
-	if (fd >=3D 0)
-		list_size =3D flistea(fd, NULL, 0);
+	if (*fd >=3D 0)
+		list_size =3D flistea(*fd, NULL, 0);
 	else if (!a->follow_symlinks)
 		list_size =3D llistea(path, NULL, 0);
 	else
@@ -611,15 +795,15 @@
 	}
=20
 #if HAVE_FLISTXATTR
-	if (fd >=3D 0)
-		list_size =3D flistxattr(fd, list, list_size);
+	if (*fd >=3D 0)
+		list_size =3D flistxattr(*fd, list, list_size);
 	else if (!a->follow_symlinks)
 		list_size =3D llistxattr(path, list, list_size);
 	else
 		list_size =3D listxattr(path, list, list_size);
 #elif HAVE_FLISTEA
-	if (fd >=3D 0)
-		list_size =3D flistea(fd, list, list_size);
+	if (*fd >=3D 0)
+		list_size =3D flistea(*fd, list, list_size);
 	else if (!a->follow_symlinks)
 		list_size =3D llistea(path, list, list_size);
 	else
@@ -637,7 +821,7 @@
 		if (strncmp(p, "system.", 7) =3D=3D 0 ||
 				strncmp(p, "xfsroot.", 8) =3D=3D 0)
 			continue;
-		setup_xattr(a, entry, p, fd);
+		setup_xattr(a, entry, p, *fd);
 	}
=20
 	free(list);
@@ -698,6 +882,7 @@
 		size =3D extattr_get_file(accpath, namespace, name, value, size);
=20
 	if (size =3D=3D -1) {
+		free(value);
 		archive_set_error(&a->archive, errno,
 		    "Couldn't read extended attribute");
 		return (ARCHIVE_WARN);
@@ -711,7 +896,7 @@
=20
 static int
 setup_xattrs(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	char buff[512];
 	char *list, *p;
@@ -723,8 +908,22 @@
 	if (path =3D=3D NULL)
 		path =3D archive_entry_pathname(entry);
=20
-	if (fd >=3D 0)
-		list_size =3D extattr_list_fd(fd, namespace, NULL, 0);
+	if (*fd < 0 && a->tree !=3D NULL) {
+		if (a->follow_symlinks ||
+		    archive_entry_filetype(entry) !=3D AE_IFLNK)
+			*fd =3D a->open_on_current_dir(a->tree, path,
+				O_RDONLY | O_NONBLOCK);
+		if (*fd < 0) {
+			if (a->tree_enter_working_dir(a->tree) !=3D 0) {
+				archive_set_error(&a->archive, errno,
+				    "Couldn't access %s", path);
+				return (ARCHIVE_FAILED);
+			}
+		}
+	}
+
+	if (*fd >=3D 0)
+		list_size =3D extattr_list_fd(*fd, namespace, NULL, 0);
 	else if (!a->follow_symlinks)
 		list_size =3D extattr_list_link(path, namespace, NULL, 0);
 	else
@@ -746,8 +945,8 @@
 		return (ARCHIVE_FATAL);
 	}
=20
-	if (fd >=3D 0)
-		list_size =3D extattr_list_fd(fd, namespace, list, list_size);
+	if (*fd >=3D 0)
+		list_size =3D extattr_list_fd(*fd, namespace, list, list_size);
 	else if (!a->follow_symlinks)
 		list_size =3D extattr_list_link(path, namespace, list, list_size);
 	else
@@ -769,7 +968,7 @@
 		name =3D buff + strlen(buff);
 		memcpy(name, p + 1, len);
 		name[len] =3D '\0';
-		setup_xattr(a, entry, namespace, name, buff, fd);
+		setup_xattr(a, entry, namespace, name, buff, *fd);
 		p +=3D 1 + len;
 	}
=20
@@ -784,7 +983,7 @@
  */
 static int
 setup_xattrs(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	(void)a;     /* UNUSED */
 	(void)entry; /* UNUSED */
@@ -813,14 +1012,13 @@
=20
 static int
 setup_sparse(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    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 =3D fd;
 	int exit_sts =3D ARCHIVE_OK;
=20
 	if (archive_entry_filetype(entry) !=3D AE_IFREG
@@ -828,14 +1026,18 @@
 	    || archive_entry_hardlink(entry) !=3D NULL)
 		return (ARCHIVE_OK);
=20
-	if (fd < 0) {
+	if (*fd < 0) {
 		const char *path;
=20
 		path =3D archive_entry_sourcepath(entry);
 		if (path =3D=3D NULL)
 			path =3D archive_entry_pathname(entry);
-		fd =3D open(path, O_RDONLY | O_NONBLOCK);
-		if (fd < 0) {
+		if (a->tree !=3D NULL)
+			*fd =3D a->open_on_current_dir(a->tree, path,
+				O_RDONLY | O_NONBLOCK);
+		else
+			*fd =3D open(path, O_RDONLY | O_NONBLOCK);
+		if (*fd < 0) {
 			archive_set_error(&a->archive, errno,
 			    "Can't open `%s'", path);
 			return (ARCHIVE_FAILED);
@@ -853,18 +1055,11 @@
 	for (;;) {
 		int i, r;
=20
-		r =3D ioctl(fd, FS_IOC_FIEMAP, fm);=20
+		r =3D ioctl(*fd, FS_IOC_FIEMAP, fm);=20
 		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 !=3D ENOTTY && errno !=3D EOPNOTSUPP) {
-				archive_set_error(&a->archive, errno,
-				    "FIEMAP failed");
-				exit_sts =3D ARCHIVE_FAILED;
-			}
+			/* When something error happens, it is better we
+			 * should return ARCHIVE_OK because an earlier
+			 * version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
 			goto exit_setup_sparse;
 		}
 		if (fm->fm_mapped_extents =3D=3D 0)
@@ -896,8 +1091,6 @@
 			break;
 	}
 exit_setup_sparse:
-	if (initial_fd !=3D fd)
-		close(fd);
 	return (exit_sts);
 }
=20
@@ -909,10 +1102,9 @@
=20
 static int
 setup_sparse(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	int64_t size;
-	int initial_fd =3D 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 =3D ARCHIVE_OK;
@@ -923,22 +1115,38 @@
 		return (ARCHIVE_OK);
=20
 	/* Does filesystem support the reporting of hole ? */
-	if (fd >=3D 0) {
-		if (fpathconf(fd, _PC_MIN_HOLE_SIZE) <=3D 0)
+	if (*fd < 0 && a->tree !=3D NULL) {
+		const char *path;
+
+		path =3D archive_entry_sourcepath(entry);
+		if (path =3D=3D NULL)
+			path =3D archive_entry_pathname(entry);
+		*fd =3D a->open_on_current_dir(a->tree, path,
+				O_RDONLY | O_NONBLOCK);
+		if (*fd < 0) {
+			archive_set_error(&a->archive, errno,
+			    "Can't open `%s'", path);
+			return (ARCHIVE_FAILED);
+		}
+	}
+
+	if (*fd >=3D 0) {
+		if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <=3D 0)
 			return (ARCHIVE_OK);
-		initial_off =3D lseek(fd, 0, SEEK_CUR);
+		initial_off =3D lseek(*fd, 0, SEEK_CUR);
 		if (initial_off !=3D 0)
-			lseek(fd, 0, SEEK_SET);
+			lseek(*fd, 0, SEEK_SET);
 	} else {
 		const char *path;
=20
 		path =3D archive_entry_sourcepath(entry);
 		if (path =3D=3D NULL)
 			path =3D archive_entry_pathname(entry);
+		=09
 		if (pathconf(path, _PC_MIN_HOLE_SIZE) <=3D 0)
 			return (ARCHIVE_OK);
-		fd =3D open(path, O_RDONLY | O_NONBLOCK);
-		if (fd < 0) {
+		*fd =3D open(path, O_RDONLY | O_NONBLOCK);
+		if (*fd < 0) {
 			archive_set_error(&a->archive, errno,
 			    "Can't open `%s'", path);
 			return (ARCHIVE_FAILED);
@@ -949,7 +1157,7 @@
 	off_s =3D 0;
 	size =3D archive_entry_size(entry);
 	while (off_s < size) {
-		off_s =3D lseek(fd, off_s, SEEK_DATA);
+		off_s =3D lseek(*fd, off_s, SEEK_DATA);
 		if (off_s =3D=3D (off_t)-1) {
 			if (errno =3D=3D ENXIO)
 				break;/* no more hole */
@@ -958,10 +1166,10 @@
 			exit_sts =3D ARCHIVE_FAILED;
 			goto exit_setup_sparse;
 		}
-		off_e =3D lseek(fd, off_s, SEEK_HOLE);
-		if (off_s =3D=3D (off_t)-1) {
+		off_e =3D lseek(*fd, off_s, SEEK_HOLE);
+		if (off_e =3D=3D (off_t)-1) {
 			if (errno =3D=3D ENXIO) {
-				off_e =3D lseek(fd, 0, SEEK_END);
+				off_e =3D lseek(*fd, 0, SEEK_END);
 				if (off_e !=3D (off_t)-1)
 					break;/* no more data */
 			}
@@ -977,10 +1185,7 @@
 		off_s =3D off_e;
 	}
 exit_setup_sparse:
-	if (initial_fd !=3D fd)
-		close(fd);
-	else
-		lseek(fd, initial_off, SEEK_SET);
+	lseek(*fd, initial_off, SEEK_SET);
 	return (exit_sts);
 }
=20
@@ -991,7 +1196,7 @@
  */
 static int
 setup_sparse(struct archive_read_disk *a,
-    struct archive_entry *entry, int fd)
+    struct archive_entry *entry, int *fd)
 {
 	(void)a;     /* UNUSED */
 	(void)entry; /* UNUSED */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_disk_posix.c
--- a/head/contrib/libarchive/libarchive/archive_read_disk_posix.c	Mon Jul =
30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_disk_posix.c	Fri Aug =
10 14:19:25 2012 +0300
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2003-2009 Tim Kientzle
- * Copyright (c) 2010,2011 Michihiro NAKAJIMA
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,19 @@
 #ifdef HAVE_LINUX_MAGIC_H
 #include <linux/magic.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_DIRECT_H
 #include <direct.h>
 #endif
@@ -76,6 +89,9 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
=20
 #include "archive.h"
 #include "archive_string.h"
@@ -222,6 +238,7 @@
 	char			 symlink_mode;
 	struct filesystem	*current_filesystem;
 	struct filesystem	*filesystem_table;
+	int			 initial_filesystem_id;
 	int			 current_filesystem_id;
 	int			 max_filesystem_id;
 	int			 allocated_filesytem;
@@ -240,6 +257,7 @@
 #define	onWorkingDir	64 /* We are on the working dir where we are
 			    * reading directory entry at this time. */
 #define	needsRestoreTimes 128
+#define	onInitialDir	256 /* We are on the initial dir. */
=20
 static int
 tree_dir_next_posix(struct tree *t);
@@ -342,6 +360,7 @@
 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 int	open_on_current_dir(struct tree *, const char *, int);
=20
=20
 static struct archive_vtable *
@@ -430,16 +449,19 @@
 {
 	struct archive_read_disk *a;
=20
-	a =3D (struct archive_read_disk *)malloc(sizeof(*a));
+	a =3D (struct archive_read_disk *)calloc(1, sizeof(*a));
 	if (a =3D=3D NULL)
 		return (NULL);
-	memset(a, 0, sizeof(*a));
 	a->archive.magic =3D ARCHIVE_READ_DISK_MAGIC;
 	a->archive.state =3D ARCHIVE_STATE_NEW;
 	a->archive.vtable =3D archive_read_disk_vtable();
 	a->lookup_uname =3D trivial_lookup_uname;
 	a->lookup_gname =3D trivial_lookup_gname;
-	a->entry_wd_fd =3D -1;
+	a->enable_copyfile =3D 1;
+	a->traverse_mount_points =3D 1;
+	a->open_on_current_dir =3D open_on_current_dir;
+	a->tree_current_dir_fd =3D tree_current_dir_fd;
+	a->tree_enter_working_dir =3D tree_enter_working_dir;
 	return (&a->archive);
 }
=20
@@ -555,6 +577,37 @@
 #endif
 }
=20
+int
+archive_read_disk_set_behavior(struct archive *_a, int flags)
+{
+	struct archive_read_disk *a =3D (struct archive_read_disk *)_a;
+	int r =3D ARCHIVE_OK;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
+
+	if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
+		r =3D archive_read_disk_set_atime_restored(_a);
+	else {
+		a->restore_time =3D 0;
+		if (a->tree !=3D NULL)
+			a->tree->flags &=3D ~needsRestoreTimes;
+	}
+	if (flags & ARCHIVE_READDISK_HONOR_NODUMP)
+		a->honor_nodump =3D 1;
+	else
+		a->honor_nodump =3D 0;
+	if (flags & ARCHIVE_READDISK_MAC_COPYFILE)
+		a->enable_copyfile =3D 1;
+	else
+		a->enable_copyfile =3D 0;
+	if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
+		a->traverse_mount_points =3D 0;
+	else
+		a->traverse_mount_points =3D 1;
+	return (r);
+}
+
 /*
  * Trivial implementations of gname/uname lookup functions.
  * These are normally overridden by the client, but these stub
@@ -685,13 +738,8 @@
 			flags |=3D O_NOATIME;
 		do {
 #endif
-#ifdef HAVE_OPENAT
-			t->entry_fd =3D openat(tree_current_dir_fd(t),
+			t->entry_fd =3D open_on_current_dir(t,
 			    tree_current_access_path(t), flags);
-#else
-			tree_enter_working_dir(t);
-			t->entry_fd =3D open(tree_current_access_path(t), flags);
-#endif
 #if defined(O_NOATIME)
 			/*
 			 * When we did open the file with O_NOATIME flag,
@@ -802,29 +850,17 @@
 }
=20
 static int
-_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+next_entry(struct archive_read_disk *a, struct tree *t,
+    struct archive_entry *entry)
 {
-	struct archive_read_disk *a =3D (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 =3D -1, r;
+	const char *name;
+	int descend, r;
=20
-	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
-	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
-	    "archive_read_next_header2");
-
-	t =3D a->tree;
-	if (t->entry_fd >=3D 0) {
-		close_and_restore_time(t->entry_fd, t, &t->restore_time);
-		t->entry_fd =3D -1;
-	}
-#if !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPEN=
DIR))
-	/* Restore working directory. */
-	tree_enter_working_dir(t);
-#endif
 	st =3D NULL;
 	lst =3D NULL;
+	t->descend =3D 0;
 	do {
 		switch (tree_next(t)) {
 		case TREE_ERROR_FATAL:
@@ -859,6 +895,38 @@
 		}=09
 	} while (lst =3D=3D NULL);
=20
+#ifdef __APPLE__
+	if (a->enable_copyfile) {
+		/* If we're using copyfile(), ignore "._XXX" files. */
+		const char *bname =3D strrchr(tree_current_path(t), '/');
+		if (bname =3D=3D NULL)
+			bname =3D tree_current_path(t);
+		else
+			++bname;
+		if (bname[0] =3D=3D '.' && bname[1] =3D=3D '_')
+			return (ARCHIVE_RETRY);
+	}
+#endif
+
+	archive_entry_copy_pathname(entry, tree_current_path(t));
+	/*
+	 * Perform path matching.
+	 */
+	if (a->matching) {
+		r =3D archive_match_path_excluded(a->matching, entry);
+		if (r < 0) {
+			archive_set_error(&(a->archive), errno,
+			    "Faild : %s", archive_error_string(a->matching));
+			return (r);
+		}
+		if (r) {
+			if (a->excluded_cb_func)
+				a->excluded_cb_func(&(a->archive),
+				    a->excluded_cb_data, entry);
+			return (ARCHIVE_RETRY);
+		}
+	}
+
 	/*
 	 * Distinguish 'L'/'P'/'H' symlink following.
 	 */
@@ -897,13 +965,44 @@
 		tree_enter_initial_dir(t);
 		return (ARCHIVE_FATAL);
 	}
+	if (t->initial_filesystem_id =3D=3D -1)
+		t->initial_filesystem_id =3D t->current_filesystem_id;
+	if (!a->traverse_mount_points) {
+		if (t->initial_filesystem_id !=3D t->current_filesystem_id)
+			return (ARCHIVE_RETRY);
+	}
 	t->descend =3D descend;
=20
-	archive_entry_set_pathname(entry, tree_current_path(t));
-	archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
+	/*
+	 * Honor nodump flag.
+	 * If the file is marked with nodump flag, do not return this entry.
+	 */
+	if (a->honor_nodump) {
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+		if (st->st_flags & UF_NODUMP)
+			return (ARCHIVE_RETRY);
+#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
+      defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+		if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
+			unsigned long stflags;
+
+			t->entry_fd =3D open_on_current_dir(t,
+			    tree_current_access_path(t), O_RDONLY | O_NONBLOCK);
+			if (t->entry_fd >=3D 0) {
+				r =3D ioctl(t->entry_fd, EXT2_IOC_GETFLAGS,
+					&stflags);
+				if (r =3D=3D 0 && (stflags & EXT2_NODUMP_FL) !=3D 0)
+					return (ARCHIVE_RETRY);
+			}
+		}
+#endif
+	}
+
 	archive_entry_copy_stat(entry, st);
=20
-	/* Save the times to be restored. */
+	/* Save the times to be restored. This must be in before
+	 * calling archive_read_disk_descend() or any chance of it,
+	 * especially, invokng a callback. */
 	t->restore_time.mtime =3D archive_entry_mtime(entry);
 	t->restore_time.mtime_nsec =3D archive_entry_mtime_nsec(entry);
 	t->restore_time.atime =3D archive_entry_atime(entry);
@@ -911,39 +1010,102 @@
 	t->restore_time.filetype =3D archive_entry_filetype(entry);
 	t->restore_time.noatime =3D t->current_filesystem->noatime;
=20
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDI=
R)
 	/*
-	 * Open the current file to freely gather its metadata anywhere in
-	 * working directory.
-	 * Note: A symbolic link file cannot be opened with O_NOFOLLOW.
+	 * Perform time matching.
 	 */
-	if (a->follow_symlinks || archive_entry_filetype(entry) !=3D AE_IFLNK)
-		fd =3D 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);
+	if (a->matching) {
+		r =3D archive_match_time_excluded(a->matching, entry);
+		if (r < 0) {
+			archive_set_error(&(a->archive), errno,
+			    "Faild : %s", archive_error_string(a->matching));
+			return (r);
+		}
+		if (r) {
+			if (a->excluded_cb_func)
+				a->excluded_cb_func(&(a->archive),
+				    a->excluded_cb_data, entry);
+			return (ARCHIVE_RETRY);
+		}
+	}
=20
-	/* The current direcotry fd is needed at
-	 * archive_read_disk_entry_from_file() function to read link data
-	 * with readlinkat(). */
-	a->entry_wd_fd =3D tree_current_dir_fd(t);
-#endif
+	/* Lookup uname/gname */
+	name =3D archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
+	if (name !=3D NULL)
+		archive_entry_copy_uname(entry, name);
+	name =3D archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
+	if (name !=3D NULL)
+		archive_entry_copy_gname(entry, name);
+
+	/*
+	 * Perform owner matching.
+	 */
+	if (a->matching) {
+		r =3D archive_match_owner_excluded(a->matching, entry);
+		if (r < 0) {
+			archive_set_error(&(a->archive), errno,
+			    "Faild : %s", archive_error_string(a->matching));
+			return (r);
+		}
+		if (r) {
+			if (a->excluded_cb_func)
+				a->excluded_cb_func(&(a->archive),
+				    a->excluded_cb_data, entry);
+			return (ARCHIVE_RETRY);
+		}
+	}
+
+	/*
+	 * Invoke a meta data filter callback.
+	 */
+	if (a->metadata_filter_func) {
+		if (!a->metadata_filter_func(&(a->archive),
+		    a->metadata_filter_data, entry))
+			return (ARCHIVE_RETRY);
+	}
=20
 	/*
 	 * Populate the archive_entry with metadata from the disk.
 	 */
-	r =3D archive_read_disk_entry_from_file(&(a->archive), entry, fd, st);
+	archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
+	r =3D archive_read_disk_entry_from_file(&(a->archive), entry,
+		t->entry_fd, st);
=20
-	/* Close the file descriptor used for reding the current file
-	 * metadata at archive_read_disk_entry_from_file(). */
-	if (fd >=3D 0)
-		close(fd);
+	return (r);
+}
+
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+	struct archive_read_disk *a =3D (struct archive_read_disk *)_a;
+	struct tree *t;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_read_next_header2");
+
+	t =3D a->tree;
+	if (t->entry_fd >=3D 0) {
+		close_and_restore_time(t->entry_fd, t, &t->restore_time);
+		t->entry_fd =3D -1;
+	}
+
+	for (;;) {
+		r =3D next_entry(a, t, entry);
+		if (t->entry_fd >=3D 0) {
+			close(t->entry_fd);
+			t->entry_fd =3D -1;
+		}
+
+		if (r =3D=3D ARCHIVE_RETRY) {
+			archive_entry_clear(entry);
+			continue;
+		}
+		break;
+	}
=20
 	/* Return to the initial directory. */
 	tree_enter_initial_dir(t);
-	archive_entry_copy_sourcepath(entry, tree_current_path(t));
=20
 	/*
 	 * EOF and FATAL are persistent at this layer.  By
@@ -956,6 +1118,8 @@
 		break;
 	case ARCHIVE_OK:
 	case ARCHIVE_WARN:
+		/* Overwrite the sourcepath based on the initial directory. */
+		archive_entry_copy_sourcepath(entry, tree_current_path(t));
 		t->entry_total =3D 0;
 		if (archive_entry_filetype(entry) =3D=3D AE_IFREG) {
 			t->nlink =3D archive_entry_nlink(entry);
@@ -1018,6 +1182,48 @@
 	return (ARCHIVE_OK);
 }
=20
+int
+archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
+    void (*_excluded_func)(struct archive *, void *, struct archive_entry =
*),
+    void *_client_data)
+{
+	struct archive_read_disk *a =3D (struct archive_read_disk *)_a;
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
+	a->matching =3D _ma;
+	a->excluded_cb_func =3D _excluded_func;
+	a->excluded_cb_data =3D _client_data;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_metadata_filter_callback(struct archive *_a,
+    int (*_metadata_filter_func)(struct archive *, void *,
+    struct archive_entry *), void *_client_data)
+{
+	struct archive_read_disk *a =3D (struct archive_read_disk *)_a;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
+	    "archive_read_disk_set_metadata_filter_callback");
+
+	a->metadata_filter_func =3D _metadata_filter_func;
+	a->metadata_filter_data =3D _client_data;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_can_descend(struct archive *_a)
+{
+	struct archive_read_disk *a =3D (struct archive_read_disk *)_a;
+	struct tree *t =3D a->tree;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_read_disk_can_descend");
+
+	return (t->visit_type =3D=3D TREE_REGULAR && t->descend);
+}
+
 /*
  * Called by the client to mark the directory just returned from
  * tree_next() as needing to be visited.
@@ -1028,14 +1234,12 @@
 	struct archive_read_disk *a =3D (struct archive_read_disk *)_a;
 	struct tree *t =3D a->tree;
=20
-	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 	    "archive_read_disk_descend");
=20
-	if (t->visit_type !=3D TREE_REGULAR || !t->descend) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Ignored the request descending the current object");
-		return (ARCHIVE_WARN);
-	}
+	if (t->visit_type !=3D TREE_REGULAR || !t->descend)
+		return (ARCHIVE_OK);
=20
 	if (tree_current_is_physical_dir(t)) {
 		tree_push(t, t->basename, t->current_filesystem_id,
@@ -1079,8 +1283,12 @@
 	archive_string_init(&path);
 	if (archive_string_append_from_wcs(&path, pathname,
 	    wcslen(pathname)) !=3D 0) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Can't convert a path to a char string");
+		if (errno =3D=3D ENOMEM)
+			archive_set_error(&a->archive, ENOMEM,
+			    "Can't allocate memory");
+		else
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Can't convert a path to a char string");
 		a->archive.state =3D ARCHIVE_STATE_FATAL;
 		ret =3D ARCHIVE_FATAL;
 	} else
@@ -1268,7 +1476,7 @@
 	t->current_filesystem->synthetic =3D -1;
 	t->current_filesystem->remote =3D -1;
 	if (tree_current_is_symblic_link_target(t)) {
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDI=
R)
+#if defined(HAVE_OPENAT)
 		/*
 		 * Get file system statistics on any directory
 		 * where current is.
@@ -1285,6 +1493,10 @@
 			xr =3D get_xfer_size(t, fd, NULL);
 		close(fd);
 #else
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		r =3D statfs(tree_current_access_path(t), &sfs);
 		if (r =3D=3D 0)
 			xr =3D get_xfer_size(t, -1, tree_current_access_path(t));
@@ -1334,9 +1546,13 @@
 	t->current_filesystem->name_max =3D sfs.f_namemax;
 #else
 	/* Mac OS X does not have f_namemax in struct statfs. */
-	if (tree_current_is_symblic_link_target(t))
+	if (tree_current_is_symblic_link_target(t)) {
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		nm =3D pathconf(tree_current_access_path(t), _PC_NAME_MAX);
-	else
+	} else
 		nm =3D fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
 	if (nm =3D=3D -1)
 		t->current_filesystem->name_max =3D NAME_MAX;
@@ -1360,6 +1576,10 @@
 	int r, xr =3D 0;
=20
 	t->current_filesystem->synthetic =3D -1;
+	if (tree_enter_working_dir(t) !=3D 0) {
+		archive_set_error(&a->archive, errno, "fchdir failed");
+		return (ARCHIVE_FAILED);
+	}
 	if (tree_current_is_symblic_link_target(t)) {
 		r =3D statvfs(tree_current_access_path(t), &sfs);
 		if (r =3D=3D 0)
@@ -1384,17 +1604,24 @@
 		 * for pathconf() function. */
 		t->current_filesystem->xfer_align =3D sfs.f_frsize;
 		t->current_filesystem->max_xfer_size =3D -1;
+#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
 		t->current_filesystem->min_xfer_size =3D sfs.f_iosize;
 		t->current_filesystem->incr_xfer_size =3D sfs.f_iosize;
+#else
+		t->current_filesystem->min_xfer_size =3D sfs.f_bsize;
+		t->current_filesystem->incr_xfer_size =3D sfs.f_bsize;
+#endif
 	}
 	if (sfs.f_flag & ST_LOCAL)
 		t->current_filesystem->remote =3D 0;
 	else
 		t->current_filesystem->remote =3D 1;
=20
+#if defined(ST_NOATIME)
 	if (sfs.f_flag & ST_NOATIME)
 		t->current_filesystem->noatime =3D 1;
 	else
+#endif
 		t->current_filesystem->noatime =3D 0;
=20
 	/* Set maximum filename length. */
@@ -1427,7 +1654,7 @@
 	int r, vr =3D 0, xr =3D 0;
=20
 	if (tree_current_is_symblic_link_target(t)) {
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDI=
R)
+#if defined(HAVE_OPENAT)
 		/*
 		 * Get file system statistics on any directory
 		 * where current is.
@@ -1445,6 +1672,10 @@
 			xr =3D get_xfer_size(t, fd, NULL);
 		close(fd);
 #else
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		vr =3D statvfs(tree_current_access_path(t), &svfs);
 		r =3D statfs(tree_current_access_path(t), &sfs);
 		if (r =3D=3D 0)
@@ -1456,9 +1687,11 @@
 		r =3D fstatfs(tree_current_dir_fd(t), &sfs);
 		if (r =3D=3D 0)
 			xr =3D get_xfer_size(t, tree_current_dir_fd(t), NULL);
-#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPEN=
DIR)
-#error "Unexpected case. Please tell us about this error."
 #else
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		vr =3D statvfs(".", &svfs);
 		r =3D statfs(".", &sfs);
 		if (r =3D=3D 0)
@@ -1529,7 +1762,7 @@
 	t->current_filesystem->synthetic =3D -1;/* Not supported */
 	t->current_filesystem->remote =3D -1;/* Not supported */
 	if (tree_current_is_symblic_link_target(t)) {
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDI=
R)
+#if defined(HAVE_OPENAT)
 		/*
 		 * Get file system statistics on any directory
 		 * where current is.
@@ -1546,6 +1779,10 @@
 			xr =3D get_xfer_size(t, fd, NULL);
 		close(fd);
 #else
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		r =3D statvfs(tree_current_access_path(t), &sfs);
 		if (r =3D=3D 0)
 			xr =3D get_xfer_size(t, -1, tree_current_access_path(t));
@@ -1555,9 +1792,11 @@
 		r =3D fstatvfs(tree_current_dir_fd(t), &sfs);
 		if (r =3D=3D 0)
 			xr =3D get_xfer_size(t, tree_current_dir_fd(t), NULL);
-#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPEN=
DIR)
-#error "Unexpected case. Please tell us about this error."
 #else
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		r =3D statvfs(".", &sfs);
 		if (r =3D=3D 0)
 			xr =3D get_xfer_size(t, -1, ".");
@@ -1615,9 +1854,13 @@
 #if defined(HAVE_READDIR_R)
 	/* Set maximum filename length. */
 #  if defined(_PC_NAME_MAX)
-	if (tree_current_is_symblic_link_target(t))
+	if (tree_current_is_symblic_link_target(t)) {
+		if (tree_enter_working_dir(t) !=3D 0) {
+			archive_set_error(&a->archive, errno, "fchdir failed");
+			return (ARCHIVE_FAILED);
+		}
 		nm =3D pathconf(tree_current_access_path(t), _PC_NAME_MAX);
-	else
+	} else
 		nm =3D fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
 	if (nm =3D=3D -1)
 #  endif /* _PC_NAME_MAX */
@@ -1697,6 +1940,18 @@
 	return (0);
 }
=20
+static int
+open_on_current_dir(struct tree *t, const char *path, int flags)
+{
+#ifdef HAVE_OPENAT
+	return (openat(tree_current_dir_fd(t), path, flags));
+#else
+	if (tree_enter_working_dir(t) !=3D 0)
+		return (-1);
+	return (open(path, flags));
+#endif
+}
+
 /*
  * Add a directory path to the current stack.
  */
@@ -1778,6 +2033,7 @@
 tree_reopen(struct tree *t, const char *path, int restore_time)
 {
 	t->flags =3D (restore_time)?needsRestoreTimes:0;
+	t->flags |=3D onInitialDir;
 	t->visit_type =3D 0;
 	t->tree_errno =3D 0;
 	t->dirname_length =3D 0;
@@ -1790,6 +2046,7 @@
 	t->entry_fd =3D -1;
 	t->entry_eof =3D 0;
 	t->entry_remaining_bytes =3D 0;
+	t->initial_filesystem_id =3D -1;
=20
 	/* First item is set up a lot like a symlink traversal. */
 	tree_push(t, path, 0, 0, 0, NULL);
@@ -1803,12 +2060,14 @@
 static int
 tree_descent(struct tree *t)
 {
-	int r =3D 0;
+	int flag, new_fd, r =3D 0;
=20
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDI=
R)
-	int new_fd;
 	t->dirname_length =3D archive_strlen(&t->path);
-	new_fd =3D openat(t->working_dir_fd, t->stack->name.s, O_RDONLY);
+	flag =3D O_RDONLY;
+#if defined(O_DIRECTORY)
+	flag |=3D O_DIRECTORY;
+#endif
+	new_fd =3D open_on_current_dir(t, t->stack->name.s, flag);
 	if (new_fd < 0) {
 		t->tree_errno =3D errno;
 		r =3D TREE_ERROR_DIR;
@@ -1822,30 +2081,10 @@
 				t->maxOpenCount =3D t->openCount;
 		} else
 			close(t->working_dir_fd);
+		/* Renew the current working directory. */
 		t->working_dir_fd =3D new_fd;
+		t->flags &=3D ~onWorkingDir;
 	}
-#else
-	/* If it is a link, set up fd for the ascent. */
-	if (t->stack->flags & isDirLink)
-		t->stack->symlink_parent_fd =3D t->working_dir_fd;
-	else {
-		close(t->working_dir_fd);
-		t->openCount--;
-	}
-	t->working_dir_fd =3D -1;
-	t->dirname_length =3D archive_strlen(&t->path);
-	if (chdir(t->stack->name.s) !=3D 0)
-	{
-		t->tree_errno =3D errno;
-		r =3D TREE_ERROR_DIR;
-	} else {
-		t->depth++;
-		t->working_dir_fd =3D open(".", O_RDONLY);
-		t->openCount++;
-		if (t->openCount > t->maxOpenCount)
-			t->maxOpenCount =3D t->openCount;
-	}
-#endif
 	return (r);
 }
=20
@@ -1856,37 +2095,21 @@
 tree_ascend(struct tree *t)
 {
 	struct tree_entry *te;
-	int r =3D 0, prev_dir_fd;
+	int new_fd, r =3D 0, prev_dir_fd;
=20
 	te =3D t->stack;
 	prev_dir_fd =3D t->working_dir_fd;
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDI=
R)
 	if (te->flags & isDirLink)
-		t->working_dir_fd =3D te->symlink_parent_fd;
-	else {
-		int new_fd =3D openat(t->working_dir_fd, "..", O_RDONLY);
-		if (new_fd < 0) {
-			t->tree_errno =3D errno;
-			r =3D TREE_ERROR_FATAL;
-		} else
-			t->working_dir_fd =3D new_fd;
-	}
-#else
-	if (te->flags & isDirLink) {
-		if (fchdir(te->symlink_parent_fd) !=3D 0) {
-			t->tree_errno =3D errno;
-			r =3D TREE_ERROR_FATAL;
-		} else
-			t->working_dir_fd =3D te->symlink_parent_fd;
+		new_fd =3D te->symlink_parent_fd;
+	else
+		new_fd =3D open_on_current_dir(t, "..", O_RDONLY);
+	if (new_fd < 0) {
+		t->tree_errno =3D errno;
+		r =3D TREE_ERROR_FATAL;
 	} else {
-		if (chdir("..") !=3D 0) {
-			t->tree_errno =3D errno;
-			r =3D TREE_ERROR_FATAL;
-		} else
-			t->working_dir_fd =3D open(".", O_RDONLY);
-	}
-#endif
-	if (r =3D=3D 0) {
+		/* Renew the current working directory. */
+		t->working_dir_fd =3D new_fd;
+		t->flags &=3D ~onWorkingDir;
 		/* 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);
@@ -1907,10 +2130,12 @@
 {
 	int r =3D 0;
=20
-	if (t->flags & onWorkingDir) {
+	if ((t->flags & onInitialDir) =3D=3D 0) {
 		r =3D fchdir(t->initial_dir_fd);
-		if (r =3D=3D 0)
+		if (r =3D=3D 0) {
 			t->flags &=3D ~onWorkingDir;
+			t->flags |=3D onInitialDir;
+		}
 	}
 	return (r);
 }
@@ -1930,8 +2155,10 @@
 	 */
 	if (t->depth > 0 && (t->flags & onWorkingDir) =3D=3D 0) {
 		r =3D fchdir(t->working_dir_fd);
-		if (r =3D=3D 0)
+		if (r =3D=3D 0) {
+			t->flags &=3D ~onInitialDir;
 			t->flags |=3D onWorkingDir;
+		}
 	}
 	return (r);
 }
@@ -2040,7 +2267,8 @@
 #if defined(HAVE_FDOPENDIR)
 		if ((t->d =3D fdopendir(dup(t->working_dir_fd))) =3D=3D NULL) {
 #else
-		if ((t->d =3D opendir(".")) =3D=3D NULL) {
+		if (tree_enter_working_dir(t) !=3D 0 ||
+		    (t->d =3D opendir(".")) =3D=3D NULL) {
 #endif
 			r =3D tree_ascend(t); /* Undo "chdir" */
 			tree_pop(t);
@@ -2111,6 +2339,8 @@
 		if (fstatat(tree_current_dir_fd(t),
 		    tree_current_access_path(t), &t->st, 0) !=3D 0)
 #else
+		if (tree_enter_working_dir(t) !=3D 0)
+			return NULL;
 		if (stat(tree_current_access_path(t), &t->st) !=3D 0)
 #endif
 			return NULL;
@@ -2131,6 +2361,8 @@
 		    tree_current_access_path(t), &t->lst,
 		    AT_SYMLINK_NOFOLLOW) !=3D 0)
 #else
+		if (tree_enter_working_dir(t) !=3D 0)
+			return NULL;
 		if (lstat(tree_current_access_path(t), &t->lst) !=3D 0)
 #endif
 			return NULL;
@@ -2152,7 +2384,10 @@
 	 */
 	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))
+		st =3D tree_current_lstat(t);
+		if (st =3D=3D NULL)
+			return 0;
+		if (S_ISDIR(st->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. */
@@ -2186,9 +2421,13 @@
 	 * 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;
+	if (t->flags & hasStat) {
+		st =3D tree_current_stat(t);
+		if (st =3D=3D NULL)
+			return (0);
+		if (!S_ISDIR(st->st_mode))
+			return (0);
+	}
=20
 	/*
 	 * Either stat() said it was a dir (in which case, we have
@@ -2232,7 +2471,7 @@
=20
 	lst =3D tree_current_lstat(t);
 	st =3D tree_current_stat(t);
-	return (st !=3D NULL &&
+	return (st !=3D NULL && lst !=3D NULL &&
 	    (int64_t)st->st_dev =3D=3D t->current_filesystem->dev &&
 	    st->st_dev !=3D lst->st_dev);
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_disk_private.h
--- a/head/contrib/libarchive/libarchive/archive_read_disk_private.h	Mon Ju=
l 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_disk_private.h	Fri Au=
g 10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
  * (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/contrib/libarchive/libarchive/archive_read_disk_private.=
h 232153 2012-02-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_read_disk_private.=
h 238856 2012-07-28 06:38:44Z mm $
  */
=20
 #ifndef __LIBARCHIVE_BUILD
@@ -34,6 +34,7 @@
 #define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
=20
 struct tree;
+struct archive_entry;
=20
 struct archive_read_disk {
 	struct archive	archive;
@@ -55,10 +56,18 @@
=20
 	/* Directory traversals. */
 	struct tree *tree;
+	int	(*open_on_current_dir)(struct tree*, const char *, int);
+	int	(*tree_current_dir_fd)(struct tree*);
+	int	(*tree_enter_working_dir)(struct tree*);
=20
 	/* Set 1 if users request to restore atime . */
 	int		 restore_time;
-	int		 entry_wd_fd;
+	/* Set 1 if users request to honor nodump flag . */
+	int		 honor_nodump;
+	/* Set 1 if users request to enable mac copyfile. */
+	int		 enable_copyfile;
+	/* Set 1 if users request to traverse mount points. */
+	int		 traverse_mount_points;
=20
 	const char * (*lookup_gname)(void *private, int64_t gid);
 	void	(*cleanup_gname)(void *private);
@@ -66,6 +75,18 @@
 	const char * (*lookup_uname)(void *private, int64_t uid);
 	void	(*cleanup_uname)(void *private);
 	void	 *lookup_uname_data;
+
+	int	(*metadata_filter_func)(struct archive *, void *,
+			struct archive_entry *);
+	void	*metadata_filter_data;
+
+	/* ARCHIVE_MATCH object. */
+	struct archive	*matching;
+	/* Callback function, this will be invoked when ARCHIVE_MATCH
+	 * archive_match_*_excluded_ae return true. */
+	void	(*excluded_cb_func)(struct archive *, void *,
+			 struct archive_entry *);
+	void	*excluded_cb_data;
 };
=20
 #endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_extract.3
--- a/head/contrib/libarchive/libarchive/archive_read_extract.3	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_extract.3	Fri Aug 10 =
14:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 22, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_EXTRACT 3
 .Os
 .Sh NAME
@@ -32,6 +32,8 @@
 .Nm archive_read_extract2 ,
 .Nm archive_read_extract_set_progress_callback
 .Nd functions for reading streaming archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_filter.3
--- a/head/contrib/libarchive/libarchive/archive_read_filter.3	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_filter.3	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 19, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_FILTER 3
 .Os
 .Sh NAME
@@ -39,6 +39,8 @@
 .Nm archive_read_support_filter_program_signature
 .Nd functions for reading streaming archives
 .\"
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_format.3
--- a/head/contrib/libarchive/libarchive/archive_read_format.3	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_format.3	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" 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:1=
3Z kientzle $
+.\" $FreeBSD$
 .\"
-.Dd March 19, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_FORMAT 3
 .Os
 .Sh NAME
@@ -45,6 +45,8 @@
 .Nm archive_read_support_format_zip
 .Nd functions for reading streaming archives
 .\"
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_free.3
--- a/head/contrib/libarchive/libarchive/archive_read_free.3	Mon Jul 30 11:=
44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_free.3	Fri Aug 10 14:=
19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" 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:1=
3Z kientzle $
+.\" $FreeBSD$
 .\"
-.Dd March 20, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_FREE 3
 .Os
 .Sh NAME
@@ -32,6 +32,8 @@
 .Nm archive_read_finish ,
 .Nm archive_read_free
 .Nd functions for reading streaming archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_header.3
--- a/head/contrib/libarchive/libarchive/archive_read_header.3	Mon Jul 30 1=
1:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_header.3	Fri Aug 10 1=
4:19:25 2012 +0300
@@ -24,13 +24,15 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 22, 2011
+.Dd February 2, 2012
 .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 LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_new.3
--- a/head/contrib/libarchive/libarchive/archive_read_new.3	Mon Jul 30 11:4=
4:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_new.3	Fri Aug 10 14:1=
9:25 2012 +0300
@@ -22,14 +22,16 @@
 .\" 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:1=
3Z kientzle $
+.\" $FreeBSD$
 .\"
-.Dd March 20, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_NEW 3
 .Os
 .Sh NAME
 .Nm archive_read_new
 .Nd functions for reading streaming archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft struct archive *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_open.3
--- a/head/contrib/libarchive/libarchive/archive_read_open.3	Mon Jul 30 11:=
44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_open.3	Fri Aug 10 14:=
19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" 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:1=
3Z kientzle $
+.\" $FreeBSD$
 .\"
-.Dd March 19, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_OPEN 3
 .Os
 .Sh NAME
@@ -35,6 +35,8 @@
 .Nm archive_read_open_filename ,
 .Nm archive_read_open_memory ,
 .Nd functions for reading streaming archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_open_fd.c
--- a/head/contrib/libarchive/libarchive/archive_read_open_fd.c	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_open_fd.c	Fri Aug 10 =
14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_open_f=
d.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_open_f=
d.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -129,8 +129,8 @@
 file_skip(struct archive *a, void *client_data, int64_t request)
 {
 	struct read_fd_data *mine =3D (struct read_fd_data *)client_data;
-	off_t skip =3D (off_t)request;
-	off_t old_offset, new_offset;
+	int64_t skip =3D request;
+	int64_t old_offset, new_offset;
 	int skip_bits =3D sizeof(skip) * 8 - 1;  /* off_t is a signed type. */
=20
 	if (!mine->use_lseek)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_open_filename.c
--- a/head/contrib/libarchive/libarchive/archive_read_open_filename.c	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_open_filename.c	Fri A=
ug 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_open_f=
ilename.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_open_f=
ilename.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
@@ -130,9 +130,13 @@
 		archive_string_init(&fn);
 		if (archive_string_append_from_wcs(&fn, wfilename,
 		    wcslen(wfilename)) !=3D 0) {
-			archive_set_error(a, EINVAL,
-			    "Failed to convert a wide-character filename to"
-			    " a multi-byte filename");
+			if (errno =3D=3D ENOMEM)
+				archive_set_error(a, errno,
+				    "Can't allocate memory");
+			else
+				archive_set_error(a, EINVAL,
+				    "Failed to convert a wide-character"
+				    " filename to a multi-byte filename");
 			archive_string_free(&fn);
 			return (ARCHIVE_FATAL);
 		}
@@ -450,7 +454,7 @@
 file_seek(struct archive *a, void *client_data, int64_t request, int whenc=
e)
 {
 	struct read_file_data *mine =3D (struct read_file_data *)client_data;
-	off_t r;
+	int64_t r;
=20
 	/* We use off_t here because lseek() is declared that way. */
 	/* See above for notes about when off_t is less than 64 bits. */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_private.h
--- a/head/contrib/libarchive/libarchive/archive_read_private.h	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_private.h	Fri Aug 10 =
14:19:25 2012 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive/archive_read_private.h 232=
153 2012-02-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_read_private.h 238=
856 2012-07-28 06:38:44Z mm $
  */
=20
 #ifndef __LIBARCHIVE_BUILD
@@ -134,8 +134,8 @@
=20
 	/* Dev/ino of the archive being read/written. */
 	int		  skip_file_set;
-	dev_t		  skip_file_dev;
-	ino_t		  skip_file_ino;
+	int64_t		  skip_file_dev;
+	int64_t		  skip_file_ino;
=20
 	/*
 	 * Used by archive_read_data() to track blocks and copy
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_set_options.3
--- a/head/contrib/libarchive/libarchive/archive_read_set_options.3	Mon Jul=
 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_set_options.3	Fri Aug=
 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 13, 2009
+.Dd February 2, 2012
 .Dt ARCHIVE_READ_OPTIONS 3
 .Os
 .Sh NAME
@@ -34,6 +34,8 @@
 .Nm archive_read_set_options
 .Nd functions controlling options for reading archives
 .\"
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .Ft int
 .Fo archive_read_set_filter_option
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_filter_rpm.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_filter_rpm.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_filter_rpm.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -188,7 +188,7 @@
 			if (rpm->total_in + avail_in < RPM_LEAD_SIZE)
 				used +=3D avail_in;
 			else {
-				n =3D RPM_LEAD_SIZE - rpm->total_in;
+				n =3D (size_t)(RPM_LEAD_SIZE - rpm->total_in);
 				used +=3D n;
 				b +=3D n;
 				rpm->state =3D ST_HEADER;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_7zip.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c=
	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c=
	Fri Aug 10 14:19:25 2012 +0300
@@ -580,7 +580,7 @@
 		free_Header(&header);
 		if (r !=3D ARCHIVE_OK)
 			return (r);
-		zip->entries_remaining =3D zip->numFiles;
+		zip->entries_remaining =3D (size_t)zip->numFiles;
 		zip->entry =3D zip->entries;
 	} else {
 		++zip->entry;
@@ -653,19 +653,24 @@
 		 */
 		while (zip->entry_bytes_remaining > 0) {
 			const void *buff;
+			unsigned char *mem;
 			size_t size;
 			int64_t offset;
=20
 			r =3D archive_read_format_7zip_read_data(a, &buff,
 				&size, &offset);
-			if (r < ARCHIVE_WARN)
+			if (r < ARCHIVE_WARN) {
+				free(symname);
 				return (r);
-			symname =3D realloc(symname, symsize + size + 1);
-			if (symname =3D=3D NULL) {
+			}
+			mem =3D realloc(symname, symsize + size + 1);
+			if (mem =3D=3D NULL) {
+				free(symname);
 				archive_set_error(&a->archive, ENOMEM,
 				    "Can't allocate memory for Symname");
 				return (ARCHIVE_FATAL);
 			}
+			symname =3D mem;
 			memcpy(symname+symsize, buff, size);
 			symsize +=3D size;
 		}
@@ -715,7 +720,8 @@
 		return (ARCHIVE_EOF);
 	}
=20
-	bytes =3D read_stream(a, buff, zip->entry_bytes_remaining, 0);
+	bytes =3D read_stream(a, buff,
+		(size_t)zip->entry_bytes_remaining, 0);
 	if (bytes < 0)
 		return ((int)bytes);
 	if (bytes =3D=3D 0) {
@@ -773,7 +779,7 @@
 	 * If the length is at the beginning, we can skip the
 	 * compressed data much more quickly.
 	 */
-	bytes_skipped =3D skip_stream(a, zip->entry_bytes_remaining);
+	bytes_skipped =3D skip_stream(a, (size_t)zip->entry_bytes_remaining);
 	if (bytes_skipped < 0)
 		return (ARCHIVE_FATAL);
 	zip->entry_bytes_remaining =3D 0;
@@ -1053,7 +1059,7 @@
 		ff =3D &filters[fi];
 #endif
 		r =3D lzma_properties_decode(&filters[fi], NULL,
-		    coder1->properties, coder1->propertiesSize);
+		    coder1->properties, (size_t)coder1->propertiesSize);
 		if (r !=3D LZMA_OK) {
 			set_error(a, r);
 			return (ARCHIVE_FAILED);
@@ -1441,8 +1447,8 @@
 		} while (zip->ppstream.avail_out &&
 			(zip->ppstream.avail_in || flush_bytes));
=20
-		t_avail_in =3D zip->ppstream.avail_in;
-		t_avail_out =3D zip->ppstream.avail_out;
+		t_avail_in =3D (size_t)zip->ppstream.avail_in;
+		t_avail_out =3D (size_t)zip->ppstream.avail_out;
 		break;
 	}
 	default:
@@ -1505,6 +1511,10 @@
 {
 	int r =3D ARCHIVE_OK;
=20
+#if !defined(HAVE_ZLIB_H) &&\
+	!(defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR))
+	(void)a;/* UNUSED */
+#endif
 #ifdef HAVE_LZMA_H
 	if (zip->lzstream_valid)
 		lzma_end(&(zip->lzstream));
@@ -1671,8 +1681,8 @@
 		return (0);
 	if (*p !=3D kSize)
 		return (-1);
-	pi->sizes =3D calloc(pi->numPackStreams, sizeof(uint64_t));
-	pi->positions =3D calloc(pi->numPackStreams, sizeof(uint64_t));
+	pi->sizes =3D calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
+	pi->positions =3D calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
 	if (pi->sizes =3D=3D NULL || pi->positions =3D=3D NULL)
 		return (-1);
=20
@@ -1689,9 +1699,9 @@
 	if (*p =3D=3D kEnd) {
 		/* PackStreamDigests[num] are not present. */
 		pi->digest.defineds =3D
-		    calloc(pi->numPackStreams, sizeof(*pi->digest.defineds));
+		    calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.defineds));
 		pi->digest.digests =3D
-		    calloc(pi->numPackStreams, sizeof(*pi->digest.digests));
+		    calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.digests));
 		if (pi->digest.defineds =3D=3D NULL || pi->digest.digests =3D=3D NULL)
 			return (-1);
 		return (0);
@@ -1700,7 +1710,7 @@
 	if (*p !=3D kSize)
 		return (-1);
=20
-	if (read_Digests(a, &(pi->digest), pi->numPackStreams) < 0)
+	if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
 		return (-1);
=20
 	/*
@@ -1749,7 +1759,7 @@
 		/* Too many coders. */
 		return (-1);
=20
-	f->coders =3D calloc(f->numCoders, sizeof(*f->coders));
+	f->coders =3D calloc((size_t)f->numCoders, sizeof(*f->coders));
 	if (f->coders =3D=3D NULL)
 		return (-1);
 	for (i =3D 0; i< f->numCoders; i++) {
@@ -1801,14 +1811,14 @@
 			    a, &(f->coders[i].propertiesSize)) < 0)
 				return (-1);
 			if ((p =3D header_bytes(
-			    a, f->coders[i].propertiesSize)) =3D=3D NULL)
+			    a, (size_t)f->coders[i].propertiesSize)) =3D=3D NULL)
 				return (-1);
 			f->coders[i].properties =3D
-			    malloc(f->coders[i].propertiesSize);
+			    malloc((size_t)f->coders[i].propertiesSize);
 			if (f->coders[i].properties =3D=3D NULL)
 				return (-1);
 			memcpy(f->coders[i].properties, p,
-			    f->coders[i].propertiesSize);
+			    (size_t)f->coders[i].propertiesSize);
 		}
=20
 		numInStreamsTotal +=3D f->coders[i].numInStreams;
@@ -1822,9 +1832,13 @@
 	f->numBindPairs =3D numOutStreamsTotal - 1;
 	if (zip->header_bytes_remaining < f->numBindPairs)
 			return (-1);
-	f->bindPairs =3D calloc(f->numBindPairs, sizeof(*f->bindPairs));
-	if (f->bindPairs =3D=3D NULL)
-		return (-1);
+	if (f->numBindPairs > 0) {
+		f->bindPairs =3D
+			calloc((size_t)f->numBindPairs, sizeof(*f->bindPairs));
+		if (f->bindPairs =3D=3D NULL)
+			return (-1);
+	} else
+		f->bindPairs =3D NULL;
 	for (i =3D 0; i < f->numBindPairs; i++) {
 		if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
 			return (-1);
@@ -1838,7 +1852,7 @@
=20
 	f->numPackedStreams =3D numInStreamsTotal - f->numBindPairs;
 	f->packedStreams =3D
-	    calloc(f->numPackedStreams, sizeof(*f->packedStreams));
+	    calloc((size_t)f->numPackedStreams, sizeof(*f->packedStreams));
 	if (f->packedStreams =3D=3D NULL)
 		return (-1);
 	if (f->numPackedStreams =3D=3D 1) {
@@ -1910,7 +1924,8 @@
 		goto failed;
 	switch (*p) {
 	case 0:
-		ci->folders =3D calloc(ci->numFolders, sizeof(*ci->folders));
+		ci->folders =3D
+			calloc((size_t)ci->numFolders, sizeof(*ci->folders));
 		if (ci->folders =3D=3D NULL)
 			return (-1);
 		for (i =3D 0; i < ci->numFolders; i++) {
@@ -1936,7 +1951,7 @@
 		unsigned j;
=20
 		folder->unPackSize =3D
-		    calloc(folder->numOutStreams, sizeof(*folder->unPackSize));
+		    calloc((size_t)folder->numOutStreams, sizeof(*folder->unPackSize));
 		if (folder->unPackSize =3D=3D NULL)
 			goto failed;
 		for (j =3D 0; j < folder->numOutStreams; j++) {
@@ -1954,7 +1969,7 @@
 		return (0);
 	if (*p !=3D kCRC)
 		goto failed;
-	if (read_Digests(a, &digest, ci->numFolders) < 0)
+	if (read_Digests(a, &digest, (size_t)ci->numFolders) < 0)
 		goto failed;
 	for (i =3D 0; i < ci->numFolders; i++) {
 		ci->folders[i].digest_defined =3D digest.defineds[i];
@@ -1978,8 +1993,8 @@
 static uint64_t
 folder_uncompressed_size(struct _7z_folder *f)
 {
-	int n =3D f->numOutStreams;
-	unsigned pairs =3D f->numBindPairs;
+	int n =3D (int)f->numOutStreams;
+	unsigned pairs =3D (unsigned)f->numBindPairs;
=20
 	while (--n >=3D 0) {
 		unsigned i;
@@ -2028,7 +2043,7 @@
 				return (-1);
 			if (1000000 < f[i].numUnpackStreams)
 				return (-1);
-			unpack_streams +=3D f[i].numUnpackStreams;
+			unpack_streams +=3D (size_t)f[i].numUnpackStreams;
 		}
 		if ((p =3D header_bytes(a, 1)) =3D=3D NULL)
 			return (-1);
@@ -2082,7 +2097,7 @@
 	numDigests =3D 0;
 	for (i =3D 0; i < numFolders; i++) {
 		if (f[i].numUnpackStreams !=3D 1 || !f[i].digest_defined)
-			numDigests +=3D f[i].numUnpackStreams;
+			numDigests +=3D (uint32_t)f[i].numUnpackStreams;
 	}
=20
 	if (type =3D=3D kCRC) {
@@ -2180,7 +2195,7 @@
 		f =3D si->ci.folders;
 		for (i =3D 0; i < si->ci.numFolders; i++) {
 			f[i].packIndex =3D packIndex;
-			packIndex +=3D f[i].numPackedStreams;
+			packIndex +=3D (uint32_t)f[i].numPackedStreams;
 			if (packIndex > si->pi.numPackStreams)
 				return (-1);
 		}
@@ -2190,7 +2205,7 @@
=20
 	if (*p =3D=3D kSubStreamsInfo) {
 		if (read_SubStreamsInfo(a, &(si->ss),
-		    si->ci.folders, si->ci.numFolders) < 0)
+		    si->ci.folders, (size_t)si->ci.numFolders) < 0)
 			return (-1);
 		if ((p =3D header_bytes(a, 1)) =3D=3D NULL)
 			return (-1);
@@ -2278,7 +2293,7 @@
 	if (1000000 < zip->numFiles)
 			return (-1);
=20
-	zip->entries =3D calloc(zip->numFiles, sizeof(*zip->entries));
+	zip->entries =3D calloc((size_t)zip->numFiles, sizeof(*zip->entries));
 	if (zip->entries =3D=3D NULL)
 		return (-1);
 	entries =3D zip->entries;
@@ -2303,12 +2318,12 @@
=20
 		switch (type) {
 		case kEmptyStream:
-			h->emptyStreamBools =3D calloc(zip->numFiles,
+			h->emptyStreamBools =3D calloc((size_t)zip->numFiles,
 			    sizeof(*h->emptyStreamBools));
 			if (h->emptyStreamBools =3D=3D NULL)
 				return (-1);
 			if (read_Bools(
-			    a, h->emptyStreamBools, zip->numFiles) < 0)
+			    a, h->emptyStreamBools, (size_t)zip->numFiles) < 0)
 				return (-1);
 			empty_streams =3D 0;
 			for (i =3D 0; i < zip->numFiles; i++) {
@@ -2317,6 +2332,12 @@
 			}
 			break;
 		case kEmptyFile:
+			if (empty_streams <=3D 0) {
+				/* Unexcepted sequence. Skip this. */
+				if (header_bytes(a, ll) =3D=3D NULL)
+					return (-1);
+				break;
+			}
 			h->emptyFileBools =3D calloc(empty_streams,
 			    sizeof(*h->emptyFileBools));
 			if (h->emptyFileBools =3D=3D NULL)
@@ -2325,6 +2346,12 @@
 				return (-1);
 			break;
 		case kAnti:
+			if (empty_streams <=3D 0) {
+				/* Unexcepted sequence. Skip this. */
+				if (header_bytes(a, ll) =3D=3D NULL)
+					return (-1);
+				break;
+			}
 			h->antiBools =3D calloc(empty_streams,
 			    sizeof(*h->antiBools));
 			if (h->antiBools =3D=3D NULL)
@@ -2403,15 +2430,15 @@
 			if ((p =3D header_bytes(a, 2)) =3D=3D NULL)
 				return (-1);
 			allAreDefined =3D *p;
-			h->attrBools =3D calloc(zip->numFiles,
+			h->attrBools =3D calloc((size_t)zip->numFiles,
 			    sizeof(*h->attrBools));
 			if (h->attrBools =3D=3D NULL)
 				return (-1);
 			if (allAreDefined)
-				memset(h->attrBools, 1, zip->numFiles);
+				memset(h->attrBools, 1, (size_t)zip->numFiles);
 			else {
 				if (read_Bools(a, h->attrBools,
-				      zip->numFiles) < 0)
+				      (size_t)zip->numFiles) < 0)
 					return (-1);
 			}
 			for (i =3D 0; i < zip->numFiles; i++) {
@@ -2445,7 +2472,7 @@
 			if ((size_t)sindex >=3D si->ss.unpack_streams)
 				return (-1);
 			if (entries[i].mode =3D=3D 0)
-				entries[i].mode =3D AE_IFREG | 0777;
+				entries[i].mode =3D AE_IFREG | 0666;
 			if (si->ss.digestsDefined[sindex])
 				entries[i].flg |=3D CRC32_IS_SET;
 			entries[i].ssIndex =3D sindex;
@@ -2465,7 +2492,7 @@
 				if (dir)
 					entries[i].mode =3D AE_IFDIR | 0777;
 				else
-					entries[i].mode =3D AE_IFREG | 0777;
+					entries[i].mode =3D AE_IFREG | 0666;
 			} else if (dir &&
 			    (entries[i].mode & AE_IFMT) !=3D AE_IFDIR) {
 				entries[i].mode &=3D ~AE_IFMT;
@@ -2541,7 +2568,7 @@
 	int allAreDefined;
 	unsigned i;
=20
-	timeBools =3D calloc(zip->numFiles, sizeof(*timeBools));
+	timeBools =3D calloc((size_t)zip->numFiles, sizeof(*timeBools));
 	if (timeBools =3D=3D NULL)
 		return (-1);
=20
@@ -2550,9 +2577,9 @@
 		goto failed;
 	allAreDefined =3D *p;
 	if (allAreDefined)
-		memset(timeBools, 1, zip->numFiles);
+		memset(timeBools, 1, (size_t)zip->numFiles);
 	else {
-		if (read_Bools(a, timeBools, zip->numFiles) < 0)
+		if (read_Bools(a, timeBools, (size_t)zip->numFiles) < 0)
 			goto failed;
 	}
=20
@@ -2563,7 +2590,7 @@
 		if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
 			goto failed;
 		if (1000000 < h->dataIndex)
-			return (-1);
+			goto failed;
 	}
=20
 	for (i =3D 0; i < zip->numFiles; i++) {
@@ -2897,10 +2924,10 @@
 			return (ARCHIVE_FATAL);
 		}
 		if (bytes_avail > (ssize_t)zip->pack_stream_inbytes_remaining)
-			bytes_avail =3D zip->pack_stream_inbytes_remaining;
+			bytes_avail =3D (ssize_t)zip->pack_stream_inbytes_remaining;
 		zip->pack_stream_inbytes_remaining -=3D bytes_avail;
 		if (bytes_avail > (ssize_t)zip->folder_outbytes_remaining)
-			bytes_avail =3D zip->folder_outbytes_remaining;
+			bytes_avail =3D (ssize_t)zip->folder_outbytes_remaining;
 		zip->folder_outbytes_remaining -=3D bytes_avail;
 		zip->uncompressed_buffer_bytes_remaining =3D bytes_avail;
 		return (ARCHIVE_OK);
@@ -2965,7 +2992,7 @@
 		size_t bytes_in, bytes_out;
 		const void *buff_in;
 		unsigned char *buff_out;
-		int eof;
+		int end_of_data;
=20
 		/*
 		 * Note: '1' here is a performance optimization.
@@ -2987,23 +3014,23 @@
 			- zip->uncompressed_buffer_bytes_remaining;
 		bytes_in =3D bytes_avail;
 		if (bytes_in > zip->pack_stream_inbytes_remaining)
-			bytes_in =3D zip->pack_stream_inbytes_remaining;
+			bytes_in =3D (size_t)zip->pack_stream_inbytes_remaining;
 		/* Drive decompression. */
 		r =3D decompress(a, zip, buff_out, &bytes_out,
 			buff_in, &bytes_in);
 		switch (r) {
 		case ARCHIVE_OK:
-			eof =3D 0;
+			end_of_data =3D 0;
 			break;
 		case ARCHIVE_EOF:
-			eof =3D 1;
+			end_of_data =3D 1;
 			break;
 		default:
 			return (ARCHIVE_FATAL);
 		}
 		zip->pack_stream_inbytes_remaining -=3D bytes_in;
 		if (bytes_out > zip->folder_outbytes_remaining)
-			bytes_out =3D zip->folder_outbytes_remaining;
+			bytes_out =3D (size_t)zip->folder_outbytes_remaining;
 		zip->folder_outbytes_remaining -=3D bytes_out;
 		zip->uncompressed_buffer_bytes_remaining +=3D bytes_out;
 		zip->pack_stream_bytes_unconsumed =3D bytes_in;
@@ -3021,7 +3048,7 @@
 		if (zip->pack_stream_inbytes_remaining =3D=3D 0 &&
 		    zip->folder_outbytes_remaining =3D=3D 0)
 			break;
-		if (eof || (bytes_in =3D=3D 0 && bytes_out =3D=3D 0)) {
+		if (end_of_data || (bytes_in =3D=3D 0 && bytes_out =3D=3D 0)) {
 			archive_set_error(&(a->archive),
 			    ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
 			return (ARCHIVE_FATAL);
@@ -3160,7 +3187,8 @@
 				return (ARCHIVE_FATAL);
 			}
 		}
-		skipped =3D get_uncompressed_data(a, buff, skip_bytes, 0);
+		skipped =3D get_uncompressed_data(
+			a, buff, (size_t)skip_bytes, 0);
 		if (skipped < 0)
 			return (skipped);
 		skip_bytes -=3D skipped;
@@ -3292,13 +3320,13 @@
 			}
 			coder2 =3D &(fc[3]);
 			zip->main_stream_bytes_remaining =3D
-				folder->unPackSize[2];
+				(size_t)folder->unPackSize[2];
 		} else if (coder2 !=3D NULL && coder2->codec =3D=3D _7Z_X86_BCJ2 &&
 		    zip->pack_stream_remaining =3D=3D 4 &&
 		    folder->numInStreams =3D=3D 5 && folder->numOutStreams =3D=3D 2) {
 			/* Source type 0 made by 7z */
 			zip->main_stream_bytes_remaining =3D
-				folder->unPackSize[0];
+				(size_t)folder->unPackSize[0];
 		} else {
 			/* We got an unexpected form. */
 			archive_set_error(&(a->archive),
@@ -3311,7 +3339,7 @@
 		if ((r =3D seek_pack(a)) < 0)
 			return (r);
 		zip->pack_stream_bytes_unconsumed =3D
-		    zip->pack_stream_inbytes_remaining;
+		    (size_t)zip->pack_stream_inbytes_remaining;
 		read_consume(a);
=20
 		/* Read following three sub streams. */
@@ -3333,7 +3361,7 @@
=20
 			/* Allocate memory for the decorded data of a sub
 			 * stream. */
-			b[i] =3D malloc(zip->folder_outbytes_remaining);
+			b[i] =3D malloc((size_t)zip->folder_outbytes_remaining);
 			if (b[i] =3D=3D NULL) {
 				archive_set_error(&a->archive, ENOMEM,
 				    "No memory for 7-Zip decompression");
@@ -3428,7 +3456,7 @@
 			    "Truncated 7-Zip file body");
 			return (ARCHIVE_FATAL);
 		}
-		bytes -=3D skipped_bytes;
+		bytes -=3D (size_t)skipped_bytes;
 		if (zip->pack_stream_bytes_unconsumed)
 			read_consume(a);
 	}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_cab.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_cab.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_cab.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -292,6 +292,8 @@
 	char			 end_of_archive;
 	char			 end_of_entry;
 	char			 end_of_entry_cleanup;
+	char			 read_data_invoked;
+	int64_t			 bytes_skipped;
=20
 	unsigned char		*uncompressed_buffer;
 	size_t			 uncompressed_buffer_size;
@@ -798,7 +800,7 @@
 		file->offset =3D archive_le32dec(p + CFFILE_uoffFolderStart);
 		file->folder =3D archive_le16dec(p + CFFILE_iFolder);
 		file->mtime =3D cab_dos_time(p + CFFILE_date_time);
-		file->attr =3D archive_le16dec(p + CFFILE_attribs);
+		file->attr =3D (uint8_t)archive_le16dec(p + CFFILE_attribs);
 		__archive_read_consume(a, 16);
=20
 		cab->cab_offset +=3D 16;
@@ -988,7 +990,7 @@
 	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_mode(entry, AE_IFREG | 0666);
 	archive_entry_set_mtime(entry, file->mtime, 0);
=20
 	cab->entry_bytes_remaining =3D file->uncompressed_size;
@@ -1026,9 +1028,22 @@
 	default:
 		break;
 	}
+	if (cab->read_data_invoked =3D=3D 0) {
+		if (cab->bytes_skipped) {
+			if (cab->entry_cfdata =3D=3D NULL) {
+				r =3D cab_next_cfdata(a);
+				if (r < 0)
+					return (r);
+			}
+			if (cab_consume_cfdata(a, cab->bytes_skipped) < 0)
+				return (ARCHIVE_FATAL);
+			cab->bytes_skipped =3D 0;
+		}
+		cab->read_data_invoked =3D 1;
+	}
 	if (cab->entry_unconsumed) {
 		/* Consume as much as the compressor actually used. */
-		r =3D cab_consume_cfdata(a, cab->entry_unconsumed);
+		r =3D (int)cab_consume_cfdata(a, cab->entry_unconsumed);
 		cab->entry_unconsumed =3D 0;
 		if (r < 0)
 			return (r);
@@ -1358,46 +1373,25 @@
 	struct cab *cab =3D (struct cab *)(a->format->data);
 	struct cfdata *cfdata;
 	const void *d;
-	int64_t skipped_bytes;
=20
 	cfdata =3D cab->entry_cfdata;
=20
-	if (cfdata->uncompressed_avail =3D=3D 0 &&
-		cfdata->read_offset > 0) {
-		/* we've already skipped some bytes before really read. */
-		skipped_bytes =3D cfdata->read_offset;
-		cfdata->read_offset =3D 0;
-		cfdata->uncompressed_bytes_remaining +=3D skipped_bytes;
-	} else
-		skipped_bytes =3D 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 =3D __archive_read_ahead(a, 1, avail);
-		if (*avail <=3D 0) {
-			*avail =3D truncated_error(a);
-			return (NULL);
-		}
-		if (*avail > cfdata->uncompressed_bytes_remaining)
-			*avail =3D cfdata->uncompressed_bytes_remaining;
-		cfdata->uncompressed_avail =3D cfdata->uncompressed_size;
-		cfdata->unconsumed =3D *avail;
-		cfdata->sum_ptr =3D d;
-		if (skipped_bytes > 0) {
-			skipped_bytes =3D
-			    cab_minimum_consume_cfdata(a, skipped_bytes);
-			if (skipped_bytes < 0) {
-				*avail =3D ARCHIVE_FATAL;
-				return (NULL);
-			}
-			continue;
-		}
-	} while (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.
+	 */
+	d =3D __archive_read_ahead(a, 1, avail);
+	if (*avail <=3D 0) {
+		*avail =3D truncated_error(a);
+		return (NULL);
+	}
+	if (*avail > cfdata->uncompressed_bytes_remaining)
+		*avail =3D cfdata->uncompressed_bytes_remaining;
+	cfdata->uncompressed_avail =3D cfdata->uncompressed_size;
+	cfdata->unconsumed =3D *avail;
+	cfdata->sum_ptr =3D d;
 	return (d);
 }
=20
@@ -1543,7 +1537,7 @@
 			return (NULL);
 		}
 	}
-	uavail =3D cab->stream.total_out;
+	uavail =3D (uint16_t)cab->stream.total_out;
=20
 	if (uavail < cfdata->uncompressed_size) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1721,7 +1715,7 @@
 		}
 	}
=20
-	uavail =3D cab->xstrm.total_out;
+	uavail =3D (uint16_t)cab->xstrm.total_out;
 	/*
 	 * Make sure a read pointer advances to next CFDATA.
 	 */
@@ -1793,9 +1787,8 @@
 		rbytes -=3D cbytes;
=20
 		if (cfdata->uncompressed_avail =3D=3D 0 &&
-		    (cab->entry_cffolder->comptype =3D=3D COMPTYPE_NONE ||
-		     cab->entry_cffile->folder =3D=3D iFoldCONTINUED_PREV_AND_NEXT ||
-			 cab->entry_cffile->folder =3D=3D iFoldCONTINUED_FROM_PREV)) {
+		   (cab->entry_cffile->folder =3D=3D iFoldCONTINUED_PREV_AND_NEXT ||
+		    cab->entry_cffile->folder =3D=3D iFoldCONTINUED_FROM_PREV)) {
 			/* We have not read any data yet. */
 			if (cbytes =3D=3D cfdata->uncompressed_bytes_remaining) {
 				/* Skip whole current CFDATA. */
@@ -1821,8 +1814,8 @@
 				}
 				continue;
 			}
-			cfdata->read_offset +=3D cbytes;
-			cfdata->uncompressed_bytes_remaining -=3D cbytes;
+			cfdata->read_offset +=3D (uint16_t)cbytes;
+			cfdata->uncompressed_bytes_remaining -=3D (uint16_t)cbytes;
 			break;
 		} else if (cbytes =3D=3D 0) {
 			err =3D cab_next_cfdata(a);
@@ -1846,7 +1839,7 @@
 			if (avail <=3D 0)
 				return (ARCHIVE_FATAL);
 			if (avail > cbytes)
-				avail =3D cbytes;
+				avail =3D (ssize_t)cbytes;
 			if (cab_minimum_consume_cfdata(a, avail) < 0)
 				return (ARCHIVE_FATAL);
 			cbytes -=3D avail;
@@ -1875,8 +1868,8 @@
 		else
 			cbytes =3D cfdata->unconsumed;
 		rbytes -=3D cbytes;=20
-		cfdata->read_offset +=3D cbytes;
-		cfdata->uncompressed_bytes_remaining -=3D cbytes;
+		cfdata->read_offset +=3D (uint16_t)cbytes;
+		cfdata->uncompressed_bytes_remaining -=3D (uint16_t)cbytes;
 		cfdata->unconsumed -=3D cbytes;
 	} else {
 		cbytes =3D cfdata->uncompressed_avail - cfdata->read_offset;
@@ -1884,8 +1877,8 @@
 			if (consumed_bytes < cbytes)
 				cbytes =3D consumed_bytes;
 			rbytes -=3D cbytes;
-			cfdata->read_offset +=3D cbytes;
-			cfdata->uncompressed_bytes_remaining -=3D cbytes;
+			cfdata->read_offset +=3D (uint16_t)cbytes;
+			cfdata->uncompressed_bytes_remaining -=3D (uint16_t)cbytes;
 		}
=20
 		if (cfdata->unconsumed) {
@@ -1896,12 +1889,12 @@
 	}
 	if (cbytes) {
 		/* Compute the sum. */
-		cab_checksum_update(a, cbytes);
+		cab_checksum_update(a, (size_t)cbytes);
=20
 		/* Consume as much as the compressor actually used. */
 		__archive_read_consume(a, cbytes);
 		cab->cab_offset +=3D cbytes;
-		cfdata->compressed_bytes_remaining -=3D cbytes;
+		cfdata->compressed_bytes_remaining -=3D (uint16_t)cbytes;
 		if (cfdata->compressed_bytes_remaining =3D=3D 0) {
 			err =3D cab_checksum_finish(a);
 			if (err < 0)
@@ -1945,7 +1938,7 @@
 			return (bytes_avail);
 	}
 	if (bytes_avail > cab->entry_bytes_remaining)
-		bytes_avail =3D cab->entry_bytes_remaining;
+		bytes_avail =3D (ssize_t)cab->entry_bytes_remaining;
=20
 	*size =3D bytes_avail;
 	*offset =3D cab->entry_offset;
@@ -1954,6 +1947,11 @@
 	if (cab->entry_bytes_remaining =3D=3D 0)
 		cab->end_of_entry =3D 1;
 	cab->entry_unconsumed =3D bytes_avail;
+	if (cab->entry_cffolder->comptype =3D=3D COMPTYPE_NONE) {
+		/* Don't consume more than current entry used. */
+		if (cab->entry_cfdata->unconsumed > cab->entry_unconsumed)
+			cab->entry_cfdata->unconsumed =3D cab->entry_unconsumed;
+	}
 	return (ARCHIVE_OK);
 }
=20
@@ -1969,9 +1967,17 @@
 	if (cab->end_of_archive)
 		return (ARCHIVE_EOF);
=20
+	if (!cab->read_data_invoked) {
+		cab->bytes_skipped +=3D cab->entry_bytes_remaining;
+		cab->entry_bytes_remaining =3D 0;
+		/* This entry is finished and done. */
+		cab->end_of_entry_cleanup =3D cab->end_of_entry =3D 1;
+		return (ARCHIVE_OK);
+	}
+
 	if (cab->entry_unconsumed) {
 		/* Consume as much as the compressor actually used. */
-		r =3D cab_consume_cfdata(a, cab->entry_unconsumed);
+		r =3D (int)cab_consume_cfdata(a, cab->entry_unconsumed);
 		cab->entry_unconsumed =3D 0;
 		if (r < 0)
 			return (r);
@@ -1993,6 +1999,11 @@
 	if (bytes_skipped < 0)
 		return (ARCHIVE_FATAL);
=20
+	/* If the compression type is none(uncompressed), we've already
+	 * consumed data as much as the current entry size. */
+	if (cab->entry_cffolder->comptype =3D=3D COMPTYPE_NONE)
+		cab->entry_cfdata->unconsumed =3D 0;
+
 	/* This entry is finished and done. */
 	cab->end_of_entry_cleanup =3D cab->end_of_entry =3D 1;
 	return (ARCHIVE_OK);
@@ -2227,7 +2238,9 @@
=20
 /* Notify how many bits we consumed. */
 #define lzx_br_consume(br, n)	((br)->cache_avail -=3D (n))
-#define lzx_br_consume_unalined_bits(br) ((br)->cache_avail &=3D ~0x0f)
+#define lzx_br_consume_unaligned_bits(br) ((br)->cache_avail &=3D ~0x0f)
+
+#define lzx_br_is_unaligned(br)	((br)->cache_avail & 0x0f)
=20
 static const uint32_t cache_masks[] =3D {
 	0x00000000, 0x00000001, 0x00000003, 0x00000007,
@@ -2354,24 +2367,25 @@
 #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
+#define ST_RD_ALIGNMENT		4
+#define ST_RD_R0		5
+#define ST_RD_R1		6
+#define ST_RD_R2		7
+#define ST_COPY_UNCOMP1		8
+#define ST_COPY_UNCOMP2		9
+#define ST_RD_ALIGNED_OFFSET	10
+#define ST_RD_VERBATIM		11
+#define ST_RD_PRE_MAIN_TREE_256	12
+#define ST_MAIN_TREE_256	13
+#define ST_RD_PRE_MAIN_TREE_REM	14
+#define ST_MAIN_TREE_REM	15
+#define ST_RD_PRE_LENGTH_TREE	16
+#define ST_LENGTH_TREE		17
+#define ST_MAIN			18
+#define ST_LENGTH		19
+#define ST_OFFSET		20
+#define ST_REAL_POS		21
+#define ST_COPY			22
=20
 static int
 lzx_decode(struct lzx_stream *strm, int last)
@@ -2475,15 +2489,25 @@
 					ds->state =3D ST_RD_ALIGNED_OFFSET;
 				break;
 			}
+			/* FALL THROUGH */
+		case ST_RD_ALIGNMENT:
 			/*
 			 * Handle an Uncompressed Block.
 			 */
 			/* Skip padding to align following field on
 			 * 16-bit boundary. */
-			if (br->cache_avail =3D=3D 32 || br->cache_avail =3D=3D 16)
-				lzx_br_consume(br, 16);
-			else
-				lzx_br_consume_unalined_bits(br);
+			if (lzx_br_is_unaligned(br))
+				lzx_br_consume_unaligned_bits(br);
+			else {
+				if (lzx_br_read_ahead(strm, br, 16))
+					lzx_br_consume(br, 16);
+				else {
+					ds->state =3D ST_RD_ALIGNMENT;
+					if (last)
+						goto failed;
+					return (ARCHIVE_OK);
+				}
+			}
 			/* Preparation to read repeated offsets R0,R1 and R2. */
 			ds->rbytes_avail =3D 0;
 			ds->state =3D ST_RD_R0;
@@ -2508,8 +2532,7 @@
 					lzx_br_consume(br, 16);
 					archive_le16enc(ds->rbytes, u16);
 					ds->rbytes_avail =3D 2;
-				} else
-					ds->rbytes_avail =3D 0;
+				}
 				if (ds->rbytes_avail < 4 && ds->br.have_odd) {
 					ds->rbytes[ds->rbytes_avail++] =3D
 					    ds->br.odd;
@@ -2525,6 +2548,7 @@
 					    *strm->next_in++;
 					strm->avail_in--;
 				}
+				ds->rbytes_avail =3D 0;
 				if (ds->state =3D=3D ST_RD_R0) {
 					ds->r0 =3D archive_le32dec(ds->rbytes);
 					if (ds->r0 < 0)
@@ -2549,8 +2573,7 @@
 			 * Copy bytes form next_in to next_out directly.
 			 */
 			while (ds->block_bytes_avail) {
-				unsigned char *d;
-				int l,ll;
+				int l;
=20
 				if (strm->avail_out <=3D 0)
 					/* Output buffer is empty. */
@@ -2568,17 +2591,16 @@
 					l =3D (int)strm->avail_out;
 				if (l > strm->avail_in)
 					l =3D (int)strm->avail_in;
-				ll =3D l;
-				d =3D &(ds->w_buff[ds->w_pos]);
-				while (--l >=3D 0) {
-					*strm->next_out++ =3D *strm->next_in;
-					*d++ =3D *strm->next_in++;
-				}
-				strm->avail_out -=3D ll;
-				strm->total_out +=3D ll;
-				strm->avail_in -=3D ll;
-				ds->w_pos =3D (ds->w_pos + ll) & ds->w_mask;
-				ds->block_bytes_avail -=3D ll;
+				memcpy(strm->next_out, strm->next_in, l);
+				memcpy(&(ds->w_buff[ds->w_pos]),
+				    strm->next_in, l);
+				strm->next_in +=3D l;
+				strm->avail_in -=3D l;
+				strm->next_out +=3D l;
+				strm->avail_out -=3D l;
+				strm->total_out +=3D l;
+				ds->w_pos =3D (ds->w_pos + l) & ds->w_mask;
+				ds->block_bytes_avail -=3D l;
 			}
 			/* FALL THROUGH */
 		case ST_COPY_UNCOMP2:
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_cpio.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_cpio.c=
	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_cpio.c=
	Fri Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_cpio.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_cpio.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -398,11 +398,12 @@
=20
 	/* If this is a symlink, read the link contents. */
 	if (archive_entry_filetype(entry) =3D=3D AE_IFLNK) {
-		h =3D __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL);
+		h =3D __archive_read_ahead(a,
+			(size_t)cpio->entry_bytes_remaining, NULL);
 		if (h =3D=3D NULL)
 			return (ARCHIVE_FATAL);
 		if (archive_entry_copy_symlink_l(entry, (const char *)h,
-		    cpio->entry_bytes_remaining, sconv) !=3D 0) {
+		    (size_t)cpio->entry_bytes_remaining, sconv) !=3D 0) {
 			if (errno =3D=3D ENOMEM) {
 				archive_set_error(&a->archive, ENOMEM,
 				    "Can't allocate memory for Linkname");
@@ -458,7 +459,7 @@
 		if (bytes_read <=3D 0)
 			return (ARCHIVE_FATAL);
 		if (bytes_read > cpio->entry_bytes_remaining)
-			bytes_read =3D cpio->entry_bytes_remaining;
+			bytes_read =3D (ssize_t)cpio->entry_bytes_remaining;
 		*size =3D bytes_read;
 		cpio->entry_bytes_unconsumed =3D bytes_read;
 		*offset =3D cpio->entry_offset;
@@ -603,17 +604,23 @@
 		/* TODO: Abort here? */
 	}
=20
-	archive_entry_set_devmajor(entry, atol16(header + newc_devmajor_offset, n=
ewc_devmajor_size));
-	archive_entry_set_devminor(entry, atol16(header + newc_devminor_offset, n=
ewc_devminor_size));
+	archive_entry_set_devmajor(entry,
+		(dev_t)atol16(header + newc_devmajor_offset, newc_devmajor_size));
+	archive_entry_set_devminor(entry,=20
+		(dev_t)atol16(header + newc_devminor_offset, newc_devminor_size));
 	archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_si=
ze));
-	archive_entry_set_mode(entry, atol16(header + newc_mode_offset, newc_mode=
_size));
+	archive_entry_set_mode(entry,=20
+		(mode_t)atol16(header + newc_mode_offset, newc_mode_size));
 	archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_si=
ze));
 	archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_si=
ze));
-	archive_entry_set_nlink(entry, atol16(header + newc_nlink_offset, newc_nl=
ink_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_nlink(entry,
+		(unsigned int)atol16(header + newc_nlink_offset, newc_nlink_size));
+	archive_entry_set_rdevmajor(entry,
+		(dev_t)atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size));
+	archive_entry_set_rdevminor(entry,
+		(dev_t)atol16(header + newc_rdevminor_offset, newc_rdevminor_size));
 	archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mt=
ime_size), 0);
-	*namelength =3D atol16(header + newc_namesize_offset, newc_namesize_size);
+	*namelength =3D (size_t)atol16(header + newc_namesize_offset, newc_namesi=
ze_size);
 	/* Pad name to 2 more than a multiple of 4. */
 	*name_pad =3D (2 - *namelength) & 3;
=20
@@ -767,15 +774,19 @@
 	/* Parse out octal fields. */
 	header =3D (const char *)h;
=20
-	archive_entry_set_dev(entry, atol8(header + odc_dev_offset, odc_dev_size)=
);
+	archive_entry_set_dev(entry,=20
+		(dev_t)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_si=
ze));
+	archive_entry_set_mode(entry,=20
+		(mode_t)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_si=
ze));
+	archive_entry_set_nlink(entry,=20
+		(unsigned int)atol8(header + odc_nlink_offset, odc_nlink_size));
+	archive_entry_set_rdev(entry,
+		(dev_t)atol8(header + odc_rdev_offset, odc_rdev_size));
 	archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime=
_size), 0);
-	*namelength =3D atol8(header + odc_namesize_offset, odc_namesize_size);
+	*namelength =3D (size_t)atol8(header + odc_namesize_offset, odc_namesize_=
size);
 	*name_pad =3D 0; /* No padding of filename. */
=20
 	/*
@@ -816,15 +827,19 @@
 	/* Parse out octal fields. */
 	header =3D (const char *)h;
=20
-	archive_entry_set_dev(entry, atol16(header + afiol_dev_offset, afiol_dev_=
size));
+	archive_entry_set_dev(entry,=20
+		(dev_t)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_mod=
e_size));
+	archive_entry_set_mode(entry,
+		(mode_t)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_rd=
ev_size));
+	archive_entry_set_nlink(entry,
+		(unsigned int)atol16(header + afiol_nlink_offset, afiol_nlink_size));
+	archive_entry_set_rdev(entry,
+		(dev_t)atol16(header + afiol_rdev_offset, afiol_rdev_size));
 	archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_=
mtime_size), 0);
-	*namelength =3D atol16(header + afiol_namesize_offset, afiol_namesize_siz=
e);
+	*namelength =3D (size_t)atol16(header + afiol_namesize_offset, afiol_name=
size_size);
 	*name_pad =3D 0; /* No padding of filename. */
=20
 	cpio->entry_bytes_remaining =3D
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_iso9660.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_iso966=
0.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_iso966=
0.c	Fri Aug 10 14:19:25 2012 +0300
@@ -26,7 +26,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_iso9660.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_iso9660.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -975,8 +975,8 @@
 		iso9660->current_position =3D parent->offset;
 	}
=20
-	step =3D ((parent->size + iso9660->logical_block_size -1) /
-	    iso9660->logical_block_size) * iso9660->logical_block_size;
+	step =3D (size_t)(((parent->size + iso9660->logical_block_size -1) /
+	    iso9660->logical_block_size) * iso9660->logical_block_size);
 	b =3D __archive_read_ahead(a, step, NULL);
 	if (b =3D=3D NULL) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1397,7 +1397,7 @@
 		return (ARCHIVE_FATAL);
 	}
 	if (bytes_read > iso9660->entry_bytes_remaining)
-		bytes_read =3D iso9660->entry_bytes_remaining;
+		bytes_read =3D (ssize_t)iso9660->entry_bytes_remaining;
 	avail =3D bytes_read;
 	uncompressed_size =3D 0;
=20
@@ -1405,9 +1405,9 @@
 		size_t ceil, xsize;
=20
 		/* Allocate block pointers buffer. */
-		ceil =3D (zisofs->pz_uncompressed_size +
-			(1LL << zisofs->pz_log2_bs) - 1)
-			>> zisofs->pz_log2_bs;
+		ceil =3D (size_t)((zisofs->pz_uncompressed_size +
+			(((int64_t)1) << zisofs->pz_log2_bs) - 1)
+			>> zisofs->pz_log2_bs);
 		xsize =3D (ceil + 1) * 4;
 		if (zisofs->block_pointers_alloc < xsize) {
 			size_t alloc;
@@ -1671,7 +1671,7 @@
 	if (*buff =3D=3D NULL)
 		return (ARCHIVE_FATAL);
 	if (bytes_read > iso9660->entry_bytes_remaining)
-		bytes_read =3D iso9660->entry_bytes_remaining;
+		bytes_read =3D (ssize_t)iso9660->entry_bytes_remaining;
 	*size =3D bytes_read;
 	*offset =3D iso9660->entry_sparse_offset;
 	iso9660->entry_sparse_offset +=3D bytes_read;
@@ -2277,7 +2277,7 @@
 			archive_set_error(&a->archive, ENOMEM, "Out of memory");
 			return (ARCHIVE_FATAL);
 		}
-		p =3D malloc(new_size * sizeof(p[0]));
+		p =3D calloc(new_size, sizeof(p[0]));
 		if (p =3D=3D NULL) {
 			archive_set_error(&a->archive, ENOMEM, "Out of memory");
 			return (ARCHIVE_FATAL);
@@ -2527,9 +2527,6 @@
=20
 	if (!file->symlink_continues || file->symlink.length < 1)
 		archive_string_empty(&file->symlink);
-	else if (!file->symlink_continues &&
-	    file->symlink.s[file->symlink.length - 1] !=3D '/')
-		separator =3D "/";
 	file->symlink_continues =3D 0;
=20
 	/*
@@ -3099,6 +3096,8 @@
 {
 	struct tm tm;
 	int offset;
+	time_t t;
+
 	memset(&tm, 0, sizeof(tm));
 	tm.tm_year =3D v[0];
 	tm.tm_mon =3D v[1] - 1;
@@ -3112,7 +3111,10 @@
 		tm.tm_hour -=3D offset / 4;
 		tm.tm_min -=3D (offset % 4) * 15;
 	}
-	return (time_from_tm(&tm));
+	t =3D time_from_tm(&tm);
+	if (t =3D=3D (time_t)-1)
+		return ((time_t)0);
+	return (t);
 }
=20
 static time_t
@@ -3120,6 +3122,8 @@
 {
 	struct tm tm;
 	int offset;
+	time_t t;
+
 	memset(&tm, 0, sizeof(tm));
 	tm.tm_year =3D (v[0] - '0') * 1000 + (v[1] - '0') * 100
 	    + (v[2] - '0') * 10 + (v[3] - '0')
@@ -3135,7 +3139,10 @@
 		tm.tm_hour -=3D offset / 4;
 		tm.tm_min -=3D (offset % 4) * 15;
 	}
-	return (time_from_tm(&tm));
+	t =3D time_from_tm(&tm);
+	if (t =3D=3D (time_t)-1)
+		return ((time_t)0);
+	return (t);
 }
=20
 static time_t
@@ -3149,7 +3156,8 @@
 #else
 	/* Else use direct calculation using POSIX assumptions. */
 	/* First, fix up tm_yday based on the year/month/day. */
-	mktime(t);
+	if (mktime(t) =3D=3D (time_t)-1)
+		return ((time_t)-1);
 	/* Then we can compute timegm() from first principles. */
 	return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600
 	    + t->tm_yday * 86400 + (t->tm_year - 70) * 31536000
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_lha.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_lha.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_lha.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -951,7 +951,7 @@
=20
 	/* Read extended headers */
 	err2 =3D lha_read_file_extended_header(a, lha, NULL, 2,
-	    lha->compsize + 2, &extdsize);
+	    (size_t)(lha->compsize + 2), &extdsize);
 	if (err2 < ARCHIVE_WARN)
 		return (err2);
 	if (err2 < err)
@@ -1446,7 +1446,7 @@
 		return (ARCHIVE_FATAL);
 	}
 	if (bytes_avail > lha->entry_bytes_remaining)
-		bytes_avail =3D lha->entry_bytes_remaining;
+		bytes_avail =3D (ssize_t)lha->entry_bytes_remaining;
 	lha->entry_crc_calculated =3D
 	    lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
 	*size =3D bytes_avail;
@@ -1529,7 +1529,7 @@
 		return (ARCHIVE_FATAL);
 	}
 	if (bytes_avail > lha->entry_bytes_remaining)
-		bytes_avail =3D lha->entry_bytes_remaining;
+		bytes_avail =3D (ssize_t)lha->entry_bytes_remaining;
=20
 	lha->strm.avail_in =3D bytes_avail;
 	lha->strm.total_in =3D 0;
@@ -1575,7 +1575,7 @@
 archive_read_format_lha_read_data_skip(struct archive_read *a)
 {
 	struct lha *lha;
-	off_t bytes_skipped;
+	int64_t bytes_skipped;
=20
 	lha =3D (struct lha *)(a->format->data);
=20
@@ -2016,7 +2016,7 @@
 		if (ds->w_pos - ds->copy_pos <=3D strm->avail_out)
 			copy_bytes =3D ds->w_pos - ds->copy_pos;
 		else
-			copy_bytes =3D strm->avail_out;
+			copy_bytes =3D (size_t)strm->avail_out;
 		memcpy(strm->next_out,
 		    ds->w_buff + ds->copy_pos, copy_bytes);
 		ds->copy_pos +=3D copy_bytes;
@@ -2024,7 +2024,7 @@
 		if (ds->w_remaining <=3D strm->avail_out)
 			copy_bytes =3D ds->w_remaining;
 		else
-			copy_bytes =3D strm->avail_out;
+			copy_bytes =3D (size_t)strm->avail_out;
 		memcpy(strm->next_out,
 		    ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes);
 		ds->w_remaining -=3D copy_bytes;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_mtree.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_mtree.=
c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_mtree.=
c	Fri Aug 10 14:19:25 2012 +0300
@@ -26,7 +26,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_mtree.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_mtree.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -1183,7 +1183,7 @@
=20
 	comma1 =3D strchr(val, ',');
 	if (comma1 =3D=3D NULL) {
-		archive_entry_set_dev(entry, mtree_atol10(&val));
+		archive_entry_set_dev(entry, (dev_t)mtree_atol10(&val));
 		return (ARCHIVE_OK);
 	}
 	++comma1;
@@ -1194,8 +1194,8 @@
 		return (ARCHIVE_WARN);
 	}
 	++comma2;
-	archive_entry_set_rdevmajor(entry, mtree_atol(&comma1));
-	archive_entry_set_rdevminor(entry, mtree_atol(&comma2));
+	archive_entry_set_rdevmajor(entry, (dev_t)mtree_atol(&comma1));
+	archive_entry_set_rdevminor(entry, (dev_t)mtree_atol(&comma2));
 	return (ARCHIVE_OK);
 }
=20
@@ -1280,7 +1280,7 @@
 			if (val[0] >=3D '0' && val[0] <=3D '9') {
 				*parsed_kws |=3D MTREE_HAS_PERM;
 				archive_entry_set_perm(entry,
-				    mtree_atol8(&val));
+				    (mode_t)mtree_atol8(&val));
 			} else {
 				archive_set_error(&a->archive,
 				    ARCHIVE_ERRNO_FILE_FORMAT,
@@ -1292,7 +1292,8 @@
 	case 'n':
 		if (strcmp(key, "nlink") =3D=3D 0) {
 			*parsed_kws |=3D MTREE_HAS_NLINK;
-			archive_entry_set_nlink(entry, mtree_atol10(&val));
+			archive_entry_set_nlink(entry,
+				(unsigned int)mtree_atol10(&val));
 			break;
 		}
 	case 'r':
@@ -1434,7 +1435,7 @@
 	*buff =3D mtree->buff;
 	*offset =3D mtree->offset;
 	if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
-		bytes_to_read =3D mtree->cur_size - mtree->offset;
+		bytes_to_read =3D (size_t)(mtree->cur_size - mtree->offset);
 	else
 		bytes_to_read =3D mtree->buffsize;
 	bytes_read =3D read(mtree->fd, mtree->buff, bytes_to_read);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_rar.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_rar.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_rar.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -453,7 +453,7 @@
       if (br->next_in =3D=3D NULL)
         return (0);
       if (br->avail_in > rar->bytes_remaining)
-        br->avail_in =3D rar->bytes_remaining;
+        br->avail_in =3D (ssize_t)rar->bytes_remaining;
       if (br->avail_in =3D=3D 0)
         return (0);
     }
@@ -481,7 +481,7 @@
       return (ARCHIVE_FATAL);
     }
     if (br->avail_in > rar->bytes_remaining)
-      br->avail_in =3D rar->bytes_remaining;
+      br->avail_in =3D (ssize_t)rar->bytes_remaining;
     if (br->cache_avail =3D=3D 0)
       (void)rar_br_fillup(a, br);
   }
@@ -522,7 +522,7 @@
 static inline int
 lzss_offset_for_position(struct lzss *lzss, int64_t pos)
 {
-  return pos & lzss->mask;
+  return (int)(pos & lzss->mask);
 }
=20
 static inline unsigned char *
@@ -1084,11 +1084,11 @@
     return (ARCHIVE_FATAL);
   }
=20
-  if ((h =3D __archive_read_ahead(a, header_size - 7, NULL)) =3D=3D NULL)
+  if ((h =3D __archive_read_ahead(a, (size_t)header_size - 7, NULL)) =3D=
=3D NULL)
     return (ARCHIVE_FATAL);
=20
   /* File Header CRC check. */
-  crc32_val =3D crc32(crc32_val, h, header_size - 7);
+  crc32_val =3D crc32(crc32_val, h, (unsigned)(header_size - 7));
   if ((crc32_val & 0xffff) !=3D archive_le16dec(rar_header.crc)) {
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
       "Header CRC error");
@@ -1131,9 +1131,6 @@
     rar->unp_size =3D archive_le32dec(file_header.unp_size);
   }
=20
-  /* 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,
@@ -1148,7 +1145,7 @@
     size_t distance =3D p - (const char *)h;
     header_size +=3D rar->packed_size;
     /* Make sure we have the extended data. */
-    if ((h =3D __archive_read_ahead(a, header_size - 7, NULL)) =3D=3D NULL)
+    if ((h =3D __archive_read_ahead(a, (size_t)header_size - 7, NULL)) =3D=
=3D NULL)
         return (ARCHIVE_FATAL);
     p =3D h;
     endp =3D p + header_size - 7;
@@ -1161,13 +1158,17 @@
       "Invalid filename size");
     return (ARCHIVE_FATAL);
   }
-  if (rar->filename_allocated < filename_size+2) {
-    rar->filename =3D realloc(rar->filename, filename_size+2);
-    if (rar->filename =3D=3D NULL) {
+  if (rar->filename_allocated < filename_size * 2 + 2) {
+    char *newptr;
+    size_t newsize =3D filename_size * 2 + 2;
+    newptr =3D realloc(rar->filename, newsize);
+    if (newptr =3D=3D NULL) {
       archive_set_error(&a->archive, ENOMEM,
                         "Couldn't allocate memory.");
       return (ARCHIVE_FATAL);
     }
+    rar->filename =3D newptr;
+    rar->filename_allocated =3D newsize;
   }
   filename =3D rar->filename;
   memcpy(filename, p, filename_size);
@@ -1176,15 +1177,17 @@
   {
     if (filename_size !=3D strlen(filename))
     {
-      unsigned char highbyte, flagbits, flagbyte, length, offset;
+      unsigned char highbyte, flagbits, flagbyte, offset;
+      unsigned fn_end;
=20
       end =3D filename_size;
+      fn_end =3D filename_size * 2;
       filename_size =3D 0;
       offset =3D strlen(filename) + 1;
       highbyte =3D *(p + offset++);
       flagbits =3D 0;
       flagbyte =3D 0;
-      while (offset < end && filename_size < end)
+      while (offset < end && filename_size < fn_end)
       {
         if (!flagbits)
         {
@@ -1210,19 +1213,26 @@
             break;
           case 3:
           {
-            length =3D *(p + offset++);
-            while (length)
-            {
-	          if (filename_size >=3D end)
-			    break;
-              filename[filename_size++] =3D *(p + offset);
+            char extra, high;
+            uint8_t length =3D *(p + offset++);
+
+            if (length & 0x80) {
+              extra =3D *(p + offset++);
+              high =3D (char)highbyte;
+            } else
+              extra =3D high =3D 0;
+            length =3D (length & 0x7f) + 2;
+            while (length && filename_size < fn_end) {
+              unsigned cp =3D filename_size >> 1;
+              filename[filename_size++] =3D high;
+              filename[filename_size++] =3D p[cp] + extra;
               length--;
             }
           }
           break;
         }
       }
-      if (filename_size >=3D end) {
+      if (filename_size > fn_end) {
         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
           "Invalid filename");
         return (ARCHIVE_FATAL);
@@ -1322,7 +1332,8 @@
=20
   rar->bytes_remaining =3D rar->packed_size;
   rar->bytes_uncopied =3D rar->bytes_unconsumed =3D 0;
-  rar->lzss.position =3D rar->dictionary_size =3D rar->offset =3D 0;
+  rar->lzss.position =3D rar->offset =3D 0;
+  rar->dictionary_size =3D 0;
   rar->offset_outgoing =3D 0;
   rar->br.cache_avail =3D 0;
   rar->br.avail_in =3D 0;
@@ -1477,11 +1488,12 @@
   int ret =3D (ARCHIVE_OK);
=20
   rar =3D (struct rar *)(a->format->data);
-  if ((h =3D __archive_read_ahead(a, rar->packed_size, NULL)) =3D=3D NULL)
+  if ((h =3D __archive_read_ahead(a, (size_t)rar->packed_size, NULL)) =3D=
=3D NULL)
     return (ARCHIVE_FATAL);
   p =3D h;
=20
-  if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv))
+  if (archive_entry_copy_symlink_l(entry,
+      p, (size_t)rar->packed_size, sconv))
   {
     if (errno =3D=3D ENOMEM)
     {
@@ -1528,7 +1540,7 @@
     return (ARCHIVE_FATAL);
   }
   if (bytes_avail > rar->bytes_remaining)
-    bytes_avail =3D rar->bytes_remaining;
+    bytes_avail =3D (ssize_t)rar->bytes_remaining;
=20
   *size =3D bytes_avail;
   *offset =3D rar->offset;
@@ -1587,7 +1599,7 @@
       if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
         bs =3D rar->unp_buffer_size - rar->unp_offset;
       else
-        bs =3D rar->bytes_uncopied;
+        bs =3D (size_t)rar->bytes_uncopied;
       ret =3D copy_from_lzss_window(a, buff, rar->offset, bs);
       if (ret !=3D ARCHIVE_OK)
         return (ret);
@@ -1715,7 +1727,7 @@
     if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
       bs =3D rar->unp_buffer_size - rar->unp_offset;
     else
-      bs =3D rar->bytes_uncopied;
+      bs =3D (size_t)rar->bytes_uncopied;
     ret =3D copy_from_lzss_window(a, buff, rar->offset, bs);
     if (ret !=3D ARCHIVE_OK)
       return (ret);
@@ -1978,7 +1990,7 @@
     if (rar->unp_size >=3D DICTIONARY_MAX_SIZE)
       rar->dictionary_size =3D DICTIONARY_MAX_SIZE;
     else
-      rar->dictionary_size =3D rar_fls(rar->unp_size) << 1;
+      rar->dictionary_size =3D rar_fls((unsigned int)rar->unp_size) << 1;
     rar->lzss.window =3D (unsigned char *)realloc(rar->lzss.window,
                                                 rar->dictionary_size);
     if (rar->lzss.window =3D=3D NULL) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_tar.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_tar.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_tar.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_tar.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_tar.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -527,56 +527,57 @@
=20
 	tar =3D (struct tar *)(a->format->data);
=20
-skip_hole:
-	/* Remove exhausted entries from sparse list. */
-	while (tar->sparse_list !=3D NULL &&
-	    tar->sparse_list->remaining =3D=3D 0) {
-		p =3D tar->sparse_list;
-		tar->sparse_list =3D p->next;
-		free(p);
+	for (;;) {
+		/* Remove exhausted entries from sparse list. */
+		while (tar->sparse_list !=3D NULL &&
+		    tar->sparse_list->remaining =3D=3D 0) {
+			p =3D tar->sparse_list;
+			tar->sparse_list =3D p->next;
+			free(p);
+		}
+
+		if (tar->entry_bytes_unconsumed) {
+			__archive_read_consume(a, tar->entry_bytes_unconsumed);
+			tar->entry_bytes_unconsumed =3D 0;
+		}
+
+		/* If we're at end of file, return EOF. */
+		if (tar->sparse_list =3D=3D NULL ||
+		    tar->entry_bytes_remaining =3D=3D 0) {
+			if (__archive_read_consume(a, tar->entry_padding) < 0)
+				return (ARCHIVE_FATAL);
+			tar->entry_padding =3D 0;
+			*buff =3D NULL;
+			*size =3D 0;
+			*offset =3D tar->realsize;
+			return (ARCHIVE_EOF);
+		}
+
+		*buff =3D __archive_read_ahead(a, 1, &bytes_read);
+		if (bytes_read < 0)
+			return (ARCHIVE_FATAL);
+		if (*buff =3D=3D NULL) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Truncated tar archive");
+			return (ARCHIVE_FATAL);
+		}
+		if (bytes_read > tar->entry_bytes_remaining)
+			bytes_read =3D (ssize_t)tar->entry_bytes_remaining;
+		/* Don't read more than is available in the
+		 * current sparse block. */
+		if (tar->sparse_list->remaining < bytes_read)
+			bytes_read =3D (ssize_t)tar->sparse_list->remaining;
+		*size =3D bytes_read;
+		*offset =3D tar->sparse_list->offset;
+		tar->sparse_list->remaining -=3D bytes_read;
+		tar->sparse_list->offset +=3D bytes_read;
+		tar->entry_bytes_remaining -=3D bytes_read;
+		tar->entry_bytes_unconsumed =3D bytes_read;
+
+		if (!tar->sparse_list->hole)
+			return (ARCHIVE_OK);
+		/* Current is hole data and skip this. */
 	}
-
-	if (tar->entry_bytes_unconsumed) {
-		__archive_read_consume(a, tar->entry_bytes_unconsumed);
-		tar->entry_bytes_unconsumed =3D 0;
-	}
-
-	/* If we're at end of file, return EOF. */
-	if (tar->sparse_list =3D=3D NULL || tar->entry_bytes_remaining =3D=3D 0) {
-		if (__archive_read_consume(a, tar->entry_padding) < 0)
-			return (ARCHIVE_FATAL);
-		tar->entry_padding =3D 0;
-		*buff =3D NULL;
-		*size =3D 0;
-		*offset =3D tar->realsize;
-		return (ARCHIVE_EOF);
-	}
-
-	*buff =3D __archive_read_ahead(a, 1, &bytes_read);
-	if (bytes_read < 0)
-		return (ARCHIVE_FATAL);
-	if (*buff =3D=3D NULL) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Truncated tar archive");
-		return (ARCHIVE_FATAL);
-	}
-	if (bytes_read > tar->entry_bytes_remaining)
-		bytes_read =3D tar->entry_bytes_remaining;
-	/* Don't read more than is available in the
-	 * current sparse block. */
-	if (tar->sparse_list->remaining < bytes_read)
-		bytes_read =3D tar->sparse_list->remaining;
-	*size =3D bytes_read;
-	*offset =3D tar->sparse_list->offset;
-	tar->sparse_list->remaining -=3D bytes_read;
-	tar->sparse_list->offset +=3D bytes_read;
-	tar->entry_bytes_remaining -=3D bytes_read;
-	tar->entry_bytes_unconsumed =3D bytes_read;
-
-	if (tar->sparse_list->hole)
-		goto skip_hole;
-
-	return (ARCHIVE_OK);
 }
=20
 static int
@@ -786,7 +787,7 @@
 	 * Test the checksum.  Note that POSIX specifies _unsigned_
 	 * bytes for this calculation.
 	 */
-	sum =3D tar_atol(header->checksum, sizeof(header->checksum));
+	sum =3D (int)tar_atol(header->checksum, sizeof(header->checksum));
 	check =3D 0;
 	for (i =3D 0; i < 148; i++)
 		check +=3D (unsigned char)bytes[i];
@@ -847,7 +848,7 @@
 	 * more to make sure that we don't overrun acl_text later.
 	 */
 	header =3D (const struct archive_entry_header_ustar *)h;
-	size =3D tar_atol(header->size, sizeof(header->size));
+	size =3D (size_t)tar_atol(header->size, sizeof(header->size));
 	err =3D read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
 	if (err !=3D ARCHIVE_OK)
 		return (err);
@@ -1021,7 +1022,7 @@
 	}
=20
 	/* Fail if we can't make our buffer big enough. */
-	if (archive_string_ensure(as, size+1) =3D=3D NULL) {
+	if (archive_string_ensure(as, (size_t)size+1) =3D=3D NULL) {
 		archive_set_error(&a->archive, ENOMEM,
 		    "No memory");
 		return (ARCHIVE_FATAL);
@@ -1030,15 +1031,15 @@
 	tar_flush_unconsumed(a, unconsumed);
=20
 	/* Read the body into the string. */
-	*unconsumed =3D (size + 511) & ~ 511;
+	*unconsumed =3D (size_t)((size + 511) & ~ 511);
 	src =3D __archive_read_ahead(a, *unconsumed, NULL);
 	if (src =3D=3D NULL) {
 		*unconsumed =3D 0;
 		return (ARCHIVE_FATAL);
 	}
-	memcpy(as->s, src, size);
+	memcpy(as->s, src, (size_t)size);
 	as->s[size] =3D '\0';
-	as->length =3D size;
+	as->length =3D (size_t)size;
 	return (ARCHIVE_OK);
 }
=20
@@ -1068,7 +1069,8 @@
 		archive_string_empty(&(tar->entry_linkpath));
=20
 	/* Parse out the numeric fields (all are octal) */
-	archive_entry_set_mode(entry, tar_atol(header->mode, sizeof(header->mode)=
));
+	archive_entry_set_mode(entry,
+		(mode_t)tar_atol(header->mode, sizeof(header->mode)));
 	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 =3D tar_atol(header->size, sizeof(header->size=
));
@@ -1310,13 +1312,13 @@
 	 * Q: Is the above idea really possible?  Even
 	 * when there are GNU or pax extension entries?
 	 */
-	data =3D __archive_read_ahead(a, size, NULL);
+	data =3D __archive_read_ahead(a, (size_t)size, NULL);
 	if (data =3D=3D NULL) {
 		*unconsumed =3D 0;
 		return (ARCHIVE_FATAL);
 	}
-	archive_entry_copy_mac_metadata(entry, data, size);
-	*unconsumed =3D (size + 511) & ~ 511;
+	archive_entry_copy_mac_metadata(entry, data, (size_t)size);
+	*unconsumed =3D (size_t)((size + 511) & ~ 511);
 	tar_flush_unconsumed(a, unconsumed);
 	return (tar_read_header(a, tar, entry, unconsumed));
 }
@@ -1424,9 +1426,9 @@
=20
 	/* Parse out device numbers only for char and block specials. */
 	if (header->typeflag[0] =3D=3D '3' || header->typeflag[0] =3D=3D '4') {
-		archive_entry_set_rdevmajor(entry,
+		archive_entry_set_rdevmajor(entry, (dev_t)
 		    tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
-		archive_entry_set_rdevminor(entry,
+		archive_entry_set_rdevminor(entry, (dev_t)
 		    tar_atol(header->rdevminor, sizeof(header->rdevminor)));
 	}
=20
@@ -1663,6 +1665,11 @@
 	long n;
 	int err =3D ARCHIVE_OK, r;
=20
+#ifndef __FreeBSD__
+	if (value =3D=3D NULL)
+		value =3D "";	/* Disable compiler warning; do not pass
+				 * NULL pointer to strlen().  */
+#endif
 	switch (key[0]) {
 	case 'G':
 		/* GNU "0.0" sparse pax format. */
@@ -1709,11 +1716,11 @@
=20
 		/* GNU "1.0" sparse pax format */
 		if (strcmp(key, "GNU.sparse.major") =3D=3D 0) {
-			tar->sparse_gnu_major =3D tar_atol10(value, strlen(value));
+			tar->sparse_gnu_major =3D (int)tar_atol10(value, strlen(value));
 			tar->sparse_gnu_pending =3D 1;
 		}
 		if (strcmp(key, "GNU.sparse.minor") =3D=3D 0) {
-			tar->sparse_gnu_minor =3D tar_atol10(value, strlen(value));
+			tar->sparse_gnu_minor =3D (int)tar_atol10(value, strlen(value));
 			tar->sparse_gnu_pending =3D 1;
 		}
 		if (strcmp(key, "GNU.sparse.name") =3D=3D 0) {
@@ -1796,20 +1803,20 @@
 			}
 		} else if (strcmp(key, "SCHILY.devmajor") =3D=3D 0) {
 			archive_entry_set_rdevmajor(entry,
-			    tar_atol10(value, strlen(value)));
+			    (dev_t)tar_atol10(value, strlen(value)));
 		} else if (strcmp(key, "SCHILY.devminor") =3D=3D 0) {
 			archive_entry_set_rdevminor(entry,
-			    tar_atol10(value, strlen(value)));
+			    (dev_t)tar_atol10(value, strlen(value)));
 		} else if (strcmp(key, "SCHILY.fflags") =3D=3D 0) {
 			archive_entry_copy_fflags_text(entry, value);
 		} else if (strcmp(key, "SCHILY.dev") =3D=3D 0) {
 			archive_entry_set_dev(entry,
-			    tar_atol10(value, strlen(value)));
+			    (dev_t)tar_atol10(value, strlen(value)));
 		} else if (strcmp(key, "SCHILY.ino") =3D=3D 0) {
 			archive_entry_set_ino(entry,
 			    tar_atol10(value, strlen(value)));
 		} else if (strcmp(key, "SCHILY.nlink") =3D=3D 0) {
-			archive_entry_set_nlink(entry,
+			archive_entry_set_nlink(entry, (unsigned)
 			    tar_atol10(value, strlen(value)));
 		} else if (strcmp(key, "SCHILY.realsize") =3D=3D 0) {
 			tar->realsize =3D tar_atol10(value, strlen(value));
@@ -2018,9 +2025,9 @@
=20
 	/* Parse out device numbers only for char and block specials */
 	if (header->typeflag[0] =3D=3D '3' || header->typeflag[0] =3D=3D '4') {
-		archive_entry_set_rdevmajor(entry,
+		archive_entry_set_rdevmajor(entry, (dev_t)
 		    tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
-		archive_entry_set_rdevminor(entry,
+		archive_entry_set_rdevminor(entry, (dev_t)
 		    tar_atol(header->rdevminor, sizeof(header->rdevminor)));
 	} else
 		archive_entry_set_rdev(entry, 0);
@@ -2255,7 +2262,8 @@
 	 * don't require this, but they should.
 	 */
 	do {
-		bytes_read =3D readline(a, tar, &p, tar_min(*remaining, 100), unconsumed=
);
+		bytes_read =3D readline(a, tar, &p,
+			(ssize_t)tar_min(*remaining, 100), unconsumed);
 		if (bytes_read <=3D 0)
 			return (ARCHIVE_FATAL);
 		*remaining -=3D bytes_read;
@@ -2296,7 +2304,7 @@
 	remaining =3D tar->entry_bytes_remaining;
=20
 	/* Parse entries. */
-	entries =3D gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
+	entries =3D (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
 	if (entries < 0)
 		return (ARCHIVE_FATAL);
 	/* Parse the individual entries. */
@@ -2314,11 +2322,11 @@
 	}
 	/* Skip rest of block... */
 	tar_flush_unconsumed(a, unconsumed);
-	bytes_read =3D tar->entry_bytes_remaining - remaining;
+	bytes_read =3D (ssize_t)(tar->entry_bytes_remaining - remaining);
 	to_skip =3D 0x1ff & -bytes_read;
 	if (to_skip !=3D __archive_read_consume(a, to_skip))
 		return (ARCHIVE_FATAL);
-	return (bytes_read + to_skip);
+	return ((ssize_t)(bytes_read + to_skip));
 }
=20
 /*
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_xar.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_xar.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_xar.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_xar.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_xar.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -183,9 +183,9 @@
 	time_t			 mtime;
 	time_t			 atime;
 	struct archive_string	 uname;
-	uid_t			 uid;
+	int64_t			 uid;
 	struct archive_string	 gname;
-	gid_t			 gid;
+	int64_t			 gid;
 	mode_t			 mode;
 	dev_t			 dev;
 	dev_t			 devmajor;
@@ -602,7 +602,8 @@
 		r =3D move_reading_point(a, xar->toc_chksum_offset);
 		if (r !=3D ARCHIVE_OK)
 			return (r);
-		b =3D __archive_read_ahead(a, xar->toc_chksum_size, &bytes);
+		b =3D __archive_read_ahead(a,
+			(size_t)xar->toc_chksum_size, &bytes);
 		if (bytes < 0)
 			return ((int)bytes);
 		if ((uint64_t)bytes < xar->toc_chksum_size) {
@@ -611,7 +612,8 @@
 			    "Truncated archive file");
 			return (ARCHIVE_FATAL);
 		}
-		r =3D checksum_final(a, b, xar->toc_chksum_size, NULL, 0);
+		r =3D checksum_final(a, b,
+			(size_t)xar->toc_chksum_size, NULL, 0);
 		__archive_read_consume(a, xar->toc_chksum_size);
 		xar->offset +=3D xar->toc_chksum_size;
 		if (r !=3D ARCHIVE_OK)
@@ -2065,7 +2067,7 @@
 					xar->file->hdnext =3D xar->hdlink_orgs;
 					xar->hdlink_orgs =3D xar->file;
 				} else {
-					xar->file->link =3D atol10(attr->value,
+					xar->file->link =3D (unsigned)atol10(attr->value,
 					    strlen(attr->value));
 					if (xar->file->link > 0)
 						if (add_link(a, xar, xar->file) !=3D ARCHIVE_OK) {
@@ -2761,7 +2763,7 @@
 		xar->file->has |=3D HAS_MODE;
 		xar->file->mode =3D
 		    (xar->file->mode & AE_IFMT) |
-		    (atol8(s, len) & ~AE_IFMT);
+		    ((mode_t)(atol8(s, len)) & ~AE_IFMT);
 		break;
 	case FILE_GROUP:
 		xar->file->has |=3D HAS_GID;
@@ -3076,12 +3078,15 @@
 		attr->name =3D strdup(
 		    (const char *)xmlTextReaderConstLocalName(reader));
 		if (attr->name =3D=3D NULL) {
+			free(attr);
 			archive_set_error(&a->archive, ENOMEM, "Out of memory");
 			return (ARCHIVE_FATAL);
 		}
 		attr->value =3D strdup(
 		    (const char *)xmlTextReaderConstValue(reader));
 		if (attr->value =3D=3D NULL) {
+			free(attr->name);
+			free(attr);
 			archive_set_error(&a->archive, ENOMEM, "Out of memory");
 			return (ARCHIVE_FATAL);
 		}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_read_support_format_zip.c
--- a/head/contrib/libarchive/libarchive/archive_read_support_format_zip.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_read_support_format_zip.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_zip.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_suppor=
t_format_zip.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -38,17 +38,19 @@
 #endif
=20
 #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_read_private.h"
-#include "archive_endian.h"
=20
 #ifndef HAVE_ZLIB_H
 #include "archive_crc32.h"
 #endif
=20
 struct zip_entry {
+	struct archive_rb_node	node;
 	int64_t			local_header_offset;
 	int64_t			compressed_size;
 	int64_t			uncompressed_size;
@@ -71,11 +73,13 @@
 	size_t			central_directory_size;
 	size_t			central_directory_entries;
 	char			have_central_directory;
+	int64_t			offset;
=20
 	/* List of entries (seekable Zip only) */
 	size_t			entries_remaining;
 	struct zip_entry	*zip_entries;
 	struct zip_entry	*entry;
+	struct archive_rb_tree	tree;
=20
 	size_t			unconsumed;
=20
@@ -275,13 +279,37 @@
 }
=20
 static int
+cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n=
2)
+{
+	const struct zip_entry *e1 =3D (const struct zip_entry *)n1;
+	const struct zip_entry *e2 =3D (const struct zip_entry *)n2;
+
+	return ((int)(e2->local_header_offset - e1->local_header_offset));
+}
+
+static int
+cmp_key(const struct archive_rb_node *n, const void *key)
+{
+	/* This function won't be called */
+	(void)n; /* UNUSED */
+	(void)key; /* UNUSED */
+	return 1;
+}
+
+static int
 slurp_central_directory(struct archive_read *a, struct zip *zip)
 {
 	unsigned i;
+	static const struct archive_rb_tree_ops rb_ops =3D {
+		&cmp_node, &cmp_key
+	};
=20
 	__archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
+	zip->offset =3D zip->central_directory_offset;
+	__archive_rb_tree_init(&zip->tree, &rb_ops);
=20
-	zip->zip_entries =3D calloc(zip->central_directory_entries, sizeof(struct=
 zip_entry));
+	zip->zip_entries =3D calloc(zip->central_directory_entries,
+				sizeof(struct zip_entry));
 	for (i =3D 0; i < zip->central_directory_entries; ++i) {
 		struct zip_entry *zip_entry =3D &zip->zip_entries[i];
 		size_t filename_length, extra_length, comment_length;
@@ -300,7 +328,7 @@
 		zip_entry->system =3D p[5];
 		/* version_required =3D archive_le16dec(p + 6); */
 		zip_entry->flags =3D archive_le16dec(p + 8);
-		zip_entry->compression =3D archive_le16dec(p + 10);
+		zip_entry->compression =3D (char)archive_le16dec(p + 10);
 		zip_entry->mtime =3D zip_time(p + 12);
 		zip_entry->crc32 =3D archive_le32dec(p + 16);
 		zip_entry->compressed_size =3D archive_le32dec(p + 20);
@@ -320,6 +348,8 @@
 		if (zip_entry->system =3D=3D 3) {
 			zip_entry->mode =3D external_attributes >> 16;
 		}
+		/* Register an entry to RB tree to sort it by file offset. */
+		__archive_rb_tree_insert_node(&zip->tree, &zip_entry->node);
=20
 		/* We don't read the filename until we get to the
 		   local file header.  Reading it here would speed up
@@ -333,11 +363,19 @@
 		    46 + filename_length + extra_length + comment_length);
 	}
=20
-	/* TODO: Sort zip entries by file offset so that we
-	   can optimize get_next_header() to use skip instead of
-	   seek. */
+	return ARCHIVE_OK;
+}
=20
-	return ARCHIVE_OK;
+static int64_t
+zip_read_consume(struct archive_read *a, int64_t bytes)
+{
+	struct zip *zip =3D (struct zip *)a->format->data;
+	int64_t skip;
+
+	skip =3D __archive_read_consume(a, bytes);
+	if (skip > 0)
+		zip->offset +=3D skip;
+	return (skip);
 }
=20
 static int
@@ -345,7 +383,7 @@
 	struct archive_entry *entry)
 {
 	struct zip *zip =3D (struct zip *)a->format->data;
-	int r;
+	int r, ret =3D ARCHIVE_OK;
=20
 	a->archive.archive_format =3D ARCHIVE_FORMAT_ZIP;
 	if (a->archive.archive_format_name =3D=3D NULL)
@@ -356,26 +394,33 @@
 		zip->entries_remaining =3D zip->central_directory_entries;
 		if (r !=3D ARCHIVE_OK)
 			return r;
-		zip->entry =3D zip->zip_entries;
-	} else {
-		++zip->entry;
+		/* Get first entry whose local header offset is lower than
+		 * other entries in the archive file. */
+		zip->entry =3D
+		    (struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
+	} else if (zip->entry !=3D NULL) {
+		/* Get next entry in local header offset order. */
+		zip->entry =3D (struct zip_entry *)__archive_rb_tree_iterate(
+		    &zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
 	}
=20
-	if (zip->entries_remaining <=3D 0)
+	if (zip->entries_remaining <=3D 0 || zip->entry =3D=3D NULL)
 		return ARCHIVE_EOF;
 	--zip->entries_remaining;
=20
-	/* 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);
+	if (zip->offset !=3D zip->entry->local_header_offset) {
+		__archive_read_seek(a, zip->entry->local_header_offset,
+			SEEK_SET);
+		zip->offset =3D zip->entry->local_header_offset;
+	}
 	zip->unconsumed =3D 0;
 	r =3D zip_read_local_file_header(a, entry, zip);
 	if (r !=3D ARCHIVE_OK)
 		return r;
 	if ((zip->entry->mode & AE_IFMT) =3D=3D AE_IFLNK) {
 		const void *p;
-		size_t linkname_length =3D archive_entry_size(entry);
+		struct archive_string_conv *sconv;
+		size_t linkname_length =3D (size_t)archive_entry_size(entry);
=20
 		archive_entry_set_size(entry, 0);
 		p =3D __archive_read_ahead(a, linkname_length, NULL);
@@ -385,17 +430,40 @@
 			return ARCHIVE_FATAL;
 		}
=20
+		sconv =3D zip->sconv;
+		if (sconv =3D=3D NULL && (zip->entry->flags & ZIP_UTF8_NAME))
+			sconv =3D zip->sconv_utf8;
+		if (sconv =3D=3D NULL)
+			sconv =3D zip->sconv_default;
 		if (archive_entry_copy_symlink_l(entry, p, linkname_length,
-		    NULL) !=3D 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);
+		    sconv) !=3D 0) {
+			if (errno !=3D ENOMEM && sconv =3D=3D zip->sconv_utf8 &&
+			    (zip->entry->flags & ZIP_UTF8_NAME))
+			    archive_entry_copy_symlink_l(entry, p,
+				linkname_length, NULL);
+			if (errno =3D=3D ENOMEM) {
+				archive_set_error(&a->archive, ENOMEM,
+				    "Can't allocate memory for Symlink");
+				return (ARCHIVE_FATAL);
+			}
+			/*
+			 * Since there is no character-set regulation for
+			 * symlink name, do not report the conversion error
+			 * in an automatic conversion.
+			 */
+			if (sconv !=3D zip->sconv_utf8 ||
+			    (zip->entry->flags & ZIP_UTF8_NAME) =3D=3D 0) {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Symlink cannot be converted "
+				    "from %s to current locale.",
+				    archive_string_conversion_charset_name(
+					sconv));
+				ret =3D ARCHIVE_WARN;
+			}
 		}
-		/* TODO: handle character-set issues? */
 	}
-	return ARCHIVE_OK;
+	return (ret);
 }
=20
 static int
@@ -489,7 +557,7 @@
 	memset(zip->entry, 0, sizeof(struct zip_entry));
=20
 	/* Search ahead for the next local file header. */
-	__archive_read_consume(a, zip->unconsumed);
+	zip_read_consume(a, zip->unconsumed);
 	zip->unconsumed =3D 0;
 	for (;;) {
 		int64_t skipped =3D 0;
@@ -509,7 +577,7 @@
=20
 				if (p[2] =3D=3D '\003' && p[3] =3D=3D '\004') {
 					/* Regular file entry. */
-					__archive_read_consume(a, skipped);
+					zip_read_consume(a, skipped);
 					return zip_read_local_file_header(a, entry, zip);
 				}
=20
@@ -520,7 +588,7 @@
 			++p;
 			++skipped;
 		}
-		__archive_read_consume(a, skipped);
+		zip_read_consume(a, skipped);
 	}
 }
=20
@@ -569,7 +637,7 @@
 	version =3D p[4];
 	zip_entry->system =3D p[5];
 	zip_entry->flags =3D archive_le16dec(p + 6);
-	zip_entry->compression =3D archive_le16dec(p + 8);
+	zip_entry->compression =3D (char)archive_le16dec(p + 8);
 	zip_entry->mtime =3D zip_time(p + 10);
 	local_crc32 =3D archive_le32dec(p + 14);
 	compressed_size =3D archive_le32dec(p + 18);
@@ -577,7 +645,7 @@
 	filename_length =3D archive_le16dec(p + 26);
 	extra_length =3D archive_le16dec(p + 28);
=20
-	__archive_read_consume(a, 30);
+	zip_read_consume(a, 30);
=20
 	if (zip->have_central_directory) {
 		/* If we read the central dir entry, we must have size information
@@ -647,7 +715,7 @@
 		    archive_string_conversion_charset_name(sconv));
 		ret =3D ARCHIVE_WARN;
 	}
-	__archive_read_consume(a, filename_length);
+	zip_read_consume(a, filename_length);
=20
 	if (zip_entry->mode =3D=3D 0) {
 		/* Especially in streaming mode, we can end up
@@ -659,14 +727,14 @@
 			if (len > 0 && wp[len - 1] =3D=3D L'/')
 				zip_entry->mode =3D AE_IFDIR | 0777;
 			else
-				zip_entry->mode =3D AE_IFREG | 0777;
+				zip_entry->mode =3D AE_IFREG | 0666;
 		} else {
 			cp =3D archive_entry_pathname(entry);
 			len =3D (cp !=3D NULL)?strlen(cp):0;
 			if (len > 0 && cp[len - 1] =3D=3D '/')
 				zip_entry->mode =3D AE_IFDIR | 0777;
 			else
-				zip_entry->mode =3D AE_IFREG | 0777;
+				zip_entry->mode =3D AE_IFREG | 0666;
 		}
 	}
=20
@@ -677,7 +745,7 @@
 		return (ARCHIVE_FATAL);
 	}
 	process_extra(h, extra_length, zip_entry);
-	__archive_read_consume(a, extra_length);
+	zip_read_consume(a, extra_length);
=20
 	/* Populate some additional entry fields: */
 	archive_entry_set_mode(entry, zip_entry->mode);
@@ -774,7 +842,7 @@
 		return (ARCHIVE_FAILED);
 	}
=20
-	__archive_read_consume(a, zip->unconsumed);
+	zip_read_consume(a, zip->unconsumed);
 	zip->unconsumed =3D 0;
=20
 	switch(zip->entry->compression) {
@@ -926,7 +994,7 @@
 			return (ARCHIVE_FATAL);
 		}
 		if (bytes_avail > zip->entry_bytes_remaining)
-			bytes_avail =3D zip->entry_bytes_remaining;
+			bytes_avail =3D (ssize_t)zip->entry_bytes_remaining;
 	}
 	*size =3D bytes_avail;
 	zip->entry_bytes_remaining -=3D bytes_avail;
@@ -990,7 +1058,7 @@
 	compressed_buff =3D __archive_read_ahead(a, 1, &bytes_avail);
 	if (0 =3D=3D (zip->entry->flags & ZIP_LENGTH_AT_END)
 	    && bytes_avail > zip->entry_bytes_remaining) {
-		bytes_avail =3D zip->entry_bytes_remaining;
+		bytes_avail =3D (ssize_t)zip->entry_bytes_remaining;
 	}
 	if (bytes_avail <=3D 0) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -1030,7 +1098,7 @@
=20
 	/* Consume as much as the compressor actually used. */
 	bytes_avail =3D zip->stream.total_in;
-	__archive_read_consume(a, bytes_avail);
+	zip_read_consume(a, bytes_avail);
 	zip->entry_bytes_remaining -=3D bytes_avail;
 	zip->entry_compressed_bytes_read +=3D bytes_avail;
=20
@@ -1070,14 +1138,11 @@
 	/* 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);
=20
 	/* So we know we're streaming... */
 	if (0 =3D=3D (zip->entry->flags & ZIP_LENGTH_AT_END)) {
 		/* We know the compressed length, so we can just skip. */
-		int64_t bytes_skipped =3D __archive_read_consume(a,
+		int64_t bytes_skipped =3D zip_read_consume(a,
 		    zip->entry_bytes_remaining + zip->unconsumed);
 		if (bytes_skipped < 0)
 			return (ARCHIVE_FATAL);
@@ -1100,11 +1165,11 @@
 			if (r !=3D ARCHIVE_OK)
 				return (r);
 		}
-		break;
+		return ARCHIVE_OK;
 #endif
 	default: /* Uncompressed or unknown. */
 		/* Scan for a PK\007\010 signature. */
-		__archive_read_consume(a, zip->unconsumed);
+		zip_read_consume(a, zip->unconsumed);
 		zip->unconsumed =3D 0;
 		for (;;) {
 			const char *p, *buff;
@@ -1122,14 +1187,13 @@
 				else if (p[3] =3D=3D '\007') { p +=3D 1; }
 				else if (p[3] =3D=3D '\010' && p[2] =3D=3D '\007'
 				    && p[1] =3D=3D 'K' && p[0] =3D=3D 'P') {
-					__archive_read_consume(a, p - buff + 16);
+					zip_read_consume(a, p - buff + 16);
 					return ARCHIVE_OK;
 				} else { p +=3D 4; }
 			}
-			__archive_read_consume(a, p - buff);
+			zip_read_consume(a, p - buff);
 		}
 	}
-	return ARCHIVE_OK;
 }
=20
 static int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_string.c
--- a/head/contrib/libarchive/libarchive/archive_string.c	Mon Jul 30 11:44:=
18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_string.c	Fri Aug 10 14:19:=
25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_string.c 23=
2153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_string.c 23=
8856 2012-07-28 06:38:44Z mm $");
=20
 /*
  * Basic resizable string support, to simplify manipulating arbitrary-sized
@@ -61,9 +61,6 @@
 #include <windows.h>
 #include <locale.h>
 #endif
-#if defined(__APPLE__)
-#include <CoreServices/CoreServices.h>
-#endif
=20
 #include "archive_endian.h"
 #include "archive_private.h"
@@ -115,11 +112,6 @@
 #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;
@@ -164,29 +156,29 @@
 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 *, s=
ize_t,
-    struct archive_string_conv *);
-static int win_strncat_to_utf16le(struct archive_string *, const void *, s=
ize_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 v=
oid *,
-    size_t, struct archive_string_conv *);
-static int best_effort_strncat_to_utf16le(struct archive_string *, const v=
oid *,
-    size_t, struct archive_string_conv *);
+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 vo=
id *,
-    size_t, struct archive_string_conv *);
+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);
@@ -201,10 +193,8 @@
     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 *);
=20
@@ -238,7 +228,8 @@
 }
=20
 void
-archive_wstring_concat(struct archive_wstring *dest, struct archive_wstrin=
g *src)
+archive_wstring_concat(struct archive_wstring *dest,
+    struct archive_wstring *src)
 {
 	if (archive_wstring_append(dest, src->s, src->length) =3D=3D NULL)
 		__archive_errx(1, "Out of memory");
@@ -443,10 +434,7 @@
 archive_wstring_append_from_mbs(struct archive_wstring *dest,
     const char *p, size_t len)
 {
-	int r =3D archive_wstring_append_from_mbs_in_codepage(dest, p, len, NULL);
-	if (r !=3D 0 && errno =3D=3D ENOMEM)
-		__archive_errx(1, "No memory");
-	return (r);
+	return archive_wstring_append_from_mbs_in_codepage(dest, p, len, NULL);
 }
=20
 static int
@@ -479,7 +467,8 @@
 			*ws++ =3D (wchar_t)*mp++;
 			count++;
 		}
-	} else if (sc !=3D NULL && (sc->flag & SCONV_NORMALIZATION_C)) {
+	} else if (sc !=3D NULL &&
+	    (sc->flag & (SCONV_NORMALIZATION_C | SCONV_NORMALIZATION_D))) {
 		/*
 		 * Normalize UTF-8 and UTF-16BE and convert it directly
 		 * to UTF-16 as wchar_t.
@@ -495,18 +484,23 @@
 		if (sc->flag & SCONV_FROM_UTF16) {
 			/*
 			 *  UTF-16BE/LE NFD =3D=3D=3D> UTF-16 NFC
+			 *  UTF-16BE/LE NFC =3D=3D=3D> UTF-16 NFD
 			 */
 			count =3D utf16nbytes(s, length);
 		} else {
 			/*
 			 *  UTF-8 NFD =3D=3D=3D> UTF-16 NFC
+			 *  UTF-8 NFC =3D=3D=3D> UTF-16 NFD
 			 */
 			count =3D mbsnbytes(s, length);
 		}
 		u16.s =3D (char *)dest->s;
 		u16.length =3D dest->length << 1;;
 		u16.buffer_length =3D dest->buffer_length;
-		ret =3D archive_string_normalize_C(&u16, s, count, sc);
+		if (sc->flag & SCONV_NORMALIZATION_C)
+			ret =3D archive_string_normalize_C(&u16, s, count, sc);
+		else
+			ret =3D archive_string_normalize_D(&u16, s, count, sc);
 		dest->s =3D (wchar_t *)u16.s;
 		dest->length =3D u16.length >> 1;
 		dest->buffer_length =3D u16.buffer_length;
@@ -519,7 +513,7 @@
 		if (NULL =3D=3D archive_wstring_ensure(dest,
 		    dest->length + count + 1))
 			return (-1);
-		wmemcpy(dest->s + dest->length, (wchar_t *)s, count);
+		wmemcpy(dest->s + dest->length, (const wchar_t *)s, count);
 		if ((sc->flag & SCONV_FROM_UTF16BE) && !is_big_endian()) {
 			uint16_t *u16 =3D (uint16_t *)(dest->s + dest->length);
 			int b;
@@ -537,6 +531,7 @@
 		}
 	} else {
 		DWORD mbflag;
+		size_t buffsize;
=20
 		if (sc =3D=3D NULL)
 			mbflag =3D 0;
@@ -548,48 +543,31 @@
 		} else
 			mbflag =3D MB_PRECOMPOSED;
=20
-		if (length =3D=3D 0) {
-			/*
-			 * We do not need to convert any characters but make
-			 * sure `dest' has a valid buffer(no NULL pointer).
-			 */
-			if (NULL =3D=3D archive_wstring_ensure(dest,
-			    dest->length + 1))
+		buffsize =3D dest->length + length + 1;
+		do {
+			/* Allocate memory for WCS. */
+			if (NULL =3D=3D archive_wstring_ensure(dest, buffsize))
 				return (-1);
-			dest->s[dest->length] =3D L'\0';
-			return (0);
-		}
-
-		/*
-		 * Count how many bytes are needed for WCS.
-		 */
-		count =3D MultiByteToWideChar(from_cp,
-		    mbflag, s, length, NULL, 0);
-		if (count =3D=3D 0) {
-			if (dest->s =3D=3D NULL) {
-				if (NULL =3D=3D archive_wstring_ensure(dest,
-				    dest->length + 1))
-					return (-1);
+			/* Convert MBS to WCS. */
+			count =3D MultiByteToWideChar(from_cp,
+			    mbflag, s, length, dest->s + dest->length,
+			    (dest->buffer_length >> 1) -1);
+			if (count =3D=3D 0 &&
+			    GetLastError() =3D=3D ERROR_INSUFFICIENT_BUFFER) {
+				/* Expand the WCS buffer. */
+				buffsize =3D dest->buffer_length << 1;
+				continue;
 			}
-			dest->s[dest->length] =3D L'\0';
-			return (-1);
-		}
-		/* Allocate memory for WCS. */
-		if (NULL =3D=3D archive_wstring_ensure(dest,
-		    dest->length + count + 1))
-			return (-1);
-		/* Convert MBS to WCS. */
-		count =3D MultiByteToWideChar(from_cp,
-		    mbflag, s, length, dest->s + dest->length, count);
-		if (count =3D=3D 0)
-			ret =3D -1;
+			if (count =3D=3D 0 && length !=3D 0)
+				ret =3D -1;
+		} while (0);
 	}
 	dest->length +=3D count;
 	dest->s[dest->length] =3D L'\0';
 	return (ret);
 }
=20
-#elif defined(HAVE_MBSNRTOWCS)
+#else
=20
 /*
  * Convert MBS to WCS.
@@ -600,42 +578,7 @@
     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.
-	 */
-	size_t wcs_length =3D len;
-	size_t mbs_length =3D len;
-	const char *mbs =3D p;
-	wchar_t *wcs;
-	mbstate_t shift_state;
-
-	memset(&shift_state, 0, sizeof(shift_state));
-	if (NULL =3D=3D archive_wstring_ensure(dest, dest->length + wcs_length + =
1))
-		__archive_errx(1,
-		    "No memory for archive_wstring_append_from_mbs()");
-	wcs =3D dest->s + dest->length;
-	r =3D mbsnrtowcs(wcs, &mbs, mbs_length, wcs_length, &shift_state);
-	if (r !=3D (size_t)-1) {
-		dest->length +=3D r;
-		dest->s[dest->length] =3D L'\0';
-		return (0);
-	}
-	dest->s[dest->length] =3D 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;
+	int ret_val =3D 0;
 	/*
 	 * No single byte will be more than one wide character,
 	 * so this length estimate will always be big enough.
@@ -650,23 +593,36 @@
 	memset(&shift_state, 0, sizeof(shift_state));
 #endif
 	if (NULL =3D=3D archive_wstring_ensure(dest, dest->length + wcs_length + =
1))
-		__archive_errx(1,
-		    "No memory for archive_wstring_append_from_mbs()");
+		return (-1);
 	wcs =3D 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) {
+	while (*mbs && mbs_length > 0) {
+		if (wcs_length =3D=3D 0) {
+			dest->length =3D wcs - dest->s;
+			dest->s[dest->length] =3D L'\0';
+			wcs_length =3D mbs_length;
+			if (NULL =3D=3D archive_wstring_ensure(dest,
+			    dest->length + wcs_length + 1))
+				return (-1);
+			wcs =3D dest->s + dest->length;
+		}
 #if HAVE_MBRTOWC
 		r =3D mbrtowc(wcs, mbs, wcs_length, &shift_state);
 #else
 		r =3D mbtowc(wcs, mbs, wcs_length);
 #endif
 		if (r =3D=3D (size_t)-1 || r =3D=3D (size_t)-2) {
-			dest->s[dest->length] =3D L'\0';
-			return (-1);
+			ret_val =3D -1;
+			if (errno =3D=3D EILSEQ) {
+				++mbs;
+				--mbs_length;
+				continue;
+			} else
+				break;
 		}
 		if (r =3D=3D 0 || r > mbs_length)
 			break;
@@ -677,7 +633,7 @@
 	}
 	dest->length =3D wcs - dest->s;
 	dest->s[dest->length] =3D L'\0';
-	return (0);
+	return (ret_val);
 }
=20
 #endif
@@ -697,10 +653,7 @@
 archive_string_append_from_wcs(struct archive_string *as,
     const wchar_t *w, size_t len)
 {
-	int r =3D archive_string_append_from_wcs_in_codepage(as, w, len, NULL);
-	if (r !=3D 0 && errno =3D=3D ENOMEM)
-		__archive_errx(1, "No memory");
-	return (r);
+	return archive_string_append_from_wcs_in_codepage(as, w, len, NULL);
 }
=20
 static int
@@ -792,73 +745,6 @@
 	return (defchar_used?-1:ret);
 }
=20
-#elif defined(HAVE_WCSNRTOMBS)
-
-/*
- * 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)
-{
-	mbstate_t shift_state;
-	size_t r, ndest, nwc;
-	char *dest;
-	const wchar_t *wp, *wpp;
-	int ret_val =3D 0;
-
-	wp =3D w;
-	nwc =3D len;
-	ndest =3D 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) =3D=3D NULL)
-			__archive_errx(1, "Out of memory");
-
-		dest =3D as->s + as->length;
-		wpp =3D wp;
-		r =3D wcsnrtombs(dest, &wp, nwc,
-		    as->buffer_length - as->length -1,
-		    &shift_state);
-		if (r =3D=3D (size_t)-1) {
-			if (errno =3D=3D EILSEQ) {
-				/* Retry conversion just for safe WCS. */
-				size_t xwc =3D wp - wpp;
-				wp =3D wpp;
-				r =3D wcsnrtombs(dest, &wp, xwc,
-				    as->buffer_length - as->length -1,
-				    &shift_state);
-				if (r =3D=3D (size_t)-1)
-					/* This would not happen. */
-					return (-1);
-				as->length +=3D r;
-				nwc -=3D wp - wpp;
-				/* Skip an illegal wide char. */
-				as->s[as->length++] =3D '?';
-				wp++;
-				nwc--;
-				ret_val =3D -1;
-				continue;
-			} else {
-				ret_val =3D -1;
-				break;
-			}
-		}
-		as->length +=3D r;
-		if (wp =3D=3D NULL || (wp - wpp) >=3D (int64_t)nwc)
-			break;
-		/* Get a remaining WCS lenth. */
-		nwc -=3D wp - wpp;
-	}
-	/* All wide characters are translated to MBS. */
-	as->s[as->length] =3D '\0';
-	return (ret_val);
-}
-
 #elif defined(HAVE_WCTOMB) || defined(HAVE_WCRTOMB)
=20
 /*
@@ -893,7 +779,7 @@
 	 * as->s is still NULL.
 	 */
 	if (archive_string_ensure(as, as->length + len + 1) =3D=3D NULL)
-		__archive_errx(1, "Out of memory");
+		return (-1);
=20
 	p =3D as->s + as->length;
 	end =3D as->s + as->buffer_length - MB_CUR_MAX -1;
@@ -904,7 +790,7 @@
 			/* Re-allocate buffer for MBS. */
 			if (archive_string_ensure(as,
 			    as->length + len * 2 + 1) =3D=3D NULL)
-				__archive_errx(1, "Out of memory");
+				return (-1);
 			p =3D as->s + as->length;
 			end =3D as->s + as->buffer_length - MB_CUR_MAX -1;
 		}
@@ -946,6 +832,7 @@
 	(void)as;/* UNUSED */
 	(void)w;/* UNUSED */
 	(void)len;/* UNUSED */
+	errno =3D ENOSYS;
 	return (-1);
 }
=20
@@ -987,27 +874,6 @@
 	*psc =3D sc;
 }
=20
-#if defined(__APPLE__)
-
-static int
-createUniInfo(struct archive_string_conv *sconv)
-{
-	UnicodeMapping map;
-	OSStatus err;
-
-	map.unicodeEncoding =3D CreateTextEncoding(kTextEncodingUnicodeDefault,
-	    kUnicodeNoSubset, kUnicode16BitFormat);
-	map.otherEncoding =3D CreateTextEncoding(kTextEncodingUnicodeDefault,
-	    kUnicodeHFSPlusDecompVariant, kUnicode16BitFormat);
-	map.mappingVersion =3D kUnicodeUseLatestMapping;
-
-	sconv->uniInfo =3D NULL;
-	err =3D CreateUnicodeToTextInfo(&map, &(sconv->uniInfo));
-	return ((err =3D=3D noErr)? 0: -1);
-}
-
-#endif /* __APPLE__ */
-
 static void
 add_converter(struct archive_string_conv *sc, int (*converter)
     (struct archive_string *, const void *, size_t,
@@ -1066,9 +932,11 @@
=20
 		if (sc->flag & SCONV_BEST_EFFORT) {
 			if (sc->flag & SCONV_TO_UTF16BE)
-				add_converter(sc, best_effort_strncat_to_utf16be);
+				add_converter(sc,
+					best_effort_strncat_to_utf16be);
 			else
-				add_converter(sc, best_effort_strncat_to_utf16le);
+				add_converter(sc,
+					best_effort_strncat_to_utf16le);
 		} else
 			/* Make sure we have no converter. */
 			sc->nconverter =3D 0;
@@ -1082,12 +950,9 @@
 		/*
 		 * 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)
+		else if (sc->flag & SCONV_NORMALIZATION_C)
 			add_converter(sc, archive_string_normalize_C);
=20
 		if (sc->flag & SCONV_TO_UTF8) {
@@ -1135,12 +1000,9 @@
 		/*
 		 * 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)
+		else if (sc->flag & SCONV_NORMALIZATION_C)
 			add_converter(sc, archive_string_normalize_C);
=20
 		/*
@@ -1174,6 +1036,16 @@
 #if HAVE_ICONV
 	if (sc->cd !=3D (iconv_t)-1) {
 		add_converter(sc, iconv_strncat_in_locale);
+		/*
+		 * iconv generally does not support UTF-8-MAC and so
+		 * we have to the output of iconv from NFC to NFD if
+		 * need.
+		 */
+		if ((sc->flag & SCONV_FROM_CHARSET) &&
+		    (sc->flag & SCONV_TO_UTF8)) {
+			if (sc->flag & SCONV_NORMALIZATION_D)
+				add_converter(sc, archive_string_normalize_D);
+		}
 		return;
 	}
 #endif
@@ -1253,10 +1125,6 @@
 		return (NULL);
 	}
 	archive_string_init(&sc->utftmp);
-#if defined(__APPLE__)
-	archive_string_init(&sc->utf16nfc);
-	archive_string_init(&sc->utf16nfd);
-#endif
=20
 	if (flag & SCONV_TO_CHARSET) {
 		/*
@@ -1335,13 +1203,35 @@
 	if ((flag & SCONV_FROM_CHARSET) &&
 	    (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8))) {
 #if defined(__APPLE__)
-		if (flag & SCONV_TO_UTF8) {
-			if (createUniInfo(sc) =3D=3D 0)
-				flag |=3D SCONV_NORMALIZATION_D;
-		} else
+		if (flag & SCONV_TO_UTF8)
+			flag |=3D SCONV_NORMALIZATION_D;
+		else
 #endif
 			flag |=3D SCONV_NORMALIZATION_C;
 	}
+#if defined(__APPLE__)
+	/*
+	 * In case writing an archive file, make sure that a filename
+	 * going to be passed to iconv is a Unicode NFC string since
+	 * a filename in HFS Plus filesystem is a Unicode NFD one and
+	 * iconv cannot handle it with "UTF-8" charset. It is simpler
+	 * than a use of "UTF-8-MAC" charset.
+	 */
+	if ((flag & SCONV_TO_CHARSET) &&
+	    (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) &&
+	    !(flag & (SCONV_TO_UTF16 | SCONV_TO_UTF8)))
+		flag |=3D SCONV_NORMALIZATION_C;
+	/*
+	 * In case reading an archive file. make sure that a filename
+	 * will be passed to users is a Unicode NFD string in order to
+	 * correctly compare the filename with other one which comes
+	 * from HFS Plus filesystem.
+	 */
+	if ((flag & SCONV_FROM_CHARSET) &&
+	   !(flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) &&
+	    (flag & SCONV_TO_UTF8))
+		flag |=3D SCONV_NORMALIZATION_D;
+#endif
=20
 #if defined(HAVE_ICONV)
 	sc->cd_w =3D (iconv_t)-1;
@@ -1353,46 +1243,6 @@
 	    (flag & SCONV_WIN_CP)) {
 		/* This case we won't use iconv. */
 		sc->cd =3D (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 =3D iconv_open("UTF-8-MAC", fc);
-		if (sc->cd =3D=3D (iconv_t)-1) {
-			if ((sc->flag & SCONV_BEST_EFFORT) &&
-			    strcmp(fc, "CP932") =3D=3D 0) {
-				sc->cd =3D iconv_open("UTF-8-MAC", "SJIS");
-				if (sc->cd =3D=3D (iconv_t)-1) {
-					sc->cd =3D iconv_open(tc, fc);
-					if (sc->cd =3D=3D (iconv_t)-1)
-						sc->cd =3D iconv_open(tc, "SJIS");
-				}
-			} else
-				sc->cd =3D 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 =3D iconv_open(tc, "UTF-8-MAC");
-		if (sc->cd =3D=3D (iconv_t)-1) {
-			if ((sc->flag & SCONV_BEST_EFFORT) &&
-			    strcmp(tc, "CP932") =3D=3D 0) {
-				sc->cd =3D iconv_open("SJIS", "UTF-8-MAC");
-				if (sc->cd =3D=3D (iconv_t)-1) {
-					sc->cd =3D iconv_open(tc, fc);
-					if (sc->cd =3D=3D (iconv_t)-1)
-						sc->cd =3D iconv_open("SJIS", fc);
-				}
-			} else
-				sc->cd =3D iconv_open(tc, fc);
-		}
-#endif
 	} else {
 		sc->cd =3D iconv_open(tc, fc);
 		if (sc->cd =3D=3D (iconv_t)-1 && (sc->flag & SCONV_BEST_EFFORT)) {
@@ -1428,7 +1278,7 @@
 	sc->flag =3D flag;
=20
 	/*
-	 * Setup converters.
+	 * Set up converters.
 	 */
 	setup_converter(sc);
=20
@@ -1450,12 +1300,6 @@
 	if (sc->cd_w !=3D (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 !=3D NULL)
-		DisposeUnicodeToTextInfo(&(sc->uniInfo));
-#endif
 	free(sc);
 }
=20
@@ -1995,11 +1839,37 @@
 #else
 		if ((sc->flag & SCONV_UTF8_LIBARCHIVE_2) =3D=3D 0) {
 			sc->flag |=3D SCONV_UTF8_LIBARCHIVE_2;
-			/* Re-setup string converters. */
+			/* Set up string converters. */
 			setup_converter(sc);
 		}
 #endif
 		break;
+	case SCONV_SET_OPT_NORMALIZATION_C:
+		if ((sc->flag & SCONV_NORMALIZATION_C) =3D=3D 0) {
+			sc->flag |=3D SCONV_NORMALIZATION_C;
+			sc->flag &=3D ~SCONV_NORMALIZATION_D;
+			/* Set up string converters. */
+			setup_converter(sc);
+		}
+		break;
+	case SCONV_SET_OPT_NORMALIZATION_D:
+#if defined(HAVE_ICONV)
+		/*
+		 * If iconv will take the string, do not change the
+		 * setting of the normalization.
+		 */
+		if (!(sc->flag & SCONV_WIN_CP) &&
+		     (sc->flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) &&
+		    !(sc->flag & (SCONV_TO_UTF16 | SCONV_TO_UTF8)))
+			break;
+#endif
+		if ((sc->flag & SCONV_NORMALIZATION_D) =3D=3D 0) {
+			sc->flag |=3D SCONV_NORMALIZATION_D;
+			sc->flag &=3D ~SCONV_NORMALIZATION_C;
+			/* Set up string converters. */
+			setup_converter(sc);
+		}
+		break;
 	default:
 		break;
 	}
@@ -2009,8 +1879,8 @@
  *
  * Copy one archive_string to another in locale conversion.
  *
- *	archive_strncpy_in_locale();
- *	archive_strcpy_in_locale();
+ *	archive_strncat_l();
+ *	archive_strncpy_l();
  *
  */
=20
@@ -2056,15 +1926,15 @@
 }
=20
 int
-archive_strncpy_in_locale(struct archive_string *as, const void *_p, size_=
t n,
+archive_strncpy_l(struct archive_string *as, const void *_p, size_t n,
     struct archive_string_conv *sc)
 {
 	as->length =3D 0;
-	return (archive_strncat_in_locale(as, _p, n, sc));
+	return (archive_strncat_l(as, _p, n, sc));
 }
=20
 int
-archive_strncat_in_locale(struct archive_string *as, const void *_p, size_=
t n,
+archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
     struct archive_string_conv *sc)
 {
 	const void *s;
@@ -2291,7 +2161,6 @@
 	const char *p =3D (const char *)_p;
 	size_t r;
=20
-	(void)sc; /* UNUSED */
 #if HAVE_MBRTOWC
 	mbstate_t shift_state;
=20
@@ -2315,6 +2184,7 @@
 		p +=3D r;
 		n -=3D r;
 	}
+	(void)sc; /* UNUSED */
 	return (0); /* All Okey. */
 }
=20
@@ -2773,8 +2643,8 @@
  * 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)
+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;
@@ -3320,7 +3190,50 @@
 	return (ret);
 }
=20
-#if defined(__APPLE__)
+static int
+get_nfd(uint32_t *cp1, uint32_t *cp2, uint32_t uc)
+{
+	int t, b;
+
+	/*
+	 * These are not converted to NFD on Mac OS.
+	 */
+	if ((uc >=3D 0x2000 && uc <=3D 0x2FFF) ||
+	    (uc >=3D 0xF900 && uc <=3D 0xFAFF) ||
+	    (uc >=3D 0x2F800 && uc <=3D 0x2FAFF))
+		return (0);
+	/*
+	 * Those code points are not converted to NFD on Mac OS.
+	 * I do not know the reason because it is undocumented.
+	 *   NFC        NFD
+	 *   1109A  =3D=3D> 11099 110BA
+	 *   1109C  =3D=3D> 1109B 110BA
+	 *   110AB  =3D=3D> 110A5 110BA
+	 */
+	if (uc =3D=3D 0x1109A || uc =3D=3D 0x1109C || uc =3D=3D 0x110AB)
+		return (0);
+
+	t =3D 0;
+	b =3D sizeof(u_decomposition_table)/sizeof(u_decomposition_table[0]) -1;
+	while (b >=3D t) {
+		int m =3D (t + b) / 2;
+		if (u_decomposition_table[m].nfc < uc)
+			t =3D m + 1;
+		else if (u_decomposition_table[m].nfc > uc)
+			b =3D m - 1;
+		else {
+			*cp1 =3D u_decomposition_table[m].cp1;
+			*cp2 =3D u_decomposition_table[m].cp2;
+			return (1);
+		}
+	}
+	return (0);
+}
+
+#define REPLACE_UC_WITH(cp) do {		\
+	uc =3D cp;				\
+	ucptr =3D NULL;				\
+} while (0)
=20
 /*
  * Normalize UTF-8 characters to Form D and copy the result.
@@ -3329,110 +3242,170 @@
 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 =3D sc->flag;/* save a flag. */
-	sc->flag &=3D ~(SCONV_TO_UTF16BE | SCONV_TO_UTF8);
-	sc->flag |=3D SCONV_TO_UTF16LE;
-	ret =3D archive_string_append_unicode(&(sc->utf16nfc), _p, len, sc);
-	sc->flag =3D saved_flag;/* restore the saved flag */
-	if (archive_strlen(&(sc->utf16nfc)) =3D=3D 0) {
-		if (archive_string_ensure(as, as->length + 1) =3D=3D NULL)
-			return (-1);
-		return (ret);
-	}
-
-	/*
-	 * Normalize an NFC string to be an NFD(HFS Plus version).
-	 */
-	newsize =3D sc->utf16nfc.length + 2;
-	if (archive_string_ensure(&(sc->utf16nfd), newsize) =3D=3D NULL)
-		return (-1);
-
-	inp =3D (UniChar *)sc->utf16nfc.s;
-	inAvail =3D archive_strlen(&(sc->utf16nfc));
-	sc->utf16nfd.length =3D 0;
-	outp =3D sc->utf16nfd.s;
-	outAvail =3D sc->utf16nfd.buffer_length -2;
-
-	do {
-		/* Reinitialize all state information. */
-		if (ResetUnicodeToTextInfo(sc->uniInfo) !=3D noErr)
-			goto return_no_changed_data;
-
-		inCount =3D outCount =3D 0;
-		err =3D ConvertFromUnicodeToText(sc->uniInfo,
-		    inAvail, inp,
-		    kUnicodeDefaultDirectionMask, 0, NULL, NULL, NULL,
-		    outAvail, &inCount, &outCount, outp);
-
-		if (err =3D=3D noErr) {
-			sc->utf16nfd.length =3D outCount;
-			sc->utf16nfd.s[sc->utf16nfd.length] =3D 0;
-			sc->utf16nfd.s[sc->utf16nfd.length+1] =3D 0;
-		} else if (err =3D=3D kTECOutputBufferFullStatus) {
-			newsize =3D inAvail - inCount;
-			if (newsize > inAvail)
-				newsize =3D inAvail;
-			newsize +=3D sc->utf16nfd.buffer_length + 2;
-			if (archive_string_ensure(&(sc->utf16nfd), newsize)
-			    =3D=3D NULL)
-				return (-1);
-			outp =3D sc->utf16nfd.s;
-			outAvail =3D sc->utf16nfd.buffer_length -2;
-		} else
-			goto return_no_changed_data;
-	} while (err =3D=3D kTECOutputBufferFullStatus);
-
-	/*
-	 * If there is a next-step conversion, we should convert
-	 * a UTF-16LE(NFD) string back to the original Unicode type.
-	 */
-	saved_flag =3D sc->flag;/* save a flag. */
-	if (!(sc->flag &
-	    (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE | SCONV_TO_UTF8))) {
+	const char *s =3D (const char *)_p;
+	char *p, *endp;
+	uint32_t uc, uc2;
+	size_t w;
+	int always_replace, n, n2, ret =3D 0, spair, ts, tm;
+	int (*parse)(uint32_t *, const char *, size_t);
+	size_t (*unparse)(char *, size_t, uint32_t);
+
+	always_replace =3D 1;
+	ts =3D 1;/* text size. */
+	if (sc->flag & SCONV_TO_UTF16BE) {
+		unparse =3D unicode_to_utf16be;
+		ts =3D 2;
+		if (sc->flag & SCONV_FROM_UTF16BE)
+			always_replace =3D 0;
+	} else if (sc->flag & SCONV_TO_UTF16LE) {
+		unparse =3D unicode_to_utf16le;
+		ts =3D 2;
+		if (sc->flag & SCONV_FROM_UTF16LE)
+			always_replace =3D 0;
+	} else if (sc->flag & SCONV_TO_UTF8) {
+		unparse =3D unicode_to_utf8;
+		if (sc->flag & SCONV_FROM_UTF8)
+			always_replace =3D 0;
+	} else {
 		/*
 		 * This case is going to be converted to another
 		 * character-set through iconv.
 		 */
-		if (sc->flag & SCONV_FROM_UTF16BE)
-			sc->flag |=3D SCONV_TO_UTF16BE;
-		else if (sc->flag & SCONV_FROM_UTF16LE)
-			sc->flag |=3D SCONV_TO_UTF16LE;
+		always_replace =3D 0;
+		if (sc->flag & SCONV_FROM_UTF16BE) {
+			unparse =3D unicode_to_utf16be;
+			ts =3D 2;
+		} else if (sc->flag & SCONV_FROM_UTF16LE) {
+			unparse =3D unicode_to_utf16le;
+			ts =3D 2;
+		} else {
+			unparse =3D unicode_to_utf8;
+		}
+	}
+
+	if (sc->flag & SCONV_FROM_UTF16BE) {
+		parse =3D utf16be_to_unicode;
+		tm =3D 1;
+		spair =3D 4;/* surrogate pair size in UTF-16. */
+	} else if (sc->flag & SCONV_FROM_UTF16LE) {
+		parse =3D utf16le_to_unicode;
+		tm =3D 1;
+		spair =3D 4;/* surrogate pair size in UTF-16. */
+	} else {
+		parse =3D cesu8_to_unicode;
+		tm =3D ts;
+		spair =3D 6;/* surrogate pair size in UTF-8. */
+	}
+
+	if (archive_string_ensure(as, as->length + len * tm + ts) =3D=3D NULL)
+		return (-1);
+
+	p =3D as->s + as->length;
+	endp =3D as->s + as->buffer_length - ts;
+	while ((n =3D parse(&uc, s, len)) !=3D 0) {
+		const char *ucptr;
+		uint32_t cp1, cp2;
+		int SIndex;
+		struct {
+			uint32_t uc;
+			int ccc;
+		} fdc[FDC_MAX];
+		int fdi, fdj;
+		int ccc;
+
+check_first_code:
+		if (n < 0) {
+			/* Use a replaced unicode character. */
+			UNPARSE(p, endp, uc);
+			s +=3D n*-1;
+			len -=3D n*-1;
+			ret =3D -1;
+			continue;
+		} else if (n =3D=3D spair || always_replace)
+			/* uc is converted from a surrogate pair.
+			 * this should be treated as a changed code. */
+			ucptr =3D NULL;
 		else
-			sc->flag |=3D SCONV_TO_UTF8;
+			ucptr =3D s;
+		s +=3D n;
+		len -=3D n;
+
+		/* Hangul Decomposition. */
+		if ((SIndex =3D uc - HC_SBASE) >=3D 0 && SIndex < HC_SCOUNT) {
+			int L =3D HC_LBASE + SIndex / HC_NCOUNT;
+			int V =3D HC_VBASE + (SIndex % HC_NCOUNT) / HC_TCOUNT;
+			int T =3D HC_TBASE + SIndex % HC_TCOUNT;
+
+			REPLACE_UC_WITH(L);
+			WRITE_UC();
+			REPLACE_UC_WITH(V);
+			WRITE_UC();
+			if (T !=3D HC_TBASE) {
+				REPLACE_UC_WITH(T);
+				WRITE_UC();
+			}
+			continue;
+		}
+		if (IS_DECOMPOSABLE_BLOCK(uc) && CCC(uc) !=3D 0) {
+			WRITE_UC();
+			continue;
+		}
+
+		fdi =3D 0;
+		while (get_nfd(&cp1, &cp2, uc) && fdi < FDC_MAX) {
+			int k;
+
+			for (k =3D fdi; k > 0; k--)
+				fdc[k] =3D fdc[k-1];
+			fdc[0].ccc =3D CCC(cp2);
+			fdc[0].uc =3D cp2;
+			fdi++;
+			REPLACE_UC_WITH(cp1);
+		}
+
+		/* Read following code points. */
+		while ((n2 =3D parse(&uc2, s, len)) > 0 &&
+		    (ccc =3D CCC(uc2)) !=3D 0 && fdi < FDC_MAX) {
+			int j, k;
+
+			s +=3D n2;
+			len -=3D n2;
+			for (j =3D 0; j < fdi; j++) {
+				if (fdc[j].ccc > ccc)
+					break;
+			}
+			if (j < fdi) {
+				for (k =3D fdi; k > j; k--)
+					fdc[k] =3D fdc[k-1];
+				fdc[j].ccc =3D ccc;
+				fdc[j].uc =3D uc2;
+			} else {
+				fdc[fdi].ccc =3D ccc;
+				fdc[fdi].uc =3D uc2;
+			}
+			fdi++;
+		}
+
+		WRITE_UC();
+		for (fdj =3D 0; fdj < fdi; fdj++) {
+			REPLACE_UC_WITH(fdc[fdj].uc);
+			WRITE_UC();
+		}
+
+		if (n2 =3D=3D 0)
+			break;
+		REPLACE_UC_WITH(uc2);
+		n =3D n2;
+		ucptr =3D s;
+		goto check_first_code;
 	}
-	sc->flag &=3D ~(SCONV_FROM_UTF16BE | SCONV_FROM_UTF8);
-	sc->flag |=3D SCONV_FROM_UTF16LE;
-	if (archive_string_append_unicode(as, sc->utf16nfd.s,
-	    sc->utf16nfd.length, sc) !=3D 0)
-		ret =3D -1;
-	sc->flag =3D saved_flag;/* restore the saved flag */
+	as->length =3D p - as->s;
+	as->s[as->length] =3D '\0';
+	if (ts =3D=3D 2)
+		as->s[as->length+1] =3D '\0';
 	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);
 }
=20
-#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 fals=
e.
@@ -3629,15 +3602,15 @@
 }
=20
 static int
-win_strncat_from_utf16be(struct archive_string *as, const void *_p, size_t=
 bytes,
-    struct archive_string_conv *sc)
+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));
 }
=20
 static int
-win_strncat_from_utf16le(struct archive_string *as, const void *_p, size_t=
 bytes,
-    struct archive_string_conv *sc)
+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));
 }
@@ -3655,8 +3628,8 @@
  * Return -1 if conversion failes.
  */
 static int
-win_strncat_to_utf16(struct archive_string *as16, const void *_p, size_t l=
ength,
-    struct archive_string_conv *sc, int bigendian)
+win_strncat_to_utf16(struct archive_string *as16, const void *_p,
+    size_t length, struct archive_string_conv *sc, int bigendian)
 {
 	const char *s =3D (const char *)_p;
 	char *u16;
@@ -3732,15 +3705,15 @@
 }
=20
 static int
-win_strncat_to_utf16be(struct archive_string *as16, const void *_p, size_t=
 length,
-    struct archive_string_conv *sc)
+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));
 }
=20
 static int
-win_strncat_to_utf16le(struct archive_string *as16, const void *_p, size_t=
 length,
-    struct archive_string_conv *sc)
+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));
 }
@@ -3914,7 +3887,7 @@
 		sc =3D archive_string_conversion_to_charset(a, "UTF-8", 1);
 		if (sc =3D=3D NULL)
 			return (-1);/* Couldn't allocate memory for sc. */
-		r =3D archive_strncpy_in_locale(&(aes->aes_mbs), aes->aes_mbs.s,
+		r =3D archive_strncpy_l(&(aes->aes_mbs), aes->aes_mbs.s,
 		    aes->aes_mbs.length, sc);
 		if (a =3D=3D NULL)
 			free_sconv_object(sc);
@@ -4043,7 +4016,7 @@
 				*length =3D aes->aes_mbs.length;
 			return (0);
 		}
-		ret =3D archive_strncpy_in_locale(&(aes->aes_mbs_in_locale),
+		ret =3D archive_strncpy_l(&(aes->aes_mbs_in_locale),
 		    aes->aes_mbs.s, aes->aes_mbs.length, sc);
 		*p =3D aes->aes_mbs_in_locale.s;
 		if (length !=3D NULL)
@@ -4084,7 +4057,8 @@
 int
 archive_mstring_copy_wcs(struct archive_mstring *aes, const wchar_t *wcs)
 {
-	return archive_mstring_copy_wcs_len(aes, wcs, wcs =3D=3D NULL ? 0 : wcsle=
n(wcs));
+	return archive_mstring_copy_wcs_len(aes, wcs,
+				wcs =3D=3D NULL ? 0 : wcslen(wcs));
 }
=20
 int
@@ -4143,7 +4117,7 @@
 		 * Translate multi-bytes from some character-set to UTF-8.
 		 */=20
 		sc->cd =3D sc->cd_w;
-		r =3D archive_strncpy_in_locale(&(aes->aes_utf8), mbs, len, sc);
+		r =3D archive_strncpy_l(&(aes->aes_utf8), mbs, len, sc);
 		sc->cd =3D cd;
 		if (r !=3D 0) {
 			aes->aes_set =3D 0;
@@ -4175,7 +4149,7 @@
 			aes->aes_set =3D 0;
 	}
 #else
-	r =3D archive_strncpy_in_locale(&(aes->aes_mbs), mbs, len, sc);
+	r =3D archive_strncpy_l(&(aes->aes_mbs), mbs, len, sc);
 	if (r =3D=3D 0)
 		aes->aes_set =3D AES_SET_MBS; /* Only MBS form is set now. */
 	else
@@ -4219,7 +4193,7 @@
 	sc =3D archive_string_conversion_from_charset(a, "UTF-8", 1);
 	if (sc =3D=3D NULL)
 		return (-1);/* Couldn't allocate memory for sc. */
-	r =3D archive_strcpy_in_locale(&(aes->aes_mbs), utf8, sc);
+	r =3D archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
 	if (a =3D=3D NULL)
 		free_sconv_object(sc);
 	if (r !=3D 0)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_string.h
--- a/head/contrib/libarchive/libarchive/archive_string.h	Mon Jul 30 11:44:=
18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_string.h	Fri Aug 10 14:19:=
25 2012 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive/archive_string.h 232153 20=
12-02-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_string.h 238856 20=
12-07-28 06:38:44Z mm $
  *
  */
=20
@@ -110,18 +110,20 @@
 void
 archive_string_conversion_set_opt(struct archive_string_conv *, int);
 #define SCONV_SET_OPT_UTF8_LIBARCHIVE2X	1
+#define SCONV_SET_OPT_NORMALIZATION_C	2
+#define SCONV_SET_OPT_NORMALIZATION_D	4
=20
=20
 /* 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,
+archive_strncpy_l(struct archive_string *, const void *, size_t,
     struct archive_string_conv *);
=20
 /* 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,
+archive_strncat_l(struct archive_string *, const void *, size_t,
     struct archive_string_conv *);
=20
=20
@@ -162,8 +164,8 @@
 	archive_strncpy((as), (p), ((p) =3D=3D NULL ? 0 : strlen(p)))
 #define	archive_wstrcpy(as,p) \
 	archive_wstrncpy((as), (p), ((p) =3D=3D NULL ? 0 : wcslen(p)))
-#define	archive_strcpy_in_locale(as,p,lo) \
-	archive_strncpy_in_locale((as), (p), ((p) =3D=3D NULL ? 0 : strlen(p)), (=
lo))
+#define	archive_strcpy_l(as,p,lo) \
+	archive_strncpy_l((as), (p), ((p) =3D=3D NULL ? 0 : strlen(p)), (lo))
=20
 /* Copy a C string to an archive_string with limit, resizing as necessary.=
 */
 #define	archive_strncpy(as,p,l) \
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_string_composition.h
--- a/head/contrib/libarchive/libarchive/archive_string_composition.h	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_string_composition.h	Fri A=
ug 10 14:19:25 2012 +0300
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2011 libarchive Project
+ * Copyright (c) 2011-2012 libarchive Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@
 /*
  * ATTENTION!
  *  This file is generated by build/utils/gen_archive_string_composition_h=
.sh
- *  from http://unicode.org/Public/UNIDATA/UnicodeData.txt
+ *  from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
  *
  *  See also http://unicode.org/report/tr15/
  */
@@ -1348,4 +1348,945 @@
   0, 0, 0, 0, 0, 0, 0, 0, 0, 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,};
=20
+struct unicode_decomposition_table {
+	uint32_t nfc;
+	uint32_t cp1;
+	uint32_t cp2;
+};
+
+static const struct unicode_decomposition_table u_decomposition_table[] =
=3D {
+	{ 0x000C0 , 0x00041 , 0x00300 },
+	{ 0x000C1 , 0x00041 , 0x00301 },
+	{ 0x000C2 , 0x00041 , 0x00302 },
+	{ 0x000C3 , 0x00041 , 0x00303 },
+	{ 0x000C4 , 0x00041 , 0x00308 },
+	{ 0x000C5 , 0x00041 , 0x0030A },
+	{ 0x000C7 , 0x00043 , 0x00327 },
+	{ 0x000C8 , 0x00045 , 0x00300 },
+	{ 0x000C9 , 0x00045 , 0x00301 },
+	{ 0x000CA , 0x00045 , 0x00302 },
+	{ 0x000CB , 0x00045 , 0x00308 },
+	{ 0x000CC , 0x00049 , 0x00300 },
+	{ 0x000CD , 0x00049 , 0x00301 },
+	{ 0x000CE , 0x00049 , 0x00302 },
+	{ 0x000CF , 0x00049 , 0x00308 },
+	{ 0x000D1 , 0x0004E , 0x00303 },
+	{ 0x000D2 , 0x0004F , 0x00300 },
+	{ 0x000D3 , 0x0004F , 0x00301 },
+	{ 0x000D4 , 0x0004F , 0x00302 },
+	{ 0x000D5 , 0x0004F , 0x00303 },
+	{ 0x000D6 , 0x0004F , 0x00308 },
+	{ 0x000D9 , 0x00055 , 0x00300 },
+	{ 0x000DA , 0x00055 , 0x00301 },
+	{ 0x000DB , 0x00055 , 0x00302 },
+	{ 0x000DC , 0x00055 , 0x00308 },
+	{ 0x000DD , 0x00059 , 0x00301 },
+	{ 0x000E0 , 0x00061 , 0x00300 },
+	{ 0x000E1 , 0x00061 , 0x00301 },
+	{ 0x000E2 , 0x00061 , 0x00302 },
+	{ 0x000E3 , 0x00061 , 0x00303 },
+	{ 0x000E4 , 0x00061 , 0x00308 },
+	{ 0x000E5 , 0x00061 , 0x0030A },
+	{ 0x000E7 , 0x00063 , 0x00327 },
+	{ 0x000E8 , 0x00065 , 0x00300 },
+	{ 0x000E9 , 0x00065 , 0x00301 },
+	{ 0x000EA , 0x00065 , 0x00302 },
+	{ 0x000EB , 0x00065 , 0x00308 },
+	{ 0x000EC , 0x00069 , 0x00300 },
+	{ 0x000ED , 0x00069 , 0x00301 },
+	{ 0x000EE , 0x00069 , 0x00302 },
+	{ 0x000EF , 0x00069 , 0x00308 },
+	{ 0x000F1 , 0x0006E , 0x00303 },
+	{ 0x000F2 , 0x0006F , 0x00300 },
+	{ 0x000F3 , 0x0006F , 0x00301 },
+	{ 0x000F4 , 0x0006F , 0x00302 },
+	{ 0x000F5 , 0x0006F , 0x00303 },
+	{ 0x000F6 , 0x0006F , 0x00308 },
+	{ 0x000F9 , 0x00075 , 0x00300 },
+	{ 0x000FA , 0x00075 , 0x00301 },
+	{ 0x000FB , 0x00075 , 0x00302 },
+	{ 0x000FC , 0x00075 , 0x00308 },
+	{ 0x000FD , 0x00079 , 0x00301 },
+	{ 0x000FF , 0x00079 , 0x00308 },
+	{ 0x00100 , 0x00041 , 0x00304 },
+	{ 0x00101 , 0x00061 , 0x00304 },
+	{ 0x00102 , 0x00041 , 0x00306 },
+	{ 0x00103 , 0x00061 , 0x00306 },
+	{ 0x00104 , 0x00041 , 0x00328 },
+	{ 0x00105 , 0x00061 , 0x00328 },
+	{ 0x00106 , 0x00043 , 0x00301 },
+	{ 0x00107 , 0x00063 , 0x00301 },
+	{ 0x00108 , 0x00043 , 0x00302 },
+	{ 0x00109 , 0x00063 , 0x00302 },
+	{ 0x0010A , 0x00043 , 0x00307 },
+	{ 0x0010B , 0x00063 , 0x00307 },
+	{ 0x0010C , 0x00043 , 0x0030C },
+	{ 0x0010D , 0x00063 , 0x0030C },
+	{ 0x0010E , 0x00044 , 0x0030C },
+	{ 0x0010F , 0x00064 , 0x0030C },
+	{ 0x00112 , 0x00045 , 0x00304 },
+	{ 0x00113 , 0x00065 , 0x00304 },
+	{ 0x00114 , 0x00045 , 0x00306 },
+	{ 0x00115 , 0x00065 , 0x00306 },
+	{ 0x00116 , 0x00045 , 0x00307 },
+	{ 0x00117 , 0x00065 , 0x00307 },
+	{ 0x00118 , 0x00045 , 0x00328 },
+	{ 0x00119 , 0x00065 , 0x00328 },
+	{ 0x0011A , 0x00045 , 0x0030C },
+	{ 0x0011B , 0x00065 , 0x0030C },
+	{ 0x0011C , 0x00047 , 0x00302 },
+	{ 0x0011D , 0x00067 , 0x00302 },
+	{ 0x0011E , 0x00047 , 0x00306 },
+	{ 0x0011F , 0x00067 , 0x00306 },
+	{ 0x00120 , 0x00047 , 0x00307 },
+	{ 0x00121 , 0x00067 , 0x00307 },
+	{ 0x00122 , 0x00047 , 0x00327 },
+	{ 0x00123 , 0x00067 , 0x00327 },
+	{ 0x00124 , 0x00048 , 0x00302 },
+	{ 0x00125 , 0x00068 , 0x00302 },
+	{ 0x00128 , 0x00049 , 0x00303 },
+	{ 0x00129 , 0x00069 , 0x00303 },
+	{ 0x0012A , 0x00049 , 0x00304 },
+	{ 0x0012B , 0x00069 , 0x00304 },
+	{ 0x0012C , 0x00049 , 0x00306 },
+	{ 0x0012D , 0x00069 , 0x00306 },
+	{ 0x0012E , 0x00049 , 0x00328 },
+	{ 0x0012F , 0x00069 , 0x00328 },
+	{ 0x00130 , 0x00049 , 0x00307 },
+	{ 0x00134 , 0x0004A , 0x00302 },
+	{ 0x00135 , 0x0006A , 0x00302 },
+	{ 0x00136 , 0x0004B , 0x00327 },
+	{ 0x00137 , 0x0006B , 0x00327 },
+	{ 0x00139 , 0x0004C , 0x00301 },
+	{ 0x0013A , 0x0006C , 0x00301 },
+	{ 0x0013B , 0x0004C , 0x00327 },
+	{ 0x0013C , 0x0006C , 0x00327 },
+	{ 0x0013D , 0x0004C , 0x0030C },
+	{ 0x0013E , 0x0006C , 0x0030C },
+	{ 0x00143 , 0x0004E , 0x00301 },
+	{ 0x00144 , 0x0006E , 0x00301 },
+	{ 0x00145 , 0x0004E , 0x00327 },
+	{ 0x00146 , 0x0006E , 0x00327 },
+	{ 0x00147 , 0x0004E , 0x0030C },
+	{ 0x00148 , 0x0006E , 0x0030C },
+	{ 0x0014C , 0x0004F , 0x00304 },
+	{ 0x0014D , 0x0006F , 0x00304 },
+	{ 0x0014E , 0x0004F , 0x00306 },
+	{ 0x0014F , 0x0006F , 0x00306 },
+	{ 0x00150 , 0x0004F , 0x0030B },
+	{ 0x00151 , 0x0006F , 0x0030B },
+	{ 0x00154 , 0x00052 , 0x00301 },
+	{ 0x00155 , 0x00072 , 0x00301 },
+	{ 0x00156 , 0x00052 , 0x00327 },
+	{ 0x00157 , 0x00072 , 0x00327 },
+	{ 0x00158 , 0x00052 , 0x0030C },
+	{ 0x00159 , 0x00072 , 0x0030C },
+	{ 0x0015A , 0x00053 , 0x00301 },
+	{ 0x0015B , 0x00073 , 0x00301 },
+	{ 0x0015C , 0x00053 , 0x00302 },
+	{ 0x0015D , 0x00073 , 0x00302 },
+	{ 0x0015E , 0x00053 , 0x00327 },
+	{ 0x0015F , 0x00073 , 0x00327 },
+	{ 0x00160 , 0x00053 , 0x0030C },
+	{ 0x00161 , 0x00073 , 0x0030C },
+	{ 0x00162 , 0x00054 , 0x00327 },
+	{ 0x00163 , 0x00074 , 0x00327 },
+	{ 0x00164 , 0x00054 , 0x0030C },
+	{ 0x00165 , 0x00074 , 0x0030C },
+	{ 0x00168 , 0x00055 , 0x00303 },
+	{ 0x00169 , 0x00075 , 0x00303 },
+	{ 0x0016A , 0x00055 , 0x00304 },
+	{ 0x0016B , 0x00075 , 0x00304 },
+	{ 0x0016C , 0x00055 , 0x00306 },
+	{ 0x0016D , 0x00075 , 0x00306 },
+	{ 0x0016E , 0x00055 , 0x0030A },
+	{ 0x0016F , 0x00075 , 0x0030A },
+	{ 0x00170 , 0x00055 , 0x0030B },
+	{ 0x00171 , 0x00075 , 0x0030B },
+	{ 0x00172 , 0x00055 , 0x00328 },
+	{ 0x00173 , 0x00075 , 0x00328 },
+	{ 0x00174 , 0x00057 , 0x00302 },
+	{ 0x00175 , 0x00077 , 0x00302 },
+	{ 0x00176 , 0x00059 , 0x00302 },
+	{ 0x00177 , 0x00079 , 0x00302 },
+	{ 0x00178 , 0x00059 , 0x00308 },
+	{ 0x00179 , 0x0005A , 0x00301 },
+	{ 0x0017A , 0x0007A , 0x00301 },
+	{ 0x0017B , 0x0005A , 0x00307 },
+	{ 0x0017C , 0x0007A , 0x00307 },
+	{ 0x0017D , 0x0005A , 0x0030C },
+	{ 0x0017E , 0x0007A , 0x0030C },
+	{ 0x001A0 , 0x0004F , 0x0031B },
+	{ 0x001A1 , 0x0006F , 0x0031B },
+	{ 0x001AF , 0x00055 , 0x0031B },
+	{ 0x001B0 , 0x00075 , 0x0031B },
+	{ 0x001CD , 0x00041 , 0x0030C },
+	{ 0x001CE , 0x00061 , 0x0030C },
+	{ 0x001CF , 0x00049 , 0x0030C },
+	{ 0x001D0 , 0x00069 , 0x0030C },
+	{ 0x001D1 , 0x0004F , 0x0030C },
+	{ 0x001D2 , 0x0006F , 0x0030C },
+	{ 0x001D3 , 0x00055 , 0x0030C },
+	{ 0x001D4 , 0x00075 , 0x0030C },
+	{ 0x001D5 , 0x000DC , 0x00304 },
+	{ 0x001D6 , 0x000FC , 0x00304 },
+	{ 0x001D7 , 0x000DC , 0x00301 },
+	{ 0x001D8 , 0x000FC , 0x00301 },
+	{ 0x001D9 , 0x000DC , 0x0030C },
+	{ 0x001DA , 0x000FC , 0x0030C },
+	{ 0x001DB , 0x000DC , 0x00300 },
+	{ 0x001DC , 0x000FC , 0x00300 },
+	{ 0x001DE , 0x000C4 , 0x00304 },
+	{ 0x001DF , 0x000E4 , 0x00304 },
+	{ 0x001E0 , 0x00226 , 0x00304 },
+	{ 0x001E1 , 0x00227 , 0x00304 },
+	{ 0x001E2 , 0x000C6 , 0x00304 },
+	{ 0x001E3 , 0x000E6 , 0x00304 },
+	{ 0x001E6 , 0x00047 , 0x0030C },
+	{ 0x001E7 , 0x00067 , 0x0030C },
+	{ 0x001E8 , 0x0004B , 0x0030C },
+	{ 0x001E9 , 0x0006B , 0x0030C },
+	{ 0x001EA , 0x0004F , 0x00328 },
+	{ 0x001EB , 0x0006F , 0x00328 },
+	{ 0x001EC , 0x001EA , 0x00304 },
+	{ 0x001ED , 0x001EB , 0x00304 },
+	{ 0x001EE , 0x001B7 , 0x0030C },
+	{ 0x001EF , 0x00292 , 0x0030C },
+	{ 0x001F0 , 0x0006A , 0x0030C },
+	{ 0x001F4 , 0x00047 , 0x00301 },
+	{ 0x001F5 , 0x00067 , 0x00301 },
+	{ 0x001F8 , 0x0004E , 0x00300 },
+	{ 0x001F9 , 0x0006E , 0x00300 },
+	{ 0x001FA , 0x000C5 , 0x00301 },
+	{ 0x001FB , 0x000E5 , 0x00301 },
+	{ 0x001FC , 0x000C6 , 0x00301 },
+	{ 0x001FD , 0x000E6 , 0x00301 },
+	{ 0x001FE , 0x000D8 , 0x00301 },
+	{ 0x001FF , 0x000F8 , 0x00301 },
+	{ 0x00200 , 0x00041 , 0x0030F },
+	{ 0x00201 , 0x00061 , 0x0030F },
+	{ 0x00202 , 0x00041 , 0x00311 },
+	{ 0x00203 , 0x00061 , 0x00311 },
+	{ 0x00204 , 0x00045 , 0x0030F },
+	{ 0x00205 , 0x00065 , 0x0030F },
+	{ 0x00206 , 0x00045 , 0x00311 },
+	{ 0x00207 , 0x00065 , 0x00311 },
+	{ 0x00208 , 0x00049 , 0x0030F },
+	{ 0x00209 , 0x00069 , 0x0030F },
+	{ 0x0020A , 0x00049 , 0x00311 },
+	{ 0x0020B , 0x00069 , 0x00311 },
+	{ 0x0020C , 0x0004F , 0x0030F },
+	{ 0x0020D , 0x0006F , 0x0030F },
+	{ 0x0020E , 0x0004F , 0x00311 },
+	{ 0x0020F , 0x0006F , 0x00311 },
+	{ 0x00210 , 0x00052 , 0x0030F },
+	{ 0x00211 , 0x00072 , 0x0030F },
+	{ 0x00212 , 0x00052 , 0x00311 },
+	{ 0x00213 , 0x00072 , 0x00311 },
+	{ 0x00214 , 0x00055 , 0x0030F },
+	{ 0x00215 , 0x00075 , 0x0030F },
+	{ 0x00216 , 0x00055 , 0x00311 },
+	{ 0x00217 , 0x00075 , 0x00311 },
+	{ 0x00218 , 0x00053 , 0x00326 },
+	{ 0x00219 , 0x00073 , 0x00326 },
+	{ 0x0021A , 0x00054 , 0x00326 },
+	{ 0x0021B , 0x00074 , 0x00326 },
+	{ 0x0021E , 0x00048 , 0x0030C },
+	{ 0x0021F , 0x00068 , 0x0030C },
+	{ 0x00226 , 0x00041 , 0x00307 },
+	{ 0x00227 , 0x00061 , 0x00307 },
+	{ 0x00228 , 0x00045 , 0x00327 },
+	{ 0x00229 , 0x00065 , 0x00327 },
+	{ 0x0022A , 0x000D6 , 0x00304 },
+	{ 0x0022B , 0x000F6 , 0x00304 },
+	{ 0x0022C , 0x000D5 , 0x00304 },
+	{ 0x0022D , 0x000F5 , 0x00304 },
+	{ 0x0022E , 0x0004F , 0x00307 },
+	{ 0x0022F , 0x0006F , 0x00307 },
+	{ 0x00230 , 0x0022E , 0x00304 },
+	{ 0x00231 , 0x0022F , 0x00304 },
+	{ 0x00232 , 0x00059 , 0x00304 },
+	{ 0x00233 , 0x00079 , 0x00304 },
+	{ 0x00385 , 0x000A8 , 0x00301 },
+	{ 0x00386 , 0x00391 , 0x00301 },
+	{ 0x00388 , 0x00395 , 0x00301 },
+	{ 0x00389 , 0x00397 , 0x00301 },
+	{ 0x0038A , 0x00399 , 0x00301 },
+	{ 0x0038C , 0x0039F , 0x00301 },
+	{ 0x0038E , 0x003A5 , 0x00301 },
+	{ 0x0038F , 0x003A9 , 0x00301 },
+	{ 0x00390 , 0x003CA , 0x00301 },
+	{ 0x003AA , 0x00399 , 0x00308 },
+	{ 0x003AB , 0x003A5 , 0x00308 },
+	{ 0x003AC , 0x003B1 , 0x00301 },
+	{ 0x003AD , 0x003B5 , 0x00301 },
+	{ 0x003AE , 0x003B7 , 0x00301 },
+	{ 0x003AF , 0x003B9 , 0x00301 },
+	{ 0x003B0 , 0x003CB , 0x00301 },
+	{ 0x003CA , 0x003B9 , 0x00308 },
+	{ 0x003CB , 0x003C5 , 0x00308 },
+	{ 0x003CC , 0x003BF , 0x00301 },
+	{ 0x003CD , 0x003C5 , 0x00301 },
+	{ 0x003CE , 0x003C9 , 0x00301 },
+	{ 0x003D3 , 0x003D2 , 0x00301 },
+	{ 0x003D4 , 0x003D2 , 0x00308 },
+	{ 0x00400 , 0x00415 , 0x00300 },
+	{ 0x00401 , 0x00415 , 0x00308 },
+	{ 0x00403 , 0x00413 , 0x00301 },
+	{ 0x00407 , 0x00406 , 0x00308 },
+	{ 0x0040C , 0x0041A , 0x00301 },
+	{ 0x0040D , 0x00418 , 0x00300 },
+	{ 0x0040E , 0x00423 , 0x00306 },
+	{ 0x00419 , 0x00418 , 0x00306 },
+	{ 0x00439 , 0x00438 , 0x00306 },
+	{ 0x00450 , 0x00435 , 0x00300 },
+	{ 0x00451 , 0x00435 , 0x00308 },
+	{ 0x00453 , 0x00433 , 0x00301 },
+	{ 0x00457 , 0x00456 , 0x00308 },
+	{ 0x0045C , 0x0043A , 0x00301 },
+	{ 0x0045D , 0x00438 , 0x00300 },
+	{ 0x0045E , 0x00443 , 0x00306 },
+	{ 0x00476 , 0x00474 , 0x0030F },
+	{ 0x00477 , 0x00475 , 0x0030F },
+	{ 0x004C1 , 0x00416 , 0x00306 },
+	{ 0x004C2 , 0x00436 , 0x00306 },
+	{ 0x004D0 , 0x00410 , 0x00306 },
+	{ 0x004D1 , 0x00430 , 0x00306 },
+	{ 0x004D2 , 0x00410 , 0x00308 },
+	{ 0x004D3 , 0x00430 , 0x00308 },
+	{ 0x004D6 , 0x00415 , 0x00306 },
+	{ 0x004D7 , 0x00435 , 0x00306 },
+	{ 0x004DA , 0x004D8 , 0x00308 },
+	{ 0x004DB , 0x004D9 , 0x00308 },
+	{ 0x004DC , 0x00416 , 0x00308 },
+	{ 0x004DD , 0x00436 , 0x00308 },
+	{ 0x004DE , 0x00417 , 0x00308 },
+	{ 0x004DF , 0x00437 , 0x00308 },
+	{ 0x004E2 , 0x00418 , 0x00304 },
+	{ 0x004E3 , 0x00438 , 0x00304 },
+	{ 0x004E4 , 0x00418 , 0x00308 },
+	{ 0x004E5 , 0x00438 , 0x00308 },
+	{ 0x004E6 , 0x0041E , 0x00308 },
+	{ 0x004E7 , 0x0043E , 0x00308 },
+	{ 0x004EA , 0x004E8 , 0x00308 },
+	{ 0x004EB , 0x004E9 , 0x00308 },
+	{ 0x004EC , 0x0042D , 0x00308 },
+	{ 0x004ED , 0x0044D , 0x00308 },
+	{ 0x004EE , 0x00423 , 0x00304 },
+	{ 0x004EF , 0x00443 , 0x00304 },
+	{ 0x004F0 , 0x00423 , 0x00308 },
+	{ 0x004F1 , 0x00443 , 0x00308 },
+	{ 0x004F2 , 0x00423 , 0x0030B },
+	{ 0x004F3 , 0x00443 , 0x0030B },
+	{ 0x004F4 , 0x00427 , 0x00308 },
+	{ 0x004F5 , 0x00447 , 0x00308 },
+	{ 0x004F8 , 0x0042B , 0x00308 },
+	{ 0x004F9 , 0x0044B , 0x00308 },
+	{ 0x00622 , 0x00627 , 0x00653 },
+	{ 0x00623 , 0x00627 , 0x00654 },
+	{ 0x00624 , 0x00648 , 0x00654 },
+	{ 0x00625 , 0x00627 , 0x00655 },
+	{ 0x00626 , 0x0064A , 0x00654 },
+	{ 0x006C0 , 0x006D5 , 0x00654 },
+	{ 0x006C2 , 0x006C1 , 0x00654 },
+	{ 0x006D3 , 0x006D2 , 0x00654 },
+	{ 0x00929 , 0x00928 , 0x0093C },
+	{ 0x00931 , 0x00930 , 0x0093C },
+	{ 0x00934 , 0x00933 , 0x0093C },
+	{ 0x009CB , 0x009C7 , 0x009BE },
+	{ 0x009CC , 0x009C7 , 0x009D7 },
+	{ 0x00B48 , 0x00B47 , 0x00B56 },
+	{ 0x00B4B , 0x00B47 , 0x00B3E },
+	{ 0x00B4C , 0x00B47 , 0x00B57 },
+	{ 0x00B94 , 0x00B92 , 0x00BD7 },
+	{ 0x00BCA , 0x00BC6 , 0x00BBE },
+	{ 0x00BCB , 0x00BC7 , 0x00BBE },
+	{ 0x00BCC , 0x00BC6 , 0x00BD7 },
+	{ 0x00C48 , 0x00C46 , 0x00C56 },
+	{ 0x00CC0 , 0x00CBF , 0x00CD5 },
+	{ 0x00CC7 , 0x00CC6 , 0x00CD5 },
+	{ 0x00CC8 , 0x00CC6 , 0x00CD6 },
+	{ 0x00CCA , 0x00CC6 , 0x00CC2 },
+	{ 0x00CCB , 0x00CCA , 0x00CD5 },
+	{ 0x00D4A , 0x00D46 , 0x00D3E },
+	{ 0x00D4B , 0x00D47 , 0x00D3E },
+	{ 0x00D4C , 0x00D46 , 0x00D57 },
+	{ 0x00DDA , 0x00DD9 , 0x00DCA },
+	{ 0x00DDC , 0x00DD9 , 0x00DCF },
+	{ 0x00DDD , 0x00DDC , 0x00DCA },
+	{ 0x00DDE , 0x00DD9 , 0x00DDF },
+	{ 0x01026 , 0x01025 , 0x0102E },
+	{ 0x01B06 , 0x01B05 , 0x01B35 },
+	{ 0x01B08 , 0x01B07 , 0x01B35 },
+	{ 0x01B0A , 0x01B09 , 0x01B35 },
+	{ 0x01B0C , 0x01B0B , 0x01B35 },
+	{ 0x01B0E , 0x01B0D , 0x01B35 },
+	{ 0x01B12 , 0x01B11 , 0x01B35 },
+	{ 0x01B3B , 0x01B3A , 0x01B35 },
+	{ 0x01B3D , 0x01B3C , 0x01B35 },
+	{ 0x01B40 , 0x01B3E , 0x01B35 },
+	{ 0x01B41 , 0x01B3F , 0x01B35 },
+	{ 0x01B43 , 0x01B42 , 0x01B35 },
+	{ 0x01E00 , 0x00041 , 0x00325 },
+	{ 0x01E01 , 0x00061 , 0x00325 },
+	{ 0x01E02 , 0x00042 , 0x00307 },
+	{ 0x01E03 , 0x00062 , 0x00307 },
+	{ 0x01E04 , 0x00042 , 0x00323 },
+	{ 0x01E05 , 0x00062 , 0x00323 },
+	{ 0x01E06 , 0x00042 , 0x00331 },
+	{ 0x01E07 , 0x00062 , 0x00331 },
+	{ 0x01E08 , 0x000C7 , 0x00301 },
+	{ 0x01E09 , 0x000E7 , 0x00301 },
+	{ 0x01E0A , 0x00044 , 0x00307 },
+	{ 0x01E0B , 0x00064 , 0x00307 },
+	{ 0x01E0C , 0x00044 , 0x00323 },
+	{ 0x01E0D , 0x00064 , 0x00323 },
+	{ 0x01E0E , 0x00044 , 0x00331 },
+	{ 0x01E0F , 0x00064 , 0x00331 },
+	{ 0x01E10 , 0x00044 , 0x00327 },
+	{ 0x01E11 , 0x00064 , 0x00327 },
+	{ 0x01E12 , 0x00044 , 0x0032D },
+	{ 0x01E13 , 0x00064 , 0x0032D },
+	{ 0x01E14 , 0x00112 , 0x00300 },
+	{ 0x01E15 , 0x00113 , 0x00300 },
+	{ 0x01E16 , 0x00112 , 0x00301 },
+	{ 0x01E17 , 0x00113 , 0x00301 },
+	{ 0x01E18 , 0x00045 , 0x0032D },
+	{ 0x01E19 , 0x00065 , 0x0032D },
+	{ 0x01E1A , 0x00045 , 0x00330 },
+	{ 0x01E1B , 0x00065 , 0x00330 },
+	{ 0x01E1C , 0x00228 , 0x00306 },
+	{ 0x01E1D , 0x00229 , 0x00306 },
+	{ 0x01E1E , 0x00046 , 0x00307 },
+	{ 0x01E1F , 0x00066 , 0x00307 },
+	{ 0x01E20 , 0x00047 , 0x00304 },
+	{ 0x01E21 , 0x00067 , 0x00304 },
+	{ 0x01E22 , 0x00048 , 0x00307 },
+	{ 0x01E23 , 0x00068 , 0x00307 },
+	{ 0x01E24 , 0x00048 , 0x00323 },
+	{ 0x01E25 , 0x00068 , 0x00323 },
+	{ 0x01E26 , 0x00048 , 0x00308 },
+	{ 0x01E27 , 0x00068 , 0x00308 },
+	{ 0x01E28 , 0x00048 , 0x00327 },
+	{ 0x01E29 , 0x00068 , 0x00327 },
+	{ 0x01E2A , 0x00048 , 0x0032E },
+	{ 0x01E2B , 0x00068 , 0x0032E },
+	{ 0x01E2C , 0x00049 , 0x00330 },
+	{ 0x01E2D , 0x00069 , 0x00330 },
+	{ 0x01E2E , 0x000CF , 0x00301 },
+	{ 0x01E2F , 0x000EF , 0x00301 },
+	{ 0x01E30 , 0x0004B , 0x00301 },
+	{ 0x01E31 , 0x0006B , 0x00301 },
+	{ 0x01E32 , 0x0004B , 0x00323 },
+	{ 0x01E33 , 0x0006B , 0x00323 },
+	{ 0x01E34 , 0x0004B , 0x00331 },
+	{ 0x01E35 , 0x0006B , 0x00331 },
+	{ 0x01E36 , 0x0004C , 0x00323 },
+	{ 0x01E37 , 0x0006C , 0x00323 },
+	{ 0x01E38 , 0x01E36 , 0x00304 },
+	{ 0x01E39 , 0x01E37 , 0x00304 },
+	{ 0x01E3A , 0x0004C , 0x00331 },
+	{ 0x01E3B , 0x0006C , 0x00331 },
+	{ 0x01E3C , 0x0004C , 0x0032D },
+	{ 0x01E3D , 0x0006C , 0x0032D },
+	{ 0x01E3E , 0x0004D , 0x00301 },
+	{ 0x01E3F , 0x0006D , 0x00301 },
+	{ 0x01E40 , 0x0004D , 0x00307 },
+	{ 0x01E41 , 0x0006D , 0x00307 },
+	{ 0x01E42 , 0x0004D , 0x00323 },
+	{ 0x01E43 , 0x0006D , 0x00323 },
+	{ 0x01E44 , 0x0004E , 0x00307 },
+	{ 0x01E45 , 0x0006E , 0x00307 },
+	{ 0x01E46 , 0x0004E , 0x00323 },
+	{ 0x01E47 , 0x0006E , 0x00323 },
+	{ 0x01E48 , 0x0004E , 0x00331 },
+	{ 0x01E49 , 0x0006E , 0x00331 },
+	{ 0x01E4A , 0x0004E , 0x0032D },
+	{ 0x01E4B , 0x0006E , 0x0032D },
+	{ 0x01E4C , 0x000D5 , 0x00301 },
+	{ 0x01E4D , 0x000F5 , 0x00301 },
+	{ 0x01E4E , 0x000D5 , 0x00308 },
+	{ 0x01E4F , 0x000F5 , 0x00308 },
+	{ 0x01E50 , 0x0014C , 0x00300 },
+	{ 0x01E51 , 0x0014D , 0x00300 },
+	{ 0x01E52 , 0x0014C , 0x00301 },
+	{ 0x01E53 , 0x0014D , 0x00301 },
+	{ 0x01E54 , 0x00050 , 0x00301 },
+	{ 0x01E55 , 0x00070 , 0x00301 },
+	{ 0x01E56 , 0x00050 , 0x00307 },
+	{ 0x01E57 , 0x00070 , 0x00307 },
+	{ 0x01E58 , 0x00052 , 0x00307 },
+	{ 0x01E59 , 0x00072 , 0x00307 },
+	{ 0x01E5A , 0x00052 , 0x00323 },
+	{ 0x01E5B , 0x00072 , 0x00323 },
+	{ 0x01E5C , 0x01E5A , 0x00304 },
+	{ 0x01E5D , 0x01E5B , 0x00304 },
+	{ 0x01E5E , 0x00052 , 0x00331 },
+	{ 0x01E5F , 0x00072 , 0x00331 },
+	{ 0x01E60 , 0x00053 , 0x00307 },
+	{ 0x01E61 , 0x00073 , 0x00307 },
+	{ 0x01E62 , 0x00053 , 0x00323 },
+	{ 0x01E63 , 0x00073 , 0x00323 },
+	{ 0x01E64 , 0x0015A , 0x00307 },
+	{ 0x01E65 , 0x0015B , 0x00307 },
+	{ 0x01E66 , 0x00160 , 0x00307 },
+	{ 0x01E67 , 0x00161 , 0x00307 },
+	{ 0x01E68 , 0x01E62 , 0x00307 },
+	{ 0x01E69 , 0x01E63 , 0x00307 },
+	{ 0x01E6A , 0x00054 , 0x00307 },
+	{ 0x01E6B , 0x00074 , 0x00307 },
+	{ 0x01E6C , 0x00054 , 0x00323 },
+	{ 0x01E6D , 0x00074 , 0x00323 },
+	{ 0x01E6E , 0x00054 , 0x00331 },
+	{ 0x01E6F , 0x00074 , 0x00331 },
+	{ 0x01E70 , 0x00054 , 0x0032D },
+	{ 0x01E71 , 0x00074 , 0x0032D },
+	{ 0x01E72 , 0x00055 , 0x00324 },
+	{ 0x01E73 , 0x00075 , 0x00324 },
+	{ 0x01E74 , 0x00055 , 0x00330 },
+	{ 0x01E75 , 0x00075 , 0x00330 },
+	{ 0x01E76 , 0x00055 , 0x0032D },
+	{ 0x01E77 , 0x00075 , 0x0032D },
+	{ 0x01E78 , 0x00168 , 0x00301 },
+	{ 0x01E79 , 0x00169 , 0x00301 },
+	{ 0x01E7A , 0x0016A , 0x00308 },
+	{ 0x01E7B , 0x0016B , 0x00308 },
+	{ 0x01E7C , 0x00056 , 0x00303 },
+	{ 0x01E7D , 0x00076 , 0x00303 },
+	{ 0x01E7E , 0x00056 , 0x00323 },
+	{ 0x01E7F , 0x00076 , 0x00323 },
+	{ 0x01E80 , 0x00057 , 0x00300 },
+	{ 0x01E81 , 0x00077 , 0x00300 },
+	{ 0x01E82 , 0x00057 , 0x00301 },
+	{ 0x01E83 , 0x00077 , 0x00301 },
+	{ 0x01E84 , 0x00057 , 0x00308 },
+	{ 0x01E85 , 0x00077 , 0x00308 },
+	{ 0x01E86 , 0x00057 , 0x00307 },
+	{ 0x01E87 , 0x00077 , 0x00307 },
+	{ 0x01E88 , 0x00057 , 0x00323 },
+	{ 0x01E89 , 0x00077 , 0x00323 },
+	{ 0x01E8A , 0x00058 , 0x00307 },
+	{ 0x01E8B , 0x00078 , 0x00307 },
+	{ 0x01E8C , 0x00058 , 0x00308 },
+	{ 0x01E8D , 0x00078 , 0x00308 },
+	{ 0x01E8E , 0x00059 , 0x00307 },
+	{ 0x01E8F , 0x00079 , 0x00307 },
+	{ 0x01E90 , 0x0005A , 0x00302 },
+	{ 0x01E91 , 0x0007A , 0x00302 },
+	{ 0x01E92 , 0x0005A , 0x00323 },
+	{ 0x01E93 , 0x0007A , 0x00323 },
+	{ 0x01E94 , 0x0005A , 0x00331 },
+	{ 0x01E95 , 0x0007A , 0x00331 },
+	{ 0x01E96 , 0x00068 , 0x00331 },
+	{ 0x01E97 , 0x00074 , 0x00308 },
+	{ 0x01E98 , 0x00077 , 0x0030A },
+	{ 0x01E99 , 0x00079 , 0x0030A },
+	{ 0x01E9B , 0x0017F , 0x00307 },
+	{ 0x01EA0 , 0x00041 , 0x00323 },
+	{ 0x01EA1 , 0x00061 , 0x00323 },
+	{ 0x01EA2 , 0x00041 , 0x00309 },
+	{ 0x01EA3 , 0x00061 , 0x00309 },
+	{ 0x01EA4 , 0x000C2 , 0x00301 },
+	{ 0x01EA5 , 0x000E2 , 0x00301 },
+	{ 0x01EA6 , 0x000C2 , 0x00300 },
+	{ 0x01EA7 , 0x000E2 , 0x00300 },
+	{ 0x01EA8 , 0x000C2 , 0x00309 },
+	{ 0x01EA9 , 0x000E2 , 0x00309 },
+	{ 0x01EAA , 0x000C2 , 0x00303 },
+	{ 0x01EAB , 0x000E2 , 0x00303 },
+	{ 0x01EAC , 0x01EA0 , 0x00302 },
+	{ 0x01EAD , 0x01EA1 , 0x00302 },
+	{ 0x01EAE , 0x00102 , 0x00301 },
+	{ 0x01EAF , 0x00103 , 0x00301 },
+	{ 0x01EB0 , 0x00102 , 0x00300 },
+	{ 0x01EB1 , 0x00103 , 0x00300 },
+	{ 0x01EB2 , 0x00102 , 0x00309 },
+	{ 0x01EB3 , 0x00103 , 0x00309 },
+	{ 0x01EB4 , 0x00102 , 0x00303 },
+	{ 0x01EB5 , 0x00103 , 0x00303 },
+	{ 0x01EB6 , 0x01EA0 , 0x00306 },
+	{ 0x01EB7 , 0x01EA1 , 0x00306 },
+	{ 0x01EB8 , 0x00045 , 0x00323 },
+	{ 0x01EB9 , 0x00065 , 0x00323 },
+	{ 0x01EBA , 0x00045 , 0x00309 },
+	{ 0x01EBB , 0x00065 , 0x00309 },
+	{ 0x01EBC , 0x00045 , 0x00303 },
+	{ 0x01EBD , 0x00065 , 0x00303 },
+	{ 0x01EBE , 0x000CA , 0x00301 },
+	{ 0x01EBF , 0x000EA , 0x00301 },
+	{ 0x01EC0 , 0x000CA , 0x00300 },
+	{ 0x01EC1 , 0x000EA , 0x00300 },
+	{ 0x01EC2 , 0x000CA , 0x00309 },
+	{ 0x01EC3 , 0x000EA , 0x00309 },
+	{ 0x01EC4 , 0x000CA , 0x00303 },
+	{ 0x01EC5 , 0x000EA , 0x00303 },
+	{ 0x01EC6 , 0x01EB8 , 0x00302 },
+	{ 0x01EC7 , 0x01EB9 , 0x00302 },
+	{ 0x01EC8 , 0x00049 , 0x00309 },
+	{ 0x01EC9 , 0x00069 , 0x00309 },
+	{ 0x01ECA , 0x00049 , 0x00323 },
+	{ 0x01ECB , 0x00069 , 0x00323 },
+	{ 0x01ECC , 0x0004F , 0x00323 },
+	{ 0x01ECD , 0x0006F , 0x00323 },
+	{ 0x01ECE , 0x0004F , 0x00309 },
+	{ 0x01ECF , 0x0006F , 0x00309 },
+	{ 0x01ED0 , 0x000D4 , 0x00301 },
+	{ 0x01ED1 , 0x000F4 , 0x00301 },
+	{ 0x01ED2 , 0x000D4 , 0x00300 },
+	{ 0x01ED3 , 0x000F4 , 0x00300 },
+	{ 0x01ED4 , 0x000D4 , 0x00309 },
+	{ 0x01ED5 , 0x000F4 , 0x00309 },
+	{ 0x01ED6 , 0x000D4 , 0x00303 },
+	{ 0x01ED7 , 0x000F4 , 0x00303 },
+	{ 0x01ED8 , 0x01ECC , 0x00302 },
+	{ 0x01ED9 , 0x01ECD , 0x00302 },
+	{ 0x01EDA , 0x001A0 , 0x00301 },
+	{ 0x01EDB , 0x001A1 , 0x00301 },
+	{ 0x01EDC , 0x001A0 , 0x00300 },
+	{ 0x01EDD , 0x001A1 , 0x00300 },
+	{ 0x01EDE , 0x001A0 , 0x00309 },
+	{ 0x01EDF , 0x001A1 , 0x00309 },
+	{ 0x01EE0 , 0x001A0 , 0x00303 },
+	{ 0x01EE1 , 0x001A1 , 0x00303 },
+	{ 0x01EE2 , 0x001A0 , 0x00323 },
+	{ 0x01EE3 , 0x001A1 , 0x00323 },
+	{ 0x01EE4 , 0x00055 , 0x00323 },
+	{ 0x01EE5 , 0x00075 , 0x00323 },
+	{ 0x01EE6 , 0x00055 , 0x00309 },
+	{ 0x01EE7 , 0x00075 , 0x00309 },
+	{ 0x01EE8 , 0x001AF , 0x00301 },
+	{ 0x01EE9 , 0x001B0 , 0x00301 },
+	{ 0x01EEA , 0x001AF , 0x00300 },
+	{ 0x01EEB , 0x001B0 , 0x00300 },
+	{ 0x01EEC , 0x001AF , 0x00309 },
+	{ 0x01EED , 0x001B0 , 0x00309 },
+	{ 0x01EEE , 0x001AF , 0x00303 },
+	{ 0x01EEF , 0x001B0 , 0x00303 },
+	{ 0x01EF0 , 0x001AF , 0x00323 },
+	{ 0x01EF1 , 0x001B0 , 0x00323 },
+	{ 0x01EF2 , 0x00059 , 0x00300 },
+	{ 0x01EF3 , 0x00079 , 0x00300 },
+	{ 0x01EF4 , 0x00059 , 0x00323 },
+	{ 0x01EF5 , 0x00079 , 0x00323 },
+	{ 0x01EF6 , 0x00059 , 0x00309 },
+	{ 0x01EF7 , 0x00079 , 0x00309 },
+	{ 0x01EF8 , 0x00059 , 0x00303 },
+	{ 0x01EF9 , 0x00079 , 0x00303 },
+	{ 0x01F00 , 0x003B1 , 0x00313 },
+	{ 0x01F01 , 0x003B1 , 0x00314 },
+	{ 0x01F02 , 0x01F00 , 0x00300 },
+	{ 0x01F03 , 0x01F01 , 0x00300 },
+	{ 0x01F04 , 0x01F00 , 0x00301 },
+	{ 0x01F05 , 0x01F01 , 0x00301 },
+	{ 0x01F06 , 0x01F00 , 0x00342 },
+	{ 0x01F07 , 0x01F01 , 0x00342 },
+	{ 0x01F08 , 0x00391 , 0x00313 },
+	{ 0x01F09 , 0x00391 , 0x00314 },
+	{ 0x01F0A , 0x01F08 , 0x00300 },
+	{ 0x01F0B , 0x01F09 , 0x00300 },
+	{ 0x01F0C , 0x01F08 , 0x00301 },
+	{ 0x01F0D , 0x01F09 , 0x00301 },
+	{ 0x01F0E , 0x01F08 , 0x00342 },
+	{ 0x01F0F , 0x01F09 , 0x00342 },
+	{ 0x01F10 , 0x003B5 , 0x00313 },
+	{ 0x01F11 , 0x003B5 , 0x00314 },
+	{ 0x01F12 , 0x01F10 , 0x00300 },
+	{ 0x01F13 , 0x01F11 , 0x00300 },
+	{ 0x01F14 , 0x01F10 , 0x00301 },
+	{ 0x01F15 , 0x01F11 , 0x00301 },
+	{ 0x01F18 , 0x00395 , 0x00313 },
+	{ 0x01F19 , 0x00395 , 0x00314 },
+	{ 0x01F1A , 0x01F18 , 0x00300 },
+	{ 0x01F1B , 0x01F19 , 0x00300 },
+	{ 0x01F1C , 0x01F18 , 0x00301 },
+	{ 0x01F1D , 0x01F19 , 0x00301 },
+	{ 0x01F20 , 0x003B7 , 0x00313 },
+	{ 0x01F21 , 0x003B7 , 0x00314 },
+	{ 0x01F22 , 0x01F20 , 0x00300 },
+	{ 0x01F23 , 0x01F21 , 0x00300 },
+	{ 0x01F24 , 0x01F20 , 0x00301 },
+	{ 0x01F25 , 0x01F21 , 0x00301 },
+	{ 0x01F26 , 0x01F20 , 0x00342 },
+	{ 0x01F27 , 0x01F21 , 0x00342 },
+	{ 0x01F28 , 0x00397 , 0x00313 },
+	{ 0x01F29 , 0x00397 , 0x00314 },
+	{ 0x01F2A , 0x01F28 , 0x00300 },
+	{ 0x01F2B , 0x01F29 , 0x00300 },
+	{ 0x01F2C , 0x01F28 , 0x00301 },
+	{ 0x01F2D , 0x01F29 , 0x00301 },
+	{ 0x01F2E , 0x01F28 , 0x00342 },
+	{ 0x01F2F , 0x01F29 , 0x00342 },
+	{ 0x01F30 , 0x003B9 , 0x00313 },
+	{ 0x01F31 , 0x003B9 , 0x00314 },
+	{ 0x01F32 , 0x01F30 , 0x00300 },
+	{ 0x01F33 , 0x01F31 , 0x00300 },
+	{ 0x01F34 , 0x01F30 , 0x00301 },
+	{ 0x01F35 , 0x01F31 , 0x00301 },
+	{ 0x01F36 , 0x01F30 , 0x00342 },
+	{ 0x01F37 , 0x01F31 , 0x00342 },
+	{ 0x01F38 , 0x00399 , 0x00313 },
+	{ 0x01F39 , 0x00399 , 0x00314 },
+	{ 0x01F3A , 0x01F38 , 0x00300 },
+	{ 0x01F3B , 0x01F39 , 0x00300 },
+	{ 0x01F3C , 0x01F38 , 0x00301 },
+	{ 0x01F3D , 0x01F39 , 0x00301 },
+	{ 0x01F3E , 0x01F38 , 0x00342 },
+	{ 0x01F3F , 0x01F39 , 0x00342 },
+	{ 0x01F40 , 0x003BF , 0x00313 },
+	{ 0x01F41 , 0x003BF , 0x00314 },
+	{ 0x01F42 , 0x01F40 , 0x00300 },
+	{ 0x01F43 , 0x01F41 , 0x00300 },
+	{ 0x01F44 , 0x01F40 , 0x00301 },
+	{ 0x01F45 , 0x01F41 , 0x00301 },
+	{ 0x01F48 , 0x0039F , 0x00313 },
+	{ 0x01F49 , 0x0039F , 0x00314 },
+	{ 0x01F4A , 0x01F48 , 0x00300 },
+	{ 0x01F4B , 0x01F49 , 0x00300 },
+	{ 0x01F4C , 0x01F48 , 0x00301 },
+	{ 0x01F4D , 0x01F49 , 0x00301 },
+	{ 0x01F50 , 0x003C5 , 0x00313 },
+	{ 0x01F51 , 0x003C5 , 0x00314 },
+	{ 0x01F52 , 0x01F50 , 0x00300 },
+	{ 0x01F53 , 0x01F51 , 0x00300 },
+	{ 0x01F54 , 0x01F50 , 0x00301 },
+	{ 0x01F55 , 0x01F51 , 0x00301 },
+	{ 0x01F56 , 0x01F50 , 0x00342 },
+	{ 0x01F57 , 0x01F51 , 0x00342 },
+	{ 0x01F59 , 0x003A5 , 0x00314 },
+	{ 0x01F5B , 0x01F59 , 0x00300 },
+	{ 0x01F5D , 0x01F59 , 0x00301 },
+	{ 0x01F5F , 0x01F59 , 0x00342 },
+	{ 0x01F60 , 0x003C9 , 0x00313 },
+	{ 0x01F61 , 0x003C9 , 0x00314 },
+	{ 0x01F62 , 0x01F60 , 0x00300 },
+	{ 0x01F63 , 0x01F61 , 0x00300 },
+	{ 0x01F64 , 0x01F60 , 0x00301 },
+	{ 0x01F65 , 0x01F61 , 0x00301 },
+	{ 0x01F66 , 0x01F60 , 0x00342 },
+	{ 0x01F67 , 0x01F61 , 0x00342 },
+	{ 0x01F68 , 0x003A9 , 0x00313 },
+	{ 0x01F69 , 0x003A9 , 0x00314 },
+	{ 0x01F6A , 0x01F68 , 0x00300 },
+	{ 0x01F6B , 0x01F69 , 0x00300 },
+	{ 0x01F6C , 0x01F68 , 0x00301 },
+	{ 0x01F6D , 0x01F69 , 0x00301 },
+	{ 0x01F6E , 0x01F68 , 0x00342 },
+	{ 0x01F6F , 0x01F69 , 0x00342 },
+	{ 0x01F70 , 0x003B1 , 0x00300 },
+	{ 0x01F72 , 0x003B5 , 0x00300 },
+	{ 0x01F74 , 0x003B7 , 0x00300 },
+	{ 0x01F76 , 0x003B9 , 0x00300 },
+	{ 0x01F78 , 0x003BF , 0x00300 },
+	{ 0x01F7A , 0x003C5 , 0x00300 },
+	{ 0x01F7C , 0x003C9 , 0x00300 },
+	{ 0x01F80 , 0x01F00 , 0x00345 },
+	{ 0x01F81 , 0x01F01 , 0x00345 },
+	{ 0x01F82 , 0x01F02 , 0x00345 },
+	{ 0x01F83 , 0x01F03 , 0x00345 },
+	{ 0x01F84 , 0x01F04 , 0x00345 },
+	{ 0x01F85 , 0x01F05 , 0x00345 },
+	{ 0x01F86 , 0x01F06 , 0x00345 },
+	{ 0x01F87 , 0x01F07 , 0x00345 },
+	{ 0x01F88 , 0x01F08 , 0x00345 },
+	{ 0x01F89 , 0x01F09 , 0x00345 },
+	{ 0x01F8A , 0x01F0A , 0x00345 },
+	{ 0x01F8B , 0x01F0B , 0x00345 },
+	{ 0x01F8C , 0x01F0C , 0x00345 },
+	{ 0x01F8D , 0x01F0D , 0x00345 },
+	{ 0x01F8E , 0x01F0E , 0x00345 },
+	{ 0x01F8F , 0x01F0F , 0x00345 },
+	{ 0x01F90 , 0x01F20 , 0x00345 },
+	{ 0x01F91 , 0x01F21 , 0x00345 },
+	{ 0x01F92 , 0x01F22 , 0x00345 },
+	{ 0x01F93 , 0x01F23 , 0x00345 },
+	{ 0x01F94 , 0x01F24 , 0x00345 },
+	{ 0x01F95 , 0x01F25 , 0x00345 },
+	{ 0x01F96 , 0x01F26 , 0x00345 },
+	{ 0x01F97 , 0x01F27 , 0x00345 },
+	{ 0x01F98 , 0x01F28 , 0x00345 },
+	{ 0x01F99 , 0x01F29 , 0x00345 },
+	{ 0x01F9A , 0x01F2A , 0x00345 },
+	{ 0x01F9B , 0x01F2B , 0x00345 },
+	{ 0x01F9C , 0x01F2C , 0x00345 },
+	{ 0x01F9D , 0x01F2D , 0x00345 },
+	{ 0x01F9E , 0x01F2E , 0x00345 },
+	{ 0x01F9F , 0x01F2F , 0x00345 },
+	{ 0x01FA0 , 0x01F60 , 0x00345 },
+	{ 0x01FA1 , 0x01F61 , 0x00345 },
+	{ 0x01FA2 , 0x01F62 , 0x00345 },
+	{ 0x01FA3 , 0x01F63 , 0x00345 },
+	{ 0x01FA4 , 0x01F64 , 0x00345 },
+	{ 0x01FA5 , 0x01F65 , 0x00345 },
+	{ 0x01FA6 , 0x01F66 , 0x00345 },
+	{ 0x01FA7 , 0x01F67 , 0x00345 },
+	{ 0x01FA8 , 0x01F68 , 0x00345 },
+	{ 0x01FA9 , 0x01F69 , 0x00345 },
+	{ 0x01FAA , 0x01F6A , 0x00345 },
+	{ 0x01FAB , 0x01F6B , 0x00345 },
+	{ 0x01FAC , 0x01F6C , 0x00345 },
+	{ 0x01FAD , 0x01F6D , 0x00345 },
+	{ 0x01FAE , 0x01F6E , 0x00345 },
+	{ 0x01FAF , 0x01F6F , 0x00345 },
+	{ 0x01FB0 , 0x003B1 , 0x00306 },
+	{ 0x01FB1 , 0x003B1 , 0x00304 },
+	{ 0x01FB2 , 0x01F70 , 0x00345 },
+	{ 0x01FB3 , 0x003B1 , 0x00345 },
+	{ 0x01FB4 , 0x003AC , 0x00345 },
+	{ 0x01FB6 , 0x003B1 , 0x00342 },
+	{ 0x01FB7 , 0x01FB6 , 0x00345 },
+	{ 0x01FB8 , 0x00391 , 0x00306 },
+	{ 0x01FB9 , 0x00391 , 0x00304 },
+	{ 0x01FBA , 0x00391 , 0x00300 },
+	{ 0x01FBC , 0x00391 , 0x00345 },
+	{ 0x01FC1 , 0x000A8 , 0x00342 },
+	{ 0x01FC2 , 0x01F74 , 0x00345 },
+	{ 0x01FC3 , 0x003B7 , 0x00345 },
+	{ 0x01FC4 , 0x003AE , 0x00345 },
+	{ 0x01FC6 , 0x003B7 , 0x00342 },
+	{ 0x01FC7 , 0x01FC6 , 0x00345 },
+	{ 0x01FC8 , 0x00395 , 0x00300 },
+	{ 0x01FCA , 0x00397 , 0x00300 },
+	{ 0x01FCC , 0x00397 , 0x00345 },
+	{ 0x01FCD , 0x01FBF , 0x00300 },
+	{ 0x01FCE , 0x01FBF , 0x00301 },
+	{ 0x01FCF , 0x01FBF , 0x00342 },
+	{ 0x01FD0 , 0x003B9 , 0x00306 },
+	{ 0x01FD1 , 0x003B9 , 0x00304 },
+	{ 0x01FD2 , 0x003CA , 0x00300 },
+	{ 0x01FD6 , 0x003B9 , 0x00342 },
+	{ 0x01FD7 , 0x003CA , 0x00342 },
+	{ 0x01FD8 , 0x00399 , 0x00306 },
+	{ 0x01FD9 , 0x00399 , 0x00304 },
+	{ 0x01FDA , 0x00399 , 0x00300 },
+	{ 0x01FDD , 0x01FFE , 0x00300 },
+	{ 0x01FDE , 0x01FFE , 0x00301 },
+	{ 0x01FDF , 0x01FFE , 0x00342 },
+	{ 0x01FE0 , 0x003C5 , 0x00306 },
+	{ 0x01FE1 , 0x003C5 , 0x00304 },
+	{ 0x01FE2 , 0x003CB , 0x00300 },
+	{ 0x01FE4 , 0x003C1 , 0x00313 },
+	{ 0x01FE5 , 0x003C1 , 0x00314 },
+	{ 0x01FE6 , 0x003C5 , 0x00342 },
+	{ 0x01FE7 , 0x003CB , 0x00342 },
+	{ 0x01FE8 , 0x003A5 , 0x00306 },
+	{ 0x01FE9 , 0x003A5 , 0x00304 },
+	{ 0x01FEA , 0x003A5 , 0x00300 },
+	{ 0x01FEC , 0x003A1 , 0x00314 },
+	{ 0x01FED , 0x000A8 , 0x00300 },
+	{ 0x01FF2 , 0x01F7C , 0x00345 },
+	{ 0x01FF3 , 0x003C9 , 0x00345 },
+	{ 0x01FF4 , 0x003CE , 0x00345 },
+	{ 0x01FF6 , 0x003C9 , 0x00342 },
+	{ 0x01FF7 , 0x01FF6 , 0x00345 },
+	{ 0x01FF8 , 0x0039F , 0x00300 },
+	{ 0x01FFA , 0x003A9 , 0x00300 },
+	{ 0x01FFC , 0x003A9 , 0x00345 },
+	{ 0x0219A , 0x02190 , 0x00338 },
+	{ 0x0219B , 0x02192 , 0x00338 },
+	{ 0x021AE , 0x02194 , 0x00338 },
+	{ 0x021CD , 0x021D0 , 0x00338 },
+	{ 0x021CE , 0x021D4 , 0x00338 },
+	{ 0x021CF , 0x021D2 , 0x00338 },
+	{ 0x02204 , 0x02203 , 0x00338 },
+	{ 0x02209 , 0x02208 , 0x00338 },
+	{ 0x0220C , 0x0220B , 0x00338 },
+	{ 0x02224 , 0x02223 , 0x00338 },
+	{ 0x02226 , 0x02225 , 0x00338 },
+	{ 0x02241 , 0x0223C , 0x00338 },
+	{ 0x02244 , 0x02243 , 0x00338 },
+	{ 0x02247 , 0x02245 , 0x00338 },
+	{ 0x02249 , 0x02248 , 0x00338 },
+	{ 0x02260 , 0x0003D , 0x00338 },
+	{ 0x02262 , 0x02261 , 0x00338 },
+	{ 0x0226D , 0x0224D , 0x00338 },
+	{ 0x0226E , 0x0003C , 0x00338 },
+	{ 0x0226F , 0x0003E , 0x00338 },
+	{ 0x02270 , 0x02264 , 0x00338 },
+	{ 0x02271 , 0x02265 , 0x00338 },
+	{ 0x02274 , 0x02272 , 0x00338 },
+	{ 0x02275 , 0x02273 , 0x00338 },
+	{ 0x02278 , 0x02276 , 0x00338 },
+	{ 0x02279 , 0x02277 , 0x00338 },
+	{ 0x02280 , 0x0227A , 0x00338 },
+	{ 0x02281 , 0x0227B , 0x00338 },
+	{ 0x02284 , 0x02282 , 0x00338 },
+	{ 0x02285 , 0x02283 , 0x00338 },
+	{ 0x02288 , 0x02286 , 0x00338 },
+	{ 0x02289 , 0x02287 , 0x00338 },
+	{ 0x022AC , 0x022A2 , 0x00338 },
+	{ 0x022AD , 0x022A8 , 0x00338 },
+	{ 0x022AE , 0x022A9 , 0x00338 },
+	{ 0x022AF , 0x022AB , 0x00338 },
+	{ 0x022E0 , 0x0227C , 0x00338 },
+	{ 0x022E1 , 0x0227D , 0x00338 },
+	{ 0x022E2 , 0x02291 , 0x00338 },
+	{ 0x022E3 , 0x02292 , 0x00338 },
+	{ 0x022EA , 0x022B2 , 0x00338 },
+	{ 0x022EB , 0x022B3 , 0x00338 },
+	{ 0x022EC , 0x022B4 , 0x00338 },
+	{ 0x022ED , 0x022B5 , 0x00338 },
+	{ 0x0304C , 0x0304B , 0x03099 },
+	{ 0x0304E , 0x0304D , 0x03099 },
+	{ 0x03050 , 0x0304F , 0x03099 },
+	{ 0x03052 , 0x03051 , 0x03099 },
+	{ 0x03054 , 0x03053 , 0x03099 },
+	{ 0x03056 , 0x03055 , 0x03099 },
+	{ 0x03058 , 0x03057 , 0x03099 },
+	{ 0x0305A , 0x03059 , 0x03099 },
+	{ 0x0305C , 0x0305B , 0x03099 },
+	{ 0x0305E , 0x0305D , 0x03099 },
+	{ 0x03060 , 0x0305F , 0x03099 },
+	{ 0x03062 , 0x03061 , 0x03099 },
+	{ 0x03065 , 0x03064 , 0x03099 },
+	{ 0x03067 , 0x03066 , 0x03099 },
+	{ 0x03069 , 0x03068 , 0x03099 },
+	{ 0x03070 , 0x0306F , 0x03099 },
+	{ 0x03071 , 0x0306F , 0x0309A },
+	{ 0x03073 , 0x03072 , 0x03099 },
+	{ 0x03074 , 0x03072 , 0x0309A },
+	{ 0x03076 , 0x03075 , 0x03099 },
+	{ 0x03077 , 0x03075 , 0x0309A },
+	{ 0x03079 , 0x03078 , 0x03099 },
+	{ 0x0307A , 0x03078 , 0x0309A },
+	{ 0x0307C , 0x0307B , 0x03099 },
+	{ 0x0307D , 0x0307B , 0x0309A },
+	{ 0x03094 , 0x03046 , 0x03099 },
+	{ 0x0309E , 0x0309D , 0x03099 },
+	{ 0x030AC , 0x030AB , 0x03099 },
+	{ 0x030AE , 0x030AD , 0x03099 },
+	{ 0x030B0 , 0x030AF , 0x03099 },
+	{ 0x030B2 , 0x030B1 , 0x03099 },
+	{ 0x030B4 , 0x030B3 , 0x03099 },
+	{ 0x030B6 , 0x030B5 , 0x03099 },
+	{ 0x030B8 , 0x030B7 , 0x03099 },
+	{ 0x030BA , 0x030B9 , 0x03099 },
+	{ 0x030BC , 0x030BB , 0x03099 },
+	{ 0x030BE , 0x030BD , 0x03099 },
+	{ 0x030C0 , 0x030BF , 0x03099 },
+	{ 0x030C2 , 0x030C1 , 0x03099 },
+	{ 0x030C5 , 0x030C4 , 0x03099 },
+	{ 0x030C7 , 0x030C6 , 0x03099 },
+	{ 0x030C9 , 0x030C8 , 0x03099 },
+	{ 0x030D0 , 0x030CF , 0x03099 },
+	{ 0x030D1 , 0x030CF , 0x0309A },
+	{ 0x030D3 , 0x030D2 , 0x03099 },
+	{ 0x030D4 , 0x030D2 , 0x0309A },
+	{ 0x030D6 , 0x030D5 , 0x03099 },
+	{ 0x030D7 , 0x030D5 , 0x0309A },
+	{ 0x030D9 , 0x030D8 , 0x03099 },
+	{ 0x030DA , 0x030D8 , 0x0309A },
+	{ 0x030DC , 0x030DB , 0x03099 },
+	{ 0x030DD , 0x030DB , 0x0309A },
+	{ 0x030F4 , 0x030A6 , 0x03099 },
+	{ 0x030F7 , 0x030EF , 0x03099 },
+	{ 0x030F8 , 0x030F0 , 0x03099 },
+	{ 0x030F9 , 0x030F1 , 0x03099 },
+	{ 0x030FA , 0x030F2 , 0x03099 },
+	{ 0x030FE , 0x030FD , 0x03099 },
+	{ 0x1109A , 0x11099 , 0x110BA },
+	{ 0x1109C , 0x1109B , 0x110BA },
+	{ 0x110AB , 0x110A5 , 0x110BA },
+};
+
 #endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */
+
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_string_sprintf.c
--- a/head/contrib/libarchive/libarchive/archive_string_sprintf.c	Mon Jul 3=
0 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_string_sprintf.c	Fri Aug 1=
0 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_string_spri=
ntf.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_string_spri=
ntf.c 238856 2012-07-28 06:38:44Z mm $");
=20
 /*
  * The use of printf()-family functions can be troublesome
@@ -38,7 +38,9 @@
  * here.  This is only used to format error messages, so doesn't
  * require any floating-point support or field-width handling.
  */
-
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 #include <stdio.h>
=20
 #include "archive_string.h"
@@ -129,7 +131,7 @@
 			break;
 		case 'c':
 			s =3D va_arg(ap, int);
-			archive_strappend_char(as, s);
+			archive_strappend_char(as, (char)s);
 			break;
 		case 'd':
 			switch(long_flag) {
@@ -146,7 +148,9 @@
 				pw =3D va_arg(ap, wchar_t *);
 				if (pw =3D=3D NULL)
 					pw =3D L"(null)";
-				archive_string_append_from_wcs(as, pw, wcslen(pw));
+				if (archive_string_append_from_wcs(as, pw,
+				    wcslen(pw)) !=3D 0 && errno =3D=3D ENOMEM)
+					__archive_errx(1, "Out of memory");
 				break;
 			default:
 				p2 =3D va_arg(ap, char *);
@@ -160,7 +164,9 @@
 			pw =3D va_arg(ap, wchar_t *);
 			if (pw =3D=3D NULL)
 				pw =3D L"(null)";
-			archive_string_append_from_wcs(as, pw, wcslen(pw));
+			if (archive_string_append_from_wcs(as, pw,
+			    wcslen(pw)) !=3D 0 && errno =3D=3D ENOMEM)
+				__archive_errx(1, "Out of memory");
 			break;
 		case 'o': case 'u': case 'x': case 'X':
 			/* Common handling for unsigned integer formats. */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_util.3
--- a/head/contrib/libarchive/libarchive/archive_util.3	Mon Jul 30 11:44:18=
 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_util.3	Fri Aug 10 14:19:25=
 2012 +0300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_util.3 232153 201=
2-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_util.3 238856 201=
2-07-28 06:38:44Z mm $
 .\"
-.Dd January 8, 2005
+.Dd February 2, 2012
 .Dt ARCHIVE_UTIL 3
 .Os
 .Sh NAME
@@ -43,6 +43,8 @@
 .Nm archive_position ,
 .Nm archive_set_error
 .Nd libarchive utility functions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft void
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_util.c
--- a/head/contrib/libarchive/libarchive/archive_util.c	Mon Jul 30 11:44:18=
 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_util.c	Fri Aug 10 14:19:25=
 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_util.c 2321=
53 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_util.c 2388=
56 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -243,8 +243,9 @@
 		archive_wstrcpy(&temp_name, tmp);
 		free(tmp);
 	} else {
-		archive_wstring_append_from_mbs(&temp_name, tmpdir,
-		    strlen(tmpdir));
+		if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
+		    strlen(tmpdir)) < 0)
+			goto exit_tmpfile;
 		if (temp_name.s[temp_name.length-1] !=3D L'/')
 			archive_wstrappend_wchar(&temp_name, L'/');
 	}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write.3
--- a/head/contrib/libarchive/libarchive/archive_write.3	Mon Jul 30 11:44:1=
8 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write.3	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -22,14 +22,16 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_write.3 232153 20=
12-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_write.3 238856 20=
12-07-28 06:38:44Z mm $
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE 3
 .Os
 .Sh NAME
 .Nm archive_write
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Sh DESCRIPTION
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write.c
--- a/head/contrib/libarchive/libarchive/archive_write.c	Mon Jul 30 11:44:1=
8 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write.c	Fri Aug 10 14:19:2=
5 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write.c 232=
153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write.c 238=
856 2012-07-28 06:38:44Z mm $");
=20
 /*
  * This file contains the "essential" portions of the write API, that
@@ -380,7 +380,7 @@
 		}
 	}
=20
-	while ((size_t)remaining > state->buffer_size) {
+	while ((size_t)remaining >=3D state->buffer_size) {
 		/* Write out full blocks directly to client. */
 		bytes_written =3D (a->client_writer)(&a->archive,
 		    a->client_data, buff, state->buffer_size);
@@ -623,7 +623,7 @@
 	if (a->skip_file_set &&
 	    archive_entry_dev_is_set(entry) &&
 	    archive_entry_ino_is_set(entry) &&
-	    archive_entry_dev(entry) =3D=3D a->skip_file_dev &&
+	    archive_entry_dev(entry) =3D=3D (dev_t)a->skip_file_dev &&
 	    archive_entry_ino64(entry) =3D=3D a->skip_file_ino) {
 		archive_set_error(&a->archive, 0,
 		    "Can't add archive to itself");
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_add_filter.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/archive_write_add_filter.c	Fri Aug=
 10 14:19:25 2012 +0300
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2012 Ondrej Holy
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+
+/* A table that maps filter codes to functions. */
+static
+struct { int code; int (*setter)(struct archive *); } codes[] =3D
+{
+	{ ARCHIVE_FILTER_NONE,		archive_write_add_filter_none },
+	{ ARCHIVE_FILTER_GZIP,		archive_write_add_filter_gzip },
+	{ ARCHIVE_FILTER_BZIP2,		archive_write_add_filter_bzip2 },
+	{ ARCHIVE_FILTER_COMPRESS,	archive_write_add_filter_compress },
+	{ ARCHIVE_FILTER_LZMA,		archive_write_add_filter_lzma },
+	{ ARCHIVE_FILTER_XZ,		archive_write_add_filter_xz },
+	{ ARCHIVE_FILTER_LZIP,		archive_write_add_filter_lzip },
+	{ -1,			NULL }
+};
+
+int
+archive_write_add_filter(struct archive *a, int code)
+{
+	int i;
+
+	for (i =3D 0; codes[i].code !=3D -1; i++) {
+		if (code =3D=3D codes[i].code)
+			return ((codes[i].setter)(a));
+	}
+
+	archive_set_error(a, EINVAL, "No such filter");
+	return (ARCHIVE_FATAL);
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_add_filter_bzip2.c
--- a/head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c	M=
on Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c	F=
ri Aug 10 14:19:25 2012 +0300
@@ -133,10 +133,18 @@
 	if (ret !=3D 0)
 		return (ret);
=20
-	/* TODO: Find a better way to size this.  (Maybe look at the */
-	/* block size expected by the following filter?) */
 	if (data->compressed =3D=3D NULL) {
-		data->compressed_buffer_size =3D 65536;
+		size_t bs =3D 65536, bpb;
+		if (f->archive->magic =3D=3D ARCHIVE_WRITE_MAGIC) {
+			/* Buffer size should be a multiple number of the of bytes
+			 * per block for performance. */
+			bpb =3D archive_write_get_bytes_per_block(f->archive);
+			if (bpb > bs)
+				bs =3D bpb;
+			else if (bpb !=3D 0)
+				bs -=3D bs % bpb;
+		}
+		data->compressed_buffer_size =3D bs;
 		data->compressed
 		    =3D (char *)malloc(data->compressed_buffer_size);
 		if (data->compressed =3D=3D NULL) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_add_filter_compress.c
--- a/head/contrib/libarchive/libarchive/archive_write_add_filter_compress.=
c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_add_filter_compress.=
c	Fri Aug 10 14:19:25 2012 +0300
@@ -148,6 +148,7 @@
 {
 	int ret;
 	struct private_data *state;
+	size_t bs =3D 65536, bpb;
=20
 	f->code =3D ARCHIVE_COMPRESSION_COMPRESS;
 	f->name =3D "compress";
@@ -163,7 +164,16 @@
 		return (ARCHIVE_FATAL);
 	}
=20
-	state->compressed_buffer_size =3D 65536;
+	if (f->archive->magic =3D=3D ARCHIVE_WRITE_MAGIC) {
+		/* Buffer size should be a multiple number of the of bytes
+		 * per block for performance. */
+		bpb =3D archive_write_get_bytes_per_block(f->archive);
+		if (bpb > bs)
+			bs =3D bpb;
+		else if (bpb !=3D 0)
+			bs -=3D bs % bpb;
+	}
+	state->compressed_buffer_size =3D bs;
 	state->compressed =3D malloc(state->compressed_buffer_size);
=20
 	if (state->compressed =3D=3D NULL) {
@@ -386,12 +396,12 @@
=20
 		state->checkpoint =3D state->in_count + CHECK_GAP;
=20
-		if (state->in_count <=3D 0x007fffff)
-			ratio =3D state->in_count * 256 / state->out_count;
-		else if ((ratio =3D state->out_count / 256) =3D=3D 0)
+		if (state->in_count <=3D 0x007fffff && state->out_count !=3D 0)
+			ratio =3D (int)(state->in_count * 256 / state->out_count);
+		else if ((ratio =3D (int)(state->out_count / 256)) =3D=3D 0)
 			ratio =3D 0x7fffffff;
 		else
-			ratio =3D state->in_count / ratio;
+			ratio =3D (int)(state->in_count / ratio);
=20
 		if (ratio > state->compress_ratio)
 			state->compress_ratio =3D ratio;
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_add_filter_gzip.c
--- a/head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c	Mo=
n Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c	Fr=
i Aug 10 14:19:25 2012 +0300
@@ -135,7 +135,17 @@
 		return (ret);
=20
 	if (data->compressed =3D=3D NULL) {
-		data->compressed_buffer_size =3D 65536;
+		size_t bs =3D 65536, bpb;
+		if (f->archive->magic =3D=3D ARCHIVE_WRITE_MAGIC) {
+			/* Buffer size should be a multiple number of the of bytes
+			 * per block for performance. */
+			bpb =3D archive_write_get_bytes_per_block(f->archive);
+			if (bpb > bs)
+				bs =3D bpb;
+			else if (bpb !=3D 0)
+				bs -=3D bs % bpb;
+		}
+		data->compressed_buffer_size =3D bs;
 		data->compressed
 		    =3D (unsigned char *)malloc(data->compressed_buffer_size);
 		if (data->compressed =3D=3D NULL) {
@@ -155,10 +165,10 @@
 	data->compressed[1] =3D 0x8b;
 	data->compressed[2] =3D 0x08; /* "Deflate" compression */
 	data->compressed[3] =3D 0; /* No options */
-	data->compressed[4] =3D (t)&0xff;  /* Timestamp */
-	data->compressed[5] =3D (t>>8)&0xff;
-	data->compressed[6] =3D (t>>16)&0xff;
-	data->compressed[7] =3D (t>>24)&0xff;
+	data->compressed[4] =3D (uint8_t)(t)&0xff;  /* Timestamp */
+	data->compressed[5] =3D (uint8_t)(t>>8)&0xff;
+	data->compressed[6] =3D (uint8_t)(t>>16)&0xff;
+	data->compressed[7] =3D (uint8_t)(t>>24)&0xff;
 	data->compressed[8] =3D 0; /* No deflate options */
 	data->compressed[9] =3D 3; /* OS=3DUnix */
 	data->stream.next_out +=3D 10;
@@ -270,14 +280,14 @@
 	}
 	if (ret =3D=3D ARCHIVE_OK) {
 		/* Build and write out 8-byte trailer. */
-		trailer[0] =3D (data->crc)&0xff;
-		trailer[1] =3D (data->crc >> 8)&0xff;
-		trailer[2] =3D (data->crc >> 16)&0xff;
-		trailer[3] =3D (data->crc >> 24)&0xff;
-		trailer[4] =3D (data->total_in)&0xff;
-		trailer[5] =3D (data->total_in >> 8)&0xff;
-		trailer[6] =3D (data->total_in >> 16)&0xff;
-		trailer[7] =3D (data->total_in >> 24)&0xff;
+		trailer[0] =3D (uint8_t)(data->crc)&0xff;
+		trailer[1] =3D (uint8_t)(data->crc >> 8)&0xff;
+		trailer[2] =3D (uint8_t)(data->crc >> 16)&0xff;
+		trailer[3] =3D (uint8_t)(data->crc >> 24)&0xff;
+		trailer[4] =3D (uint8_t)(data->total_in)&0xff;
+		trailer[5] =3D (uint8_t)(data->total_in >> 8)&0xff;
+		trailer[6] =3D (uint8_t)(data->total_in >> 16)&0xff;
+		trailer[7] =3D (uint8_t)(data->total_in >> 24)&0xff;
 		ret =3D __archive_write_filter(f->next_filter, trailer, 8);
 	}
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_add_filter_program.c
--- a/head/contrib/libarchive/libarchive/archive_write_add_filter_program.c=
	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_add_filter_program.c=
	Fri Aug 10 14:19:25 2012 +0300
@@ -171,60 +171,62 @@
 	if (buf_len =3D=3D 0)
 		return (-1);
=20
-restart_write:
-	do {
-		ret =3D write(data->child_stdin, buf, buf_len);
-	} while (ret =3D=3D -1 && errno =3D=3D EINTR);
+	for (;;) {
+		do {
+			ret =3D write(data->child_stdin, buf, buf_len);
+		} while (ret =3D=3D -1 && errno =3D=3D EINTR);
=20
-	if (ret > 0)
-		return (ret);
-	if (ret =3D=3D 0) {
-		close(data->child_stdin);
-		data->child_stdin =3D -1;
-		fcntl(data->child_stdout, F_SETFL, 0);
-		return (0);
+		if (ret > 0)
+			return (ret);
+		if (ret =3D=3D 0) {
+			close(data->child_stdin);
+			data->child_stdin =3D -1;
+			fcntl(data->child_stdout, F_SETFL, 0);
+			return (0);
+		}
+		if (ret =3D=3D -1 && errno !=3D EAGAIN)
+			return (-1);
+
+		if (data->child_stdout =3D=3D -1) {
+			fcntl(data->child_stdin, F_SETFL, 0);
+			__archive_check_child(data->child_stdin,
+				data->child_stdout);
+			continue;
+		}
+
+		do {
+			ret =3D read(data->child_stdout,
+			    data->child_buf + data->child_buf_avail,
+			    data->child_buf_len - data->child_buf_avail);
+		} while (ret =3D=3D -1 && errno =3D=3D EINTR);
+
+		if (ret =3D=3D 0 || (ret =3D=3D -1 && errno =3D=3D EPIPE)) {
+			close(data->child_stdout);
+			data->child_stdout =3D -1;
+			fcntl(data->child_stdin, F_SETFL, 0);
+			continue;
+		}
+		if (ret =3D=3D -1 && errno =3D=3D EAGAIN) {
+			__archive_check_child(data->child_stdin,
+				data->child_stdout);
+			continue;
+		}
+		if (ret =3D=3D -1)
+			return (-1);
+
+		data->child_buf_avail +=3D ret;
+
+		ret =3D __archive_write_filter(f->next_filter,
+		    data->child_buf, data->child_buf_avail);
+		if (ret <=3D 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 -=3D ret;
 	}
-	if (ret =3D=3D -1 && errno !=3D EAGAIN)
-		return (-1);
-
-	if (data->child_stdout =3D=3D -1) {
-		fcntl(data->child_stdin, F_SETFL, 0);
-		__archive_check_child(data->child_stdin, data->child_stdout);
-		goto restart_write;
-	}
-
-	do {
-		ret =3D read(data->child_stdout,
-		    data->child_buf + data->child_buf_avail,
-		    data->child_buf_len - data->child_buf_avail);
-	} while (ret =3D=3D -1 && errno =3D=3D EINTR);
-
-	if (ret =3D=3D 0 || (ret =3D=3D -1 && errno =3D=3D EPIPE)) {
-		close(data->child_stdout);
-		data->child_stdout =3D -1;
-		fcntl(data->child_stdin, F_SETFL, 0);
-		goto restart_write;
-	}
-	if (ret =3D=3D -1 && errno =3D=3D EAGAIN) {
-		__archive_check_child(data->child_stdin, data->child_stdout);
-		goto restart_write;
-	}
-	if (ret =3D=3D -1)
-		return (-1);
-
-	data->child_buf_avail +=3D ret;
-
-	ret =3D __archive_write_filter(f->next_filter,
-	    data->child_buf, data->child_buf_avail);
-	if (ret <=3D 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 -=3D ret;
-	goto restart_write;
 }
=20
 /*
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_add_filter_xz.c
--- a/head/contrib/libarchive/libarchive/archive_write_add_filter_xz.c	Mon =
Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_add_filter_xz.c	Fri =
Aug 10 14:19:25 2012 +0300
@@ -298,7 +298,17 @@
 		return (ret);
=20
 	if (data->compressed =3D=3D NULL) {
-		data->compressed_buffer_size =3D 65536;
+		size_t bs =3D 65536, bpb;
+		if (f->archive->magic =3D=3D ARCHIVE_WRITE_MAGIC) {
+			/* Buffer size should be a multiple number of the of bytes
+			 * per block for performance. */
+			bpb =3D archive_write_get_bytes_per_block(f->archive);
+			if (bpb > bs)
+				bs =3D bpb;
+			else if (bpb !=3D 0)
+				bs -=3D bs % bpb;
+		}
+		data->compressed_buffer_size =3D bs;
 		data->compressed
 		    =3D (unsigned char *)malloc(data->compressed_buffer_size);
 		if (data->compressed =3D=3D NULL) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_blocksize.3
--- a/head/contrib/libarchive/libarchive/archive_write_blocksize.3	Mon Jul =
30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_blocksize.3	Fri Aug =
10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_BLOCKSIZE 3
 .Os
 .Sh NAME
@@ -33,6 +33,8 @@
 .Nm archive_write_get_bytes_in_last_block ,
 .Nm archive_write_set_bytes_in_last_block
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_data.3
--- a/head/contrib/libarchive/libarchive/archive_write_data.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_data.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -22,14 +22,16 @@
 .\" 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 $
+.\" $FreeBSD$
 .\"
-.Dd March 23, 2011
-.Dt ARCHIVE_WRITE 3
+.Dd February 2, 2012
+.Dt ARCHIVE_WRITE_DATA 3
 .Os
 .Sh NAME
 .Nm archive_write_data
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft ssize_t
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_disk.3
--- a/head/contrib/libarchive/libarchive/archive_write_disk.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_disk.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_write_disk.3 2321=
53 2012-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/archive_write_disk.3 2388=
56 2012-07-28 06:38:44Z mm $
 .\"
-.Dd August 5, 2008
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_DISK 3
 .Os
 .Sh NAME
@@ -42,6 +42,8 @@
 .Nm archive_write_finish
 .Nm archive_write_free
 .Nd functions for creating objects on disk
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft struct archive *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_disk_acl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/archive_write_disk_acl.c	Fri Aug 1=
0 14:19:25 2012 +0300
@@ -0,0 +1,249 @@
+/*-
+ * 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
+ *    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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_disk.c 201159 2009-1=
2-29 05:35:40Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#define _ACL_PRIVATE /* For debugging */
+#include <sys/acl.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_acl_private.h"
+#include "archive_write_disk_private.h"
+
+#ifndef HAVE_POSIX_ACL
+/* Default empty function body to satisfy mainline code. */
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+	 struct archive_acl *abstract_acl)
+{
+	(void)a; /* UNUSED */
+	(void)fd; /* UNUSED */
+	(void)name; /* UNUSED */
+	(void)abstract_acl; /* UNUSED */
+	return (ARCHIVE_OK);
+}
+
+#else
+
+static int	set_acl(struct archive *, int fd, const char *,
+			struct archive_acl *,
+			acl_type_t, int archive_entry_acl_type, const char *tn);
+
+/*
+ * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
+ */
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+	 struct archive_acl *abstract_acl)
+{
+	int		 ret;
+
+	if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) > 0) {
+		ret =3D set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
+		    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
+		if (ret !=3D ARCHIVE_OK)
+			return (ret);
+		ret =3D set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
+		    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
+		return (ret);
+	} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) >=
 0) {
+		ret =3D set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
+		    ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+		return (ret);
+	} else
+		return ARCHIVE_OK;
+}
+
+static struct {
+	int archive_perm;
+	int platform_perm;
+} acl_perm_map[] =3D {
+	{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+	{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
+	{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+	{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
+	{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
+	{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
+	{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
+	{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
+	{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
+	{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
+	{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
+	{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
+	{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
+	{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
+	{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
+	{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
+	{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
+	{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
+	{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+};
+
+static struct {
+	int archive_inherit;
+	int platform_inherit;
+} acl_inherit_map[] =3D {
+	{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
+	{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
+	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INH=
ERIT},
+	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
+};
+
+static int
+set_acl(struct archive *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;
+	acl_entry_t	 acl_entry;
+	acl_permset_t	 acl_permset;
+	acl_flagset_t	 acl_flagset;
+	int		 ret;
+	int		 ae_type, ae_permset, ae_tag, ae_id;
+	uid_t		 ae_uid;
+	gid_t		 ae_gid;
+	const char	*ae_name;
+	int		 entries;
+	int		 i;
+
+	ret =3D ARCHIVE_OK;
+	entries =3D archive_acl_reset(abstract_acl, ae_requested_type);
+	if (entries =3D=3D 0)
+		return (ARCHIVE_OK);
+	acl =3D acl_init(entries);
+	while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+		   &ae_permset, &ae_tag, &ae_id, &ae_name) =3D=3D 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 =3D archive_write_disk_uid(a, 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 =3D archive_write_disk_gid(a, ae_name, ae_id);
+			acl_set_qualifier(acl_entry, &ae_gid);
+			break;
+		case ARCHIVE_ENTRY_ACL_USER_OBJ:
+			acl_set_tag_type(acl_entry, ACL_USER_OBJ);
+			break;
+		case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+			acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
+			break;
+		case ARCHIVE_ENTRY_ACL_MASK:
+			acl_set_tag_type(acl_entry, ACL_MASK);
+			break;
+		case ARCHIVE_ENTRY_ACL_OTHER:
+			acl_set_tag_type(acl_entry, ACL_OTHER);
+			break;
+		case ARCHIVE_ENTRY_ACL_EVERYONE:
+			acl_set_tag_type(acl_entry, ACL_EVERYONE);
+			break;
+		default:
+			/* XXX */
+			break;
+		}
+
+		switch (ae_type) {
+		case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
+			break;
+		case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
+			break;
+		case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
+			break;
+		case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
+			break;
+		case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+		case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+			// These don't translate directly into the system ACL.
+			break;
+		default:
+			// XXX error handling here.
+			break;
+		}
+
+		acl_get_permset(acl_entry, &acl_permset);
+		acl_clear_perms(acl_permset);
+
+		for (i =3D 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0]));=
 ++i) {
+			if (ae_permset & acl_perm_map[i].archive_perm)
+				acl_add_perm(acl_permset,
+					     acl_perm_map[i].platform_perm);
+		}
+
+		acl_get_flagset_np(acl_entry, &acl_flagset);
+		acl_clear_flags_np(acl_flagset);
+		for (i =3D 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map=
[0])); ++i) {
+			if (ae_permset & acl_inherit_map[i].archive_inherit)
+				acl_add_flag_np(acl_flagset,
+						acl_inherit_map[i].platform_inherit);
+		}
+	}
+
+	/* Try restoring the ACL through 'fd' if we can. */
+#if HAVE_ACL_SET_FD
+	if (fd >=3D 0 && acl_type =3D=3D ACL_TYPE_ACCESS && acl_set_fd(fd, acl) =
=3D=3D 0)
+		ret =3D ARCHIVE_OK;
+	else
+#else
+#if HAVE_ACL_SET_FD_NP
+	if (fd >=3D 0 && acl_set_fd_np(fd, acl, acl_type) =3D=3D 0)
+		ret =3D ARCHIVE_OK;
+	else
+#endif
+#endif
+#if HAVE_ACL_SET_LINK_NP
+	  if (acl_set_link_np(name, acl_type, acl) !=3D 0) {
+		archive_set_error(a, errno, "Failed to set %s acl", tname);
+		ret =3D ARCHIVE_WARN;
+	  }
+#else
+	/* TODO: Skip this if 'name' is a symlink. */
+	if (acl_set_file(name, acl_type, acl) !=3D 0) {
+		archive_set_error(a, errno, "Failed to set %s acl", tname);
+		ret =3D ARCHIVE_WARN;
+	}
+#endif
+	acl_free(acl);
+	return (ret);
+}
+#endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_disk_posix.c
--- a/head/contrib/libarchive/libarchive/archive_write_disk_posix.c	Mon Jul=
 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_disk_posix.c	Fri Aug=
 10 14:19:25 2012 +0300
@@ -32,9 +32,6 @@
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_SYS_ACL_H
-#include <sys/acl.h>
-#endif
 #ifdef HAVE_SYS_EXTATTR_H
 #include <sys/extattr.h>
 #endif
@@ -129,6 +126,7 @@
 #include "archive_string.h"
 #include "archive_entry.h"
 #include "archive_private.h"
+#include "archive_write_disk_private.h"
=20
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -188,8 +186,8 @@
 	struct fixup_entry	*current_fixup;
 	int64_t			 user_uid;
 	int			 skip_file_set;
-	dev_t			 skip_file_dev;
-	ino_t			 skip_file_ino;
+	int64_t			 skip_file_dev;
+	int64_t			 skip_file_ino;
 	time_t			 start_time;
=20
 	int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
@@ -267,11 +265,6 @@
 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, const char *, stru=
ct archive_acl *,
-		    acl_type_t, int archive_entry_acl_type, const char *tn);
-#endif
-static int	set_acls(struct archive_write_disk *, int fd, const char *, str=
uct 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 *);
@@ -570,6 +563,7 @@
=20
 	if (a->deferred & TODO_ACLS) {
 		fe =3D current_fixup(a, archive_entry_pathname(entry));
+		fe->fixup |=3D TODO_ACLS;
 		archive_acl_copy(&fe->acl, archive_entry_acl(entry));
 	}
=20
@@ -878,7 +872,7 @@
 	 * ACLs that prevent attribute changes (including time).
 	 */
 	if (a->todo & TODO_ACLS) {
-		int r2 =3D set_acls(a, a->fd,
+		int r2 =3D archive_write_disk_set_acls(&a->archive, a->fd,
 				  archive_entry_pathname(a->entry),
 				  archive_entry_acl(a->entry));
 		if (r2 < ret) ret =3D r2;
@@ -950,12 +944,12 @@
 int64_t
 archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
 {
-       struct archive_write_disk *a =3D (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);
+	struct archive_write_disk *a =3D (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);
 }
=20
 /*
@@ -1143,9 +1137,10 @@
=20
 		/* If it's our archive, we're done. */
 		if (a->skip_file_set &&
-		    a->st.st_dev =3D=3D a->skip_file_dev &&
-		    a->st.st_ino =3D=3D a->skip_file_ino) {
-			archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
+		    a->st.st_dev =3D=3D (dev_t)a->skip_file_dev &&
+		    a->st.st_ino =3D=3D (ino_t)a->skip_file_ino) {
+			archive_set_error(&a->archive, 0,
+			    "Refusing to overwrite archive");
 			return (ARCHIVE_FAILED);
 		}
=20
@@ -1163,7 +1158,7 @@
 			/* A dir is in the way of a non-dir, rmdir it. */
 			if (rmdir(a->name) !=3D 0) {
 				archive_set_error(&a->archive, errno,
-				    "Can't remove already-existing dir");
+				    "Can't replace existing directory with non-directory");
 				return (ARCHIVE_FAILED);
 			}
 			/* Try again. */
@@ -1380,7 +1375,8 @@
 		if (p->fixup & TODO_MODE_BASE)
 			chmod(p->name, p->mode);
 		if (p->fixup & TODO_ACLS)
-			set_acls(a, -1, p->name, &p->acl);
+			archive_write_disk_set_acls(&a->archive,
+						    -1, p->name, &p->acl);
 		if (p->fixup & TODO_FFLAGS)
 			set_fflags_platform(a, -1, p->name,
 			    p->mode, p->fflags_set, 0);
@@ -2529,7 +2525,7 @@
 	}
 	written =3D write(fd, metadata, metadata_size);
 	close(fd);
-	if (written !=3D metadata_size
+	if ((size_t)written !=3D metadata_size
 	    || copyfile(tmp.s, pathname, 0,
 			COPYFILE_UNPACK | COPYFILE_NOFOLLOW
 			| COPYFILE_ACL | COPYFILE_XATTR)) {
@@ -2542,125 +2538,6 @@
 }
 #endif
=20
-#ifndef HAVE_POSIX_ACL
-/* Default empty function body to satisfy mainline code. */
-static int
-set_acls(struct archive_write_disk *a, int fd, const char *name,
-	 struct archive_acl *aacl)
-{
-	(void)a; /* UNUSED */
-	(void)fd; /* UNUSED */
-	(void)name; /* UNUSED */
-	(void)aacl; /* UNUSED */
-	return (ARCHIVE_OK);
-}
-
-#else
-
-/*
- * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
- */
-static int
-set_acls(struct archive_write_disk *a, int fd, const char *name,
-	 struct archive_acl *abstract_acl)
-{
-	int		 ret;
-
-	ret =3D set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
-	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
-	if (ret !=3D ARCHIVE_OK)
-		return (ret);
-	ret =3D 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, const char *name,
-    struct archive_acl *abstract_acl,
-    acl_type_t acl_type, int ae_requested_type, const char *tname)
-{
-	acl_t		 acl;
-	acl_entry_t	 acl_entry;
-	acl_permset_t	 acl_permset;
-	int		 ret;
-	int		 ae_type, ae_permset, ae_tag, ae_id;
-	uid_t		 ae_uid;
-	gid_t		 ae_gid;
-	const char	*ae_name;
-	int		 entries;
-
-	ret =3D ARCHIVE_OK;
-	entries =3D archive_acl_reset(abstract_acl, ae_requested_type);
-	if (entries =3D=3D 0)
-		return (ARCHIVE_OK);
-	acl =3D acl_init(entries);
-	while (archive_acl_next(&a->archive, abstract_acl,
-	    ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id,
-	    &ae_name) =3D=3D 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 =3D 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 =3D archive_write_disk_gid(&a->archive,
-			    ae_name, ae_id);
-			acl_set_qualifier(acl_entry, &ae_gid);
-			break;
-		case ARCHIVE_ENTRY_ACL_USER_OBJ:
-			acl_set_tag_type(acl_entry, ACL_USER_OBJ);
-			break;
-		case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
-			acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
-			break;
-		case ARCHIVE_ENTRY_ACL_MASK:
-			acl_set_tag_type(acl_entry, ACL_MASK);
-			break;
-		case ARCHIVE_ENTRY_ACL_OTHER:
-			acl_set_tag_type(acl_entry, ACL_OTHER);
-			break;
-		default:
-			/* XXX */
-			break;
-		}
-
-		acl_get_permset(acl_entry, &acl_permset);
-		acl_clear_perms(acl_permset);
-		if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
-			acl_add_perm(acl_permset, ACL_EXECUTE);
-		if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
-			acl_add_perm(acl_permset, ACL_WRITE);
-		if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
-			acl_add_perm(acl_permset, ACL_READ);
-	}
-
-	/* Try restoring the ACL through 'fd' if we can. */
-#if HAVE_ACL_SET_FD
-	if (fd >=3D 0 && acl_type =3D=3D ACL_TYPE_ACCESS && acl_set_fd(fd, acl) =
=3D=3D 0)
-		ret =3D ARCHIVE_OK;
-	else
-#else
-#if HAVE_ACL_SET_FD_NP
-	if (fd >=3D 0 && acl_set_fd_np(fd, acl, acl_type) =3D=3D 0)
-		ret =3D ARCHIVE_OK;
-	else
-#endif
-#endif
-	if (acl_set_file(name, acl_type, acl) !=3D 0) {
-		archive_set_error(&a->archive, errno, "Failed to set %s acl", tname);
-		ret =3D ARCHIVE_WARN;
-	}
-	acl_free(acl);
-	return (ret);
-}
-#endif
=20
 #if HAVE_LSETXATTR || HAVE_LSETEA
 /*
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_disk_private.h
--- a/head/contrib/libarchive/libarchive/archive_write_disk_private.h	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_disk_private.h	Fri A=
ug 10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
  * (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/contrib/libarchive/libarchive/archive_write_disk_private=
.h 228763 2011-12-21 11:13:29Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_write_disk_private=
.h 238909 2012-07-30 14:47:35Z mm $
  */
=20
 #ifndef __LIBARCHIVE_BUILD
@@ -33,6 +33,11 @@
 #ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
 #define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
=20
+#include "archive_acl_private.h"
+
 struct archive_write_disk;
=20
+int
+archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /=
* pathname */, struct archive_acl *);
+
 #endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_disk_set_standard_lookup.c
--- a/head/contrib/libarchive/libarchive/archive_write_disk_set_standard_lo=
okup.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_disk_set_standard_lo=
okup.c	Fri Aug 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_disk_=
set_standard_lookup.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_disk_=
set_standard_lookup.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -122,6 +122,7 @@
 		char _buffer[128];
 		size_t bufsize =3D 128;
 		char *buffer =3D _buffer;
+		char *allocated =3D NULL;
 		struct group	grent, *result;
 		int r;
=20
@@ -133,16 +134,15 @@
 			if (r !=3D ERANGE)
 				break;
 			bufsize *=3D 2;
-			if (buffer !=3D _buffer)
-				free(buffer);
-			buffer =3D malloc(bufsize);
-			if (buffer =3D=3D NULL)
+			free(allocated);
+			allocated =3D malloc(bufsize);
+			if (allocated =3D=3D NULL)
 				break;
+			buffer =3D allocated;
 		}
 		if (result !=3D NULL)
 			gid =3D result->gr_gid;
-		if (buffer !=3D _buffer)
-			free(buffer);
+		free(allocated);
 	}
 #  else /* HAVE_GETGRNAM_R */
 	{
@@ -158,7 +158,7 @@
 #else
 	#error No way to perform gid lookups on this platform
 #endif
-	b->id =3D gid;
+	b->id =3D (gid_t)gid;
=20
 	return (gid);
 }
@@ -192,6 +192,7 @@
 		char _buffer[128];
 		size_t bufsize =3D 128;
 		char *buffer =3D _buffer;
+		char *allocated =3D NULL;
 		struct passwd	pwent, *result;
 		int r;
=20
@@ -203,16 +204,15 @@
 			if (r !=3D ERANGE)
 				break;
 			bufsize *=3D 2;
-			if (buffer !=3D _buffer)
-				free(buffer);
-			buffer =3D malloc(bufsize);
-			if (buffer =3D=3D NULL)
+			free(allocated);
+			allocated =3D malloc(bufsize);
+			if (allocated =3D=3D NULL)
 				break;
+			buffer =3D allocated;
 		}
 		if (result !=3D NULL)
 			uid =3D result->pw_uid;
-		if (buffer !=3D _buffer)
-			free(buffer);
+		free(allocated);
 	}
 #  else /* HAVE_GETPWNAM_R */
 	{
@@ -228,7 +228,7 @@
 #else
 	#error No way to look up uids on this platform
 #endif
-	b->id =3D uid;
+	b->id =3D (uid_t)uid;
=20
 	return (uid);
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_filter.3
--- a/head/contrib/libarchive/libarchive/archive_write_filter.3	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_filter.3	Fri Aug 10 =
14:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_FILTER 3
 .Os
 .Sh NAME
@@ -36,6 +36,8 @@
 .Nm archive_write_add_filter_none ,
 .Nm archive_write_add_filter_program ,
 .Nm archive_write_add_filter_xz
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_finish_entry.3
--- a/head/contrib/libarchive/libarchive/archive_write_finish_entry.3	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_finish_entry.3	Fri A=
ug 10 14:19:25 2012 +0300
@@ -22,14 +22,16 @@
 .\" 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 $
+.\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_FINISH_ENTRY 3
 .Os
 .Sh NAME
 .Nm archive_write_finish_entry
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_format.3
--- a/head/contrib/libarchive/libarchive/archive_write_format.3	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_format.3	Fri Aug 10 =
14:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_FORMAT 3
 .Os
 .Sh NAME
@@ -35,6 +35,8 @@
 .Nm archive_write_set_format_shar_dump ,
 .Nm archive_write_set_format_ustar
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_free.3
--- a/head/contrib/libarchive/libarchive/archive_write_free.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_free.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_FREE 3
 .Os
 .Sh NAME
@@ -32,6 +32,8 @@
 .Nm archive_write_finish ,
 .Nm archive_write_free
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_header.3
--- a/head/contrib/libarchive/libarchive/archive_write_header.3	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_header.3	Fri Aug 10 =
14:19:25 2012 +0300
@@ -24,12 +24,14 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_HEADER 3
 .Os
 .Sh NAME
 .Nm archive_write_header
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_new.3
--- a/head/contrib/libarchive/libarchive/archive_write_new.3	Mon Jul 30 11:=
44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_new.3	Fri Aug 10 14:=
19:25 2012 +0300
@@ -24,12 +24,14 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 23, 2011
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_NEW 3
 .Os
 .Sh NAME
 .Nm archive_write_new
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft struct archive *
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_open.3
--- a/head/contrib/libarchive/libarchive/archive_write_open.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_open.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -22,10 +22,10 @@
 .\" 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 $
+.\" $FreeBSD$
 .\"
-.Dd March 23, 2011
-.Dt ARCHIVE_WRITE 3
+.Dd February 2, 2012
+.Dt ARCHIVE_WRITE_OPEN 3
 .Os
 .Sh NAME
 .Nm archive_write_open ,
@@ -34,6 +34,8 @@
 .Nm archive_write_open_filename ,
 .Nm archive_write_open_memory
 .Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .In archive.h
 .Ft int
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_open_filename.c
--- a/head/contrib/libarchive/libarchive/archive_write_open_filename.c	Mon =
Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_open_filename.c	Fri =
Aug 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_open_=
filename.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_open_=
filename.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -54,16 +54,13 @@
=20
 struct write_file_data {
 	int		fd;
-	char		mbs_filename;
-	union {
-		char		m[1];
-		wchar_t		w[1];
-	} filename; /* Must be last! */
+	struct archive_mstring filename;
 };
=20
 static int	file_close(struct archive *, void *);
 static int	file_open(struct archive *, void *);
 static ssize_t	file_write(struct archive *, void *, const void *buff, size=
_t);
+static int	open_filename(struct archive *, int, const void *);
=20
 int
 archive_write_open_file(struct archive *a, const char *filename)
@@ -74,76 +71,69 @@
 int
 archive_write_open_filename(struct archive *a, const char *filename)
 {
-	struct write_file_data *mine;
=20
 	if (filename =3D=3D NULL || filename[0] =3D=3D '\0')
 		return (archive_write_open_fd(a, 1));
=20
-	mine =3D (struct write_file_data *)malloc(sizeof(*mine) + strlen(filename=
));
-	if (mine =3D=3D NULL) {
-		archive_set_error(a, ENOMEM, "No memory");
-		return (ARCHIVE_FATAL);
-	}
-	strcpy(mine->filename.m, filename);
-	mine->mbs_filename =3D 1;
-	mine->fd =3D -1;
-	return (archive_write_open(a, mine,
-		file_open, file_write, file_close));
+	return (open_filename(a, 1, filename));
 }
=20
 int
 archive_write_open_filename_w(struct archive *a, const wchar_t *filename)
 {
-#if defined(_WIN32) && !defined(__CYGWIN__)
-	struct write_file_data *mine;
=20
 	if (filename =3D=3D NULL || filename[0] =3D=3D L'\0')
 		return (archive_write_open_fd(a, 1));
=20
-	mine =3D malloc(sizeof(*mine) + wcslen(filename) * sizeof(wchar_t));
+	return (open_filename(a, 0, filename));
+}
+
+static int
+open_filename(struct archive *a, int mbs_fn, const void *filename)
+{
+	struct write_file_data *mine;
+	int r;
+
+	mine =3D (struct write_file_data *)calloc(1, sizeof(*mine));
 	if (mine =3D=3D NULL) {
 		archive_set_error(a, ENOMEM, "No memory");
 		return (ARCHIVE_FATAL);
 	}
-	wcscpy(mine->filename.w, filename);
-	mine->mbs_filename =3D 0;
+	if (mbs_fn)
+		r =3D archive_mstring_copy_mbs(&mine->filename, filename);
+	else
+		r =3D archive_mstring_copy_wcs(&mine->filename, filename);
+	if (r < 0) {
+		if (errno =3D=3D ENOMEM) {
+			archive_set_error(a, ENOMEM, "No memory");
+			return (ARCHIVE_FATAL);
+		}
+		if (mbs_fn)
+			archive_set_error(a, ARCHIVE_ERRNO_MISC,
+			    "Can't convert '%s' to WCS",
+			    (const char *)filename);
+		else
+			archive_set_error(a, ARCHIVE_ERRNO_MISC,
+			    "Can't convert '%S' to MBS",
+			    (const wchar_t *)filename);
+		return (ARCHIVE_FAILED);
+	}
 	mine->fd =3D -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 =3D=3D NULL || filename[0] =3D=3D L'\0')
-		return (archive_write_open_fd(a, 1));
-
-	archive_string_init(&fn);
-	if (archive_string_append_from_wcs(&fn, filename,
-	    wcslen(filename)) !=3D 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 =3D archive_write_open_filename(a, fn.s);
-	archive_string_free(&fn);
-	return (r);
-#endif
 }
=20
-
 static int
 file_open(struct archive *a, void *client_data)
 {
 	int flags;
 	struct write_file_data *mine;
 	struct stat st;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	wchar_t *fullpath;
+#endif
+	const wchar_t *wcs;
+	const char *mbs;
=20
 	mine =3D (struct write_file_data *)client_data;
 	flags =3D O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
@@ -151,46 +141,51 @@
 	/*
 	 * Open the file.
 	 */
-	if (mine->mbs_filename) {
-		mine->fd =3D 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);
+	mbs =3D NULL; wcs =3D NULL;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	if (archive_mstring_get_wcs(a, &mine->filename, &wcs) !=3D 0) {
+		if (errno =3D=3D ENOMEM)
+			archive_set_error(a, errno, "No memory");
+		else {
+			archive_mstring_get_mbs(a, &mine->filename, &mbs);
+			archive_set_error(a, errno,
+			    "Can't convert '%s' to WCS", mbs);
 		}
+		return (ARCHIVE_FATAL);
+	}
+	fullpath =3D __la_win_permissive_name_w(wcs);
+	if (fullpath !=3D NULL) {
+		mine->fd =3D _wopen(fullpath, flags, 0666);
+		free(fullpath);
+	} else
+		mine->fd =3D _wopen(wcs, flags, 0666);
+#else
+	if (archive_mstring_get_mbs(a, &mine->filename, &mbs) !=3D 0) {
+		if (errno =3D=3D ENOMEM)
+			archive_set_error(a, errno, "No memory");
+		else {
+			archive_mstring_get_wcs(a, &mine->filename, &wcs);
+			archive_set_error(a, errno,
+			    "Can't convert '%S' to MBS", wcs);
+		}
+		return (ARCHIVE_FATAL);
+	}
+	mine->fd =3D open(mbs, flags, 0666);
+#endif
+	if (mine->fd < 0) {
+		if (mbs !=3D NULL)
+			archive_set_error(a, errno, "Failed to open '%s'", mbs);
+		else
+			archive_set_error(a, errno, "Failed to open '%S'", wcs);
+		return (ARCHIVE_FATAL);
+	}
=20
-		if (fstat(mine->fd, &st) !=3D 0) {
-			archive_set_error(a, errno, "Couldn't stat '%s'",
-			    mine->filename.m);
-			return (ARCHIVE_FATAL);
-		}
-	} else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
-		mine->fd =3D _wopen(mine->filename.w, flags, 0666);
-		if (mine->fd < 0 && errno =3D=3D ENOENT) {
-			wchar_t *fullpath;
-			fullpath =3D __la_win_permissive_name_w(mine->filename.w);
-			if (fullpath !=3D NULL) {
-				mine->fd =3D _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) !=3D 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");
+	if (fstat(mine->fd, &st) !=3D 0) {
+		if (mbs !=3D NULL)
+			archive_set_error(a, errno, "Couldn't stat '%s'", mbs);
+		else
+			archive_set_error(a, errno, "Couldn't stat '%S'", wcs);
 		return (ARCHIVE_FATAL);
-#endif
 	}
=20
 	/*
@@ -218,7 +213,8 @@
 }
=20
 static ssize_t
-file_write(struct archive *a, void *client_data, const void *buff, size_t =
length)
+file_write(struct archive *a, void *client_data, const void *buff,
+    size_t length)
 {
 	struct write_file_data	*mine;
 	ssize_t	bytesWritten;
@@ -243,6 +239,7 @@
=20
 	(void)a; /* UNUSED */
 	close(mine->fd);
+	archive_mstring_clean(&mine->filename);
 	free(mine);
 	return (ARCHIVE_OK);
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_private.h
--- a/head/contrib/libarchive/libarchive/archive_write_private.h	Mon Jul 30=
 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_private.h	Fri Aug 10=
 14:19:25 2012 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive/archive_write_private.h 23=
2153 2012-02-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/archive_write_private.h 23=
8856 2012-07-28 06:38:44Z mm $
  */
=20
 #ifndef __LIBARCHIVE_BUILD
@@ -72,7 +72,7 @@
=20
 	/* Dev/ino of the archive being written. */
 	int		  skip_file_set;
-	dev_t		  skip_file_dev;
+	int64_t		  skip_file_dev;
 	int64_t		  skip_file_ino;
=20
 	/* Utility:  Pointer to a block of nulls. */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_7zip.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_7zip.c	Mo=
n Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_7zip.c	Fr=
i Aug 10 14:19:25 2012 +0300
@@ -199,7 +199,7 @@
 	/*
 	 * Compressed data buffer.
 	 */
-	unsigned char		 wbuff[1024 * 64];
+	unsigned char		 wbuff[512 * 20 * 6];
 	size_t			 wbuff_remaining;
=20
 	/*
@@ -498,7 +498,7 @@
 	if (archive_entry_filetype(entry) =3D=3D AE_IFLNK) {
 		ssize_t bytes;
 		const void *p =3D (const void *)archive_entry_symlink(entry);
-		bytes =3D compress_out(a, p, file->size, ARCHIVE_Z_RUN);
+		bytes =3D compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN);
 		if (bytes < 0)
 			return ((int)bytes);
 		zip->entry_crc32 =3D crc32(zip->entry_crc32, p, bytes);
@@ -580,11 +580,11 @@
 	} while (zip->stream.avail_in);
 	if (run =3D=3D ARCHIVE_Z_FINISH) {
 		uint64_t bytes =3D sizeof(zip->wbuff) - zip->stream.avail_out;
-		if (write_to_temp(a, zip->wbuff, bytes) !=3D ARCHIVE_OK)
+		if (write_to_temp(a, zip->wbuff, (size_t)bytes) !=3D ARCHIVE_OK)
 			return (ARCHIVE_FATAL);
 		if ((zip->crc32flg & ENCODED_CRC32) && bytes)
 			zip->encoded_crc32 =3D crc32(zip->encoded_crc32,
-			    zip->wbuff, bytes);
+			    zip->wbuff, (unsigned)bytes);
 	}
=20
 	return (s);
@@ -599,7 +599,7 @@
 	zip =3D (struct _7zip *)a->format_data;
=20
 	if (s > zip->entry_bytes_remaining)
-		s =3D zip->entry_bytes_remaining;
+		s =3D (size_t)zip->entry_bytes_remaining;
 	if (s =3D=3D 0 || zip->cur_file =3D=3D NULL)
 		return (0);
 	bytes =3D compress_out(a, buff, s, ARCHIVE_Z_RUN);
@@ -622,7 +622,7 @@
 		return (ARCHIVE_OK);
=20
 	while (zip->entry_bytes_remaining > 0) {
-		s =3D zip->entry_bytes_remaining;
+		s =3D (size_t)zip->entry_bytes_remaining;
 		if (s > a->null_length)
 			s =3D a->null_length;
 		r =3D _7z_write_data(a, a->nulls, s);
@@ -1151,7 +1151,7 @@
 	struct _7zip *zip =3D (struct _7zip *)a->format_data;
 	struct file *file;
 	int r;
-	uint8_t mask, byte;
+	uint8_t b, mask;
=20
 	/*
 	 * Make Time Bools.
@@ -1188,23 +1188,23 @@
 		if (r < 0)
 			return (r);
=20
-		byte =3D 0;
+		b =3D 0;
 		mask =3D 0x80;
 		file =3D zip->file_list.first;
 		for (;file !=3D NULL; file =3D file->next) {
 			if (file->flg & flg)
-				byte |=3D mask;
+				b |=3D mask;
 			mask >>=3D 1;
 			if (mask =3D=3D 0) {
-				r =3D compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+				r =3D compress_out(a, &b, 1, ARCHIVE_Z_RUN);
 				if (r < 0)
 					return (r);
 				mask =3D 0x80;
-				byte =3D 0;
+				b =3D 0;
 			}
 		}
 		if (mask !=3D 0x80) {
-			r =3D compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+			r =3D compress_out(a, &b, 1, ARCHIVE_Z_RUN);
 			if (r < 0)
 				return (r);
 		}
@@ -1240,7 +1240,7 @@
 	struct _7zip *zip =3D (struct _7zip *)a->format_data;
 	struct file *file;
 	int r;
-	uint8_t mask, byte;
+	uint8_t b, mask;
=20
 	/*
 	 * Make FilesInfo.
@@ -1288,23 +1288,23 @@
 		if (r < 0)
 			return (r);
=20
-		byte =3D 0;
+		b =3D 0;
 		mask =3D 0x80;
 		file =3D zip->file_list.first;
 		for (;file !=3D NULL; file =3D file->next) {
 			if (file->size =3D=3D 0)
-				byte |=3D mask;
+				b |=3D mask;
 			mask >>=3D 1;
 			if (mask =3D=3D 0) {
-				r =3D compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+				r =3D compress_out(a, &b, 1, ARCHIVE_Z_RUN);
 				if (r < 0)
 					return (r);
 				mask =3D 0x80;
-				byte =3D 0;
+				b =3D 0;
 			}
 		}
 		if (mask !=3D 0x80) {
-			r =3D compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+			r =3D compress_out(a, &b, 1, ARCHIVE_Z_RUN);
 			if (r < 0)
 				return (r);
 		}
@@ -1321,25 +1321,25 @@
 		if (r < 0)
 			return (r);
=20
-		byte =3D 0;
+		b =3D 0;
 		mask =3D 0x80;
 		file =3D zip->file_list.first;
 		for (;file !=3D NULL; file =3D file->next) {
 			if (file->size)
 				continue;
 			if (!file->dir)
-				byte |=3D mask;
+				b |=3D mask;
 			mask >>=3D 1;
 			if (mask =3D=3D 0) {
-				r =3D compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+				r =3D compress_out(a, &b, 1, ARCHIVE_Z_RUN);
 				if (r < 0)
 					return (r);
 				mask =3D 0x80;
-				byte =3D 0;
+				b =3D 0;
 			}
 		}
 		if (mask !=3D 0x80) {
-			r =3D compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+			r =3D compress_out(a, &b, 1, ARCHIVE_Z_RUN);
 			if (r < 0)
 				return (r);
 		}
@@ -1492,6 +1492,7 @@
=20
 	if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) {
 		if (errno =3D=3D ENOMEM) {
+			free(file);
 			archive_set_error(&a->archive, ENOMEM,
 			    "Can't allocate memory for UTF-16LE");
 			return (ARCHIVE_FATAL);
@@ -1503,6 +1504,7 @@
 	}
 	file->utf16name =3D malloc(u16len + 2);
 	if (file->utf16name =3D=3D NULL) {
+		free(file);
 		archive_set_error(&a->archive, ENOMEM,
 		    "Can't allocate memory for Name");
 		return (ARCHIVE_FATAL);
@@ -1676,10 +1678,10 @@
 	 * a non-const pointer. */
 	strm->next_in =3D (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
 	strm->avail_in =3D lastrm->avail_in;
-	strm->total_in =3D lastrm->total_in;
+	strm->total_in =3D (uLong)lastrm->total_in;
 	strm->next_out =3D lastrm->next_out;
 	strm->avail_out =3D lastrm->avail_out;
-	strm->total_out =3D lastrm->total_out;
+	strm->total_out =3D (uLong)lastrm->total_out;
 	if (deflateInit2(strm, level, Z_DEFLATED,
 	    (withheader)?15:-15,
 	    8, Z_DEFAULT_STRATEGY) !=3D Z_OK) {
@@ -1709,10 +1711,10 @@
 	 * a non-const pointer. */
 	strm->next_in =3D (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
 	strm->avail_in =3D lastrm->avail_in;
-	strm->total_in =3D lastrm->total_in;
+	strm->total_in =3D (uLong)lastrm->total_in;
 	strm->next_out =3D lastrm->next_out;
 	strm->avail_out =3D lastrm->avail_out;
-	strm->total_out =3D lastrm->total_out;
+	strm->total_out =3D (uLong)lastrm->total_out;
 	r =3D deflate(strm,
 	    (action =3D=3D ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
 	lastrm->next_in =3D strm->next_in;
@@ -1914,6 +1916,7 @@
 	if (level > 6)
 		level =3D 6;
 	if (lzma_lzma_preset(&lzma_opt, level)) {
+		free(strm);
 		lastrm->real_stream =3D NULL;
 		archive_set_error(a, ENOMEM,
 		    "Internal error initializing compression library");
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_ar.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_ar.c	Mon =
Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_ar.c	Fri =
Aug 10 14:19:25 2012 +0300
@@ -26,7 +26,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_ar.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_ar.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -366,7 +366,7 @@
=20
 	ar =3D (struct ar_w *)a->format_data;
 	if (s > ar->entry_bytes_remaining)
-		s =3D ar->entry_bytes_remaining;
+		s =3D (size_t)ar->entry_bytes_remaining;
=20
 	if (ar->is_strtab > 0) {
 		if (ar->has_strtab > 0) {
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_cpio.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_cpio.c	Mo=
n Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_cpio.c	Fr=
i Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_cpio.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_cpio.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -189,7 +189,7 @@
=20
 	/* Don't store a mapping if we don't need to. */
 	if (archive_entry_nlink(entry) < 2) {
-		return ++cpio->ino_next;
+		return (int)(++cpio->ino_next);
 	}
=20
 	/* Look up old ino; if we have it, this is a hardlink
@@ -200,7 +200,7 @@
 	}
=20
 	/* Assign a new index number. */
-	ino_new =3D ++cpio->ino_next;
+	ino_new =3D (int)(++cpio->ino_next);
=20
 	/* Ensure space for the new mapping. */
 	if (cpio->ino_list_size <=3D cpio->ino_list_next) {
@@ -421,7 +421,7 @@
=20
 	cpio =3D (struct cpio *)a->format_data;
 	if (s > cpio->entry_bytes_remaining)
-		s =3D cpio->entry_bytes_remaining;
+		s =3D (size_t)cpio->entry_bytes_remaining;
=20
 	ret =3D __archive_write_output(a, buff, s);
 	cpio->entry_bytes_remaining -=3D s;
@@ -457,7 +457,7 @@
 	if (s =3D=3D 0)
 		return (v);
 	v =3D format_octal_recursive(v, p+1, s-1);
-	*p =3D '0' + (v & 7);
+	*p =3D '0' + ((char)v & 7);
 	return (v >> 3);
 }
=20
@@ -495,5 +495,6 @@
 	struct cpio *cpio;
=20
 	cpio =3D (struct cpio *)a->format_data;
-	return (__archive_write_nulls(a, cpio->entry_bytes_remaining));
+	return (__archive_write_nulls(a,
+		(size_t)cpio->entry_bytes_remaining));
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_cpio_newc.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc=
.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc=
.c	Fri Aug 10 14:19:25 2012 +0300
@@ -26,7 +26,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_cpio_newc.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_cpio_newc.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -350,7 +350,7 @@
 	}
=20
 	cpio->entry_bytes_remaining =3D archive_entry_size(entry);
-	cpio->padding =3D PAD4(cpio->entry_bytes_remaining);
+	cpio->padding =3D (int)PAD4(cpio->entry_bytes_remaining);
=20
 	/* Write the symlink now. */
 	if (p !=3D NULL  &&  *p !=3D '\0') {
@@ -380,7 +380,7 @@
=20
 	cpio =3D (struct cpio *)a->format_data;
 	if (s > cpio->entry_bytes_remaining)
-		s =3D cpio->entry_bytes_remaining;
+		s =3D (size_t)cpio->entry_bytes_remaining;
=20
 	ret =3D __archive_write_output(a, buff, s);
 	cpio->entry_bytes_remaining -=3D s;
@@ -453,5 +453,6 @@
 	struct cpio *cpio;
=20
 	cpio =3D (struct cpio *)a->format_data;
-	return (__archive_write_nulls(a, cpio->entry_bytes_remaining + cpio->padd=
ing));
+	return (__archive_write_nulls(a,
+		(size_t)cpio->entry_bytes_remaining + cpio->padding));
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_gnutar.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c	=
Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c	=
Fri Aug 10 14:19:25 2012 +0300
@@ -247,8 +247,8 @@
 	int ret;
=20
 	gnutar =3D (struct gnutar *)a->format_data;
-	ret =3D __archive_write_nulls(a,
-	    gnutar->entry_bytes_remaining + gnutar->entry_padding);
+	ret =3D __archive_write_nulls(a, (size_t)
+	    (gnutar->entry_bytes_remaining + gnutar->entry_padding));
 	gnutar->entry_bytes_remaining =3D gnutar->entry_padding =3D 0;
 	return (ret);
 }
@@ -261,7 +261,7 @@
=20
 	gnutar =3D (struct gnutar *)a->format_data;
 	if (s > gnutar->entry_bytes_remaining)
-		s =3D gnutar->entry_bytes_remaining;
+		s =3D (size_t)gnutar->entry_bytes_remaining;
 	ret =3D __archive_write_output(a, buff, s);
 	gnutar->entry_bytes_remaining -=3D s;
 	if (ret !=3D ARCHIVE_OK)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_iso9660.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c=
	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c=
	Fri Aug 10 14:19:25 2012 +0300
@@ -1698,7 +1698,7 @@
 	size_t ns;
 	int ret;
=20
-	ns =3D csize % LOGICAL_BLOCK_SIZE;
+	ns =3D (size_t)(csize % LOGICAL_BLOCK_SIZE);
 	if (ns !=3D 0)
 		ret =3D write_null(a, LOGICAL_BLOCK_SIZE - ns);
 	else
@@ -1725,8 +1725,8 @@
 		struct content *con;
 		size_t ts;
=20
-		ts =3D MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
-		    iso9660->cur_file->cur_content->size;
+		ts =3D (size_t)(MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
+		    iso9660->cur_file->cur_content->size);
=20
 		if (iso9660->zisofs.detect_magic)
 			zisofs_detect_magic(a, buff, ts);
@@ -1746,9 +1746,9 @@
 			return (ARCHIVE_FATAL);
=20
 		/* Compute the logical block number. */
-		iso9660->cur_file->cur_content->blocks =3D
-		    (iso9660->cur_file->cur_content->size
-		     + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+		iso9660->cur_file->cur_content->blocks =3D (int)
+		    ((iso9660->cur_file->cur_content->size
+		     + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
=20
 		/*
 		 * Make next extent.
@@ -1796,7 +1796,7 @@
 	if (archive_entry_filetype(iso9660->cur_file->entry) !=3D AE_IFREG)
 		return (0);
 	if (s > iso9660->bytes_remaining)
-		s =3D iso9660->bytes_remaining;
+		s =3D (size_t)iso9660->bytes_remaining;
 	if (s =3D=3D 0)
 		return (0);
=20
@@ -1838,9 +1838,9 @@
 		return (ARCHIVE_FATAL);
=20
 	/* Compute the logical block number. */
-	iso9660->cur_file->cur_content->blocks =3D
-	    (iso9660->cur_file->cur_content->size
-	     + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+	iso9660->cur_file->cur_content->blocks =3D (int)
+	    ((iso9660->cur_file->cur_content->size
+	     + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
=20
 	/* Add the current file to data file list. */
 	isofile_add_data_file(iso9660, iso9660->cur_file);
@@ -2244,7 +2244,7 @@
 		onepad =3D 0;
 	if (vdc =3D=3D VDC_UCS2) {
 		struct iso9660 *iso9660 =3D a->format_data;
-		if (archive_strncpy_in_locale(&iso9660->utf16be, s, strlen(s),
+		if (archive_strncpy_l(&iso9660->utf16be, s, strlen(s),
 		    iso9660->sconv_to_utf16be) !=3D 0 && errno =3D=3D ENOMEM) {
 			archive_set_error(&a->archive, ENOMEM,
 			    "Can't allocate memory for UTF-16BE");
@@ -2547,7 +2547,7 @@
 	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));
+	set_num_712(p+16, (char)(get_gmoffset(&tm)/(60*15)));
 }
=20
 static void
@@ -2569,7 +2569,7 @@
 	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));
+	set_num_712(p+6, (char)(get_gmoffset(&tm)/(60*15)));
 }
=20
=20
@@ -2941,8 +2941,8 @@
 			bp =3D extra_next_record(&ctl, length);
 		if (bp !=3D NULL) {
 			mode_t mode;
-			uid_t uid;
-			gid_t gid;
+			int64_t uid;
+			int64_t gid;
=20
 			mode =3D archive_entry_mode(file->entry);
 			uid =3D archive_entry_uid(file->entry);
@@ -2975,8 +2975,8 @@
 			/* 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);
+			set_num_733(bp+21, (uint32_t)uid);
+			set_num_733(bp+29, (uint32_t)gid);
 			/* File Serial Number */
 			if (pxent->dir)
 				set_num_733(bp+37, pxent->dir_location);
@@ -3357,8 +3357,8 @@
 			bp[3] =3D length;
 			bp[4] =3D 1;	/* version	*/
 			dev =3D (uint64_t)archive_entry_rdev(file->entry);
-			set_num_733(bp + 5, dev >> 32);
-			set_num_733(bp + 13, dev & 0xFFFFFFFF);
+			set_num_733(bp + 5, (uint32_t)(dev >> 32));
+			set_num_733(bp + 13, (uint32_t)(dev & 0xFFFFFFFF));
 			bp +=3D length;
 		}
 		extra_tell_used_size(&ctl, length);
@@ -3492,7 +3492,7 @@
 			set_num_733(bp+11,
 			    xisoent->dir_block * LOGICAL_BLOCK_SIZE);
 		else
-			set_num_733(bp+11, file->cur_content->size);
+			set_num_733(bp+11, (uint32_t)file->cur_content->size);
 		/* Recording Date and Time */
 		/* NOTE:
 		 *  If a file type is symbolic link, you are seeing this
@@ -3669,7 +3669,7 @@
 		iso9660->wbuff_tail =3D iso9660->wbuff_offset + used;
 	if (iso9660->wbuff_offset < iso9660->wbuff_written) {
 		if (used > 0 &&
-		    write_to_temp(a, iso9660->wbuff, used) !=3D ARCHIVE_OK)
+		    write_to_temp(a, iso9660->wbuff, (size_t)used) !=3D ARCHIVE_OK)
 			return (ARCHIVE_FATAL);
 		iso9660->wbuff_offset =3D iso9660->wbuff_written;
 		lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
@@ -3688,12 +3688,12 @@
 		iso9660->wbuff_offset =3D off;
 		iso9660->wbuff_remaining =3D sizeof(iso9660->wbuff);
 	} else if (off <=3D iso9660->wbuff_tail) {
-		iso9660->wbuff_remaining =3D
-		    sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset);
+		iso9660->wbuff_remaining =3D (size_t)
+		    (sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset));
 	} else {
 		ext_bytes =3D off - iso9660->wbuff_tail;
-		iso9660->wbuff_remaining =3D sizeof(iso9660->wbuff)
-		   - (iso9660->wbuff_tail - iso9660->wbuff_offset);
+		iso9660->wbuff_remaining =3D (size_t)(sizeof(iso9660->wbuff)
+		   - (iso9660->wbuff_tail - iso9660->wbuff_offset));
 		while (ext_bytes >=3D (int64_t)iso9660->wbuff_remaining) {
 			if (write_null(a, (size_t)iso9660->wbuff_remaining)
 			    !=3D ARCHIVE_OK)
@@ -4814,13 +4814,19 @@
 		struct archive_wstring ws;
=20
 		if (wp !=3D NULL) {
+			int r;
 			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),
+			r =3D archive_string_append_from_wcs(&(file->parentdir),
 			    ws.s, ws.length);
 			archive_wstring_free(&ws);
+			if (r < 0 && errno =3D=3D ENOMEM) {
+				archive_set_error(&a->archive, ENOMEM,
+				    "Can't allocate memory");
+				return (ARCHIVE_FATAL);
+			}
 		}
 	}
 #endif
@@ -4923,14 +4929,20 @@
 			struct archive_wstring ws;
=20
 			if (wp !=3D NULL) {
+				int r;
 				archive_string_init(&ws);
 				archive_wstrcpy(&ws, wp);
 				cleanup_backslash_2(ws.s);
 				archive_string_empty(&(file->symlink));
-				archive_string_append_from_wcs(
+				r =3D archive_string_append_from_wcs(
 				    &(file->symlink),
 				    ws.s, ws.length);
 				archive_wstring_free(&ws);
+				if (r < 0 && errno =3D=3D ENOMEM) {
+					archive_set_error(&a->archive, ENOMEM,
+					    "Can't allocate memory");
+					return (ARCHIVE_FATAL);
+				}
 			}
 		}
 #endif
@@ -5426,8 +5438,8 @@
 	iso9660->total_file_block =3D 0;
 	if ((isoent =3D iso9660->el_torito.catalog) !=3D NULL) {
 		isoent->file->content.location =3D location;
-		block =3D (archive_entry_size(isoent->file->entry) +
-		    LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+		block =3D (int)((archive_entry_size(isoent->file->entry) +
+		    LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
 		location +=3D block;
 		iso9660->total_file_block +=3D block;
 	}
@@ -5435,7 +5447,7 @@
 		isoent->file->content.location =3D location;
 		size =3D fd_boot_image_size(iso9660->el_torito.media_type);
 		if (size =3D=3D 0)
-			size =3D archive_entry_size(isoent->file->entry);
+			size =3D (size_t)archive_entry_size(isoent->file->entry);
 		block =3D (size + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
 		location +=3D block;
 		iso9660->total_file_block +=3D block;
@@ -6262,9 +6274,14 @@
 		 * Get a length of MBS of a full-pathname.
 		 */
 		if ((int)np->file->basename_utf16.length > ffmax) {
-			archive_strncpy_in_locale(&iso9660->mbs,
+			if (archive_strncpy_l(&iso9660->mbs,
 			    (const char *)np->identifier, l,
-			    iso9660->sconv_from_utf16be);
+				iso9660->sconv_from_utf16be) !=3D 0 &&
+			    errno =3D=3D ENOMEM) {
+				archive_set_error(&a->archive, errno,
+				    "No memory");
+				return (ARCHIVE_FATAL);
+			}
 			np->mb_len =3D iso9660->mbs.length;
 			if (np->mb_len !=3D (int)np->file->basename.length)
 				weight =3D np->mb_len;
@@ -6364,7 +6381,7 @@
 			if (0x20 !=3D *s2++)
 				return (0x20
 				    - *(const unsigned char *)(s2 - 1));
-	} else if (p1->ext_len < p2->ext_len) {
+	} else if (p1->ext_len > p2->ext_len) {
 		s1 +=3D l;
 		l =3D p1->ext_len - p2->ext_len;
 		while (l--)
@@ -6452,7 +6469,7 @@
 		while (l--)
 			if (0 !=3D *s2++)
 				return (- *(const unsigned char *)(s2 - 1));
-	} else if (p1->ext_len < p2->ext_len) {
+	} else if (p1->ext_len > p2->ext_len) {
 		s1 +=3D l;
 		l =3D p1->ext_len - p2->ext_len;
 		while (l--)
@@ -6622,7 +6639,7 @@
  */
 static int
 isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
-    struct isoent *isoent, struct isoent **newent)
+    struct isoent *curent, struct isoent **newent)
 {
 	struct iso9660 *iso9660 =3D a->format_data;
 	struct isoent *rrmoved, *mvent, *np;
@@ -6648,40 +6665,40 @@
 		*rr_moved =3D rrmoved;
 	}
 	/*
-	 * Make a clone of isoent which is going to be relocated
+	 * Make a clone of curent which is going to be relocated
 	 * to rr_moved.
 	 */
-	mvent =3D isoent_clone(isoent);
+	mvent =3D isoent_clone(curent);
 	if (mvent =3D=3D 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 =3D isoent->parent;
-	isoent->rr_child =3D mvent;
+	mvent->rr_parent =3D curent->parent;
+	curent->rr_child =3D mvent;
 	/*
-	 * Move subdirectories from the isoent to mvent
+	 * Move subdirectories from the curent to mvent
 	 */
-	if (isoent->children.first !=3D NULL) {
-		*mvent->children.last =3D isoent->children.first;
-		mvent->children.last =3D isoent->children.last;
+	if (curent->children.first !=3D NULL) {
+		*mvent->children.last =3D curent->children.first;
+		mvent->children.last =3D curent->children.last;
 	}
 	for (np =3D mvent->children.first; np !=3D NULL; np =3D np->chnext)
 		np->parent =3D mvent;
-	mvent->children.cnt =3D isoent->children.cnt;
-	isoent->children.cnt =3D 0;
-	isoent->children.first =3D NULL;
-	isoent->children.last =3D &isoent->children.first;
-
-	if (isoent->subdirs.first !=3D NULL) {
-		*mvent->subdirs.last =3D isoent->subdirs.first;
-		mvent->subdirs.last =3D isoent->subdirs.last;
-	}
-	mvent->subdirs.cnt =3D isoent->subdirs.cnt;
-	isoent->subdirs.cnt =3D 0;
-	isoent->subdirs.first =3D NULL;
-	isoent->subdirs.last =3D &isoent->subdirs.first;
+	mvent->children.cnt =3D curent->children.cnt;
+	curent->children.cnt =3D 0;
+	curent->children.first =3D NULL;
+	curent->children.last =3D &curent->children.first;
+
+	if (curent->subdirs.first !=3D NULL) {
+		*mvent->subdirs.last =3D curent->subdirs.first;
+		mvent->subdirs.last =3D curent->subdirs.last;
+	}
+	mvent->subdirs.cnt =3D curent->subdirs.cnt;
+	curent->subdirs.cnt =3D 0;
+	curent->subdirs.first =3D NULL;
+	curent->subdirs.last =3D &curent->subdirs.first;
=20
 	/*
 	 * The mvent becomes a child of the rr_moved entry.
@@ -6694,7 +6711,7 @@
 	 * has to set the flag as a file.
 	 * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
 	 */
-	isoent->dir =3D 0;
+	curent->dir =3D 0;
=20
 	*newent =3D mvent;
=20
@@ -7408,7 +7425,8 @@
 	/* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
 	file->zisofs.header_size =3D ZF_HEADER_SIZE >> 2;
 	file->zisofs.log2_bs =3D ZF_LOG2_BS;
-	file->zisofs.uncompressed_size =3D archive_entry_size(file->entry);
+	file->zisofs.uncompressed_size =3D
+		(uint32_t)archive_entry_size(file->entry);
=20
 	/* Calculate a size of Block Pointers of zisofs. */
 	ceil =3D (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
@@ -7436,13 +7454,14 @@
 	 * file.
 	 */
 	tsize =3D ZF_HEADER_SIZE + bpsize;
-	if (write_null(a, tsize) !=3D ARCHIVE_OK)
+	if (write_null(a, (size_t)tsize) !=3D ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
=20
 	/*
 	 * Initialize some variables to make zisofs.
 	 */
-	archive_le32enc(&(iso9660->zisofs.block_pointers[0]), tsize);
+	archive_le32enc(&(iso9660->zisofs.block_pointers[0]),
+		(uint32_t)tsize);
 	iso9660->zisofs.remaining =3D file->zisofs.uncompressed_size;
 	iso9660->zisofs.making =3D 1;
 	iso9660->zisofs.allzero =3D 1;
@@ -7471,7 +7490,7 @@
=20
 	entry_size =3D archive_entry_size(file->entry);
 	if ((int64_t)sizeof(iso9660->zisofs.magic_buffer) > entry_size)
-		magic_max =3D entry_size;
+		magic_max =3D (int)entry_size;
 	else
 		magic_max =3D sizeof(iso9660->zisofs.magic_buffer);
=20
@@ -7647,7 +7666,7 @@
 			iso9660->zisofs.block_pointers_idx ++;
 			archive_le32enc(&(iso9660->zisofs.block_pointers[
 			    iso9660->zisofs.block_pointers_idx]),
-				iso9660->zisofs.total_size);
+				(uint32_t)iso9660->zisofs.total_size);
 			r =3D zisofs_init_zstream(a);
 			if (r !=3D ARCHIVE_OK)
 				return (ARCHIVE_FATAL);
@@ -7776,9 +7795,9 @@
 	size_t ceil, xsize;
=20
 	/* Allocate block pointers buffer. */
-	ceil =3D (zisofs->pz_uncompressed_size +
-		(1LL << zisofs->pz_log2_bs) - 1)
-		>> zisofs->pz_log2_bs;
+	ceil =3D (size_t)((zisofs->pz_uncompressed_size +
+		(((int64_t)1) << zisofs->pz_log2_bs) - 1)
+		>> zisofs->pz_log2_bs);
 	xsize =3D (ceil + 1) * 4;
 	if (zisofs->block_pointers =3D=3D NULL) {
 		size_t alloc =3D ((xsize >> 10) + 1) << 10;
@@ -7999,7 +8018,7 @@
 	fd =3D iso9660->temp_fd;
 	new_offset =3D wb_offset(a);
 	read_offset =3D file->content.offset_of_temp;
-	remaining =3D file->content.size;
+	remaining =3D (size_t)file->content.size;
 	if (remaining > 1024 * 32)
 		rbuff_size =3D 1024 * 32;
 	else
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_mtree.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_mtree.c	M=
on Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_mtree.c	F=
ri Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_mtree.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_mtree.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -389,13 +389,13 @@
 		else if (*p =3D=3D '/')
 			al =3D p - path;
 	}
-	if (l =3D=3D -1)
+	if (l =3D=3D (size_t)-1)
 		goto alen;
 	size =3D p - path;
 	rp =3D p =3D path;
 	while (*p !=3D '\0') {
 		l =3D mbtowc(&wc, p, size);
-		if (l =3D=3D -1)
+		if (l =3D=3D (size_t)-1)
 			goto alen;
 		if (l =3D=3D 1 && (wc =3D=3D L'/' || wc =3D=3D L'\\'))
 			rp =3D p;
@@ -404,7 +404,7 @@
 	}
 	return (rp - path + 1);
 alen:
-	if (al =3D=3D -1)
+	if (al =3D=3D (size_t)-1)
 		return (0);
 	return (al + 1);
 }
@@ -1079,7 +1079,7 @@
 	struct mtree_writer *mtree=3D a->format_data;
=20
 	if (n > mtree->entry_bytes_remaining)
-		n =3D mtree->entry_bytes_remaining;
+		n =3D (size_t)mtree->entry_bytes_remaining;
 	mtree->entry_bytes_remaining -=3D n;
=20
 	/* We don't need to compute a regular file sum */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_pax.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_pax.c	Mon=
 Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_pax.c	Fri=
 Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_pax.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_pax.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -334,8 +334,7 @@
 		url_encoded_name =3D url_encode(name);
 		if (url_encoded_name !=3D NULL) {
 			/* Convert narrow-character to UTF-8. */
-			r =3D archive_strcpy_in_locale(
-			    &(pax->l_url_encoded_name),
+			r =3D archive_strcpy_l(&(pax->l_url_encoded_name),
 			    url_encoded_name, pax->sconv_utf8);
 			free(url_encoded_name); /* Done with this. */
 			if (r =3D=3D 0)
@@ -1324,7 +1323,7 @@
 			return (ARCHIVE_FATAL);
 		}
 		/* Pad out the end of the entry. */
-		r =3D __archive_write_nulls(a, pax->entry_padding);
+		r =3D __archive_write_nulls(a, (size_t)pax->entry_padding);
 		if (r !=3D ARCHIVE_OK) {
 			/* If a write fails, we're pretty much toast. */
 			return (ARCHIVE_FATAL);
@@ -1666,7 +1665,7 @@
 			pax->sparse_list =3D sb;
 		}
 	}
-	ret =3D __archive_write_nulls(a, remaining + pax->entry_padding);
+	ret =3D __archive_write_nulls(a, (size_t)(remaining + pax->entry_padding)=
);
 	pax->entry_bytes_remaining =3D pax->entry_padding =3D 0;
 	return (ret);
 }
@@ -1713,7 +1712,7 @@
 		p =3D ((const unsigned char *)buff) + total;
 		ws =3D s - total;
 		if (ws > pax->sparse_list->remaining)
-			ws =3D pax->sparse_list->remaining;
+			ws =3D (size_t)pax->sparse_list->remaining;
=20
 		if (pax->sparse_list->is_hole) {
 			/* Current block is hole thus we do not write
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_ustar.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_ustar.c	M=
on Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_ustar.c	F=
ri Aug 10 14:19:25 2012 +0300
@@ -25,7 +25,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_ustar.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_ustar.c 238856 2012-07-28 06:38:44Z mm $");
=20
=20
 #ifdef HAVE_ERRNO_H
@@ -742,7 +742,7 @@
=20
 	ustar =3D (struct ustar *)a->format_data;
 	ret =3D __archive_write_nulls(a,
-	    ustar->entry_bytes_remaining + ustar->entry_padding);
+	    (size_t)(ustar->entry_bytes_remaining + ustar->entry_padding));
 	ustar->entry_bytes_remaining =3D ustar->entry_padding =3D 0;
 	return (ret);
 }
@@ -755,7 +755,7 @@
=20
 	ustar =3D (struct ustar *)a->format_data;
 	if (s > ustar->entry_bytes_remaining)
-		s =3D ustar->entry_bytes_remaining;
+		s =3D (size_t)ustar->entry_bytes_remaining;
 	ret =3D __archive_write_output(a, buff, s);
 	ustar->entry_bytes_remaining -=3D s;
 	if (ret !=3D ARCHIVE_OK)
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_xar.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_xar.c	Mon=
 Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_xar.c	Fri=
 Aug 10 14:19:25 2012 +0300
@@ -46,10 +46,6 @@
 #include <zlib.h>
 #endif
=20
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif
-
 #include "archive.h"
 #include "archive_crypto_private.h"
 #include "archive_endian.h"
@@ -660,7 +656,7 @@
 	xar =3D (struct xar *)a->format_data;
=20
 	if (s > xar->bytes_remaining)
-		s =3D xar->bytes_remaining;
+		s =3D (size_t)xar->bytes_remaining;
 	if (s =3D=3D 0 || xar->cur_file =3D=3D NULL)
 		return (0);
 	if (xar->cur_file->data.compression =3D=3D NONE) {
@@ -741,7 +737,7 @@
 		return (ARCHIVE_OK);
=20
 	while (xar->bytes_remaining > 0) {
-		s =3D xar->bytes_remaining;
+		s =3D (size_t)xar->bytes_remaining;
 		if (s > a->null_length)
 			s =3D a->null_length;
 		w =3D xar_write_data(a, a->nulls, s);
@@ -2600,10 +2596,10 @@
 	 * a non-const pointer. */
 	strm->next_in =3D (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
 	strm->avail_in =3D lastrm->avail_in;
-	strm->total_in =3D lastrm->total_in;
+	strm->total_in =3D (uLong)lastrm->total_in;
 	strm->next_out =3D lastrm->next_out;
 	strm->avail_out =3D lastrm->avail_out;
-	strm->total_out =3D lastrm->total_out;
+	strm->total_out =3D (uLong)lastrm->total_out;
 	if (deflateInit2(strm, level, Z_DEFLATED,
 	    (withheader)?15:-15,
 	    8, Z_DEFAULT_STRATEGY) !=3D Z_OK) {
@@ -2633,10 +2629,10 @@
 	 * a non-const pointer. */
 	strm->next_in =3D (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
 	strm->avail_in =3D lastrm->avail_in;
-	strm->total_in =3D lastrm->total_in;
+	strm->total_in =3D (uLong)lastrm->total_in;
 	strm->next_out =3D lastrm->next_out;
 	strm->avail_out =3D lastrm->avail_out;
-	strm->total_out =3D lastrm->total_out;
+	strm->total_out =3D (uLong)lastrm->total_out;
 	r =3D deflate(strm,
 	    (action =3D=3D ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
 	lastrm->next_in =3D strm->next_in;
@@ -2872,6 +2868,7 @@
 	if (level > 6)
 		level =3D 6;
 	if (lzma_lzma_preset(&lzma_opt, level)) {
+		free(strm);
 		lastrm->real_stream =3D NULL;
 		archive_set_error(a, ENOMEM,
 		    "Internal error initializing compression library");
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_format_zip.c
--- a/head/contrib/libarchive/libarchive/archive_write_set_format_zip.c	Mon=
 Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_format_zip.c	Fri=
 Aug 10 14:19:25 2012 +0300
@@ -48,7 +48,7 @@
  */
=20
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_zip.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_write_set_f=
ormat_zip.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -109,69 +109,75 @@
 static size_t path_length(struct archive_entry *);
 static int write_path(struct archive_entry *, struct archive_write *);
=20
-struct zip_local_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];
-};
+#define LOCAL_FILE_HEADER_SIGNATURE		0
+#define LOCAL_FILE_HEADER_VERSION		4
+#define LOCAL_FILE_HEADER_FLAGS			6
+#define LOCAL_FILE_HEADER_COMPRESSION		8
+#define LOCAL_FILE_HEADER_TIMEDATE		10
+#define LOCAL_FILE_HEADER_CRC32			14
+#define LOCAL_FILE_HEADER_COMPRESSED_SIZE	18
+#define LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE	22
+#define LOCAL_FILE_HEADER_FILENAME_LENGTH	26
+#define LOCAL_FILE_HEADER_EXTRA_LENGTH		28
+#define SIZE_LOCAL_FILE_HEADER			30
=20
-struct zip_file_header {
-	char signature[4];
-	char version_by[2];
-	char version_extract[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];
-	char comment_length[2];
-	char disk_number[2];
-	char attributes_internal[2];
-	char attributes_external[4];
-	char offset[4];
-};
+#define FILE_HEADER_SIGNATURE			0
+#define FILE_HEADER_VERSION_BY			4
+#define FILE_HEADER_VERSION_EXTRACT		6
+#define FILE_HEADER_FLAGS			8
+#define FILE_HEADER_COMPRESSION			10
+#define FILE_HEADER_TIMEDATE			12
+#define FILE_HEADER_CRC32			16
+#define FILE_HEADER_COMPRESSED_SIZE		20
+#define FILE_HEADER_UNCOMPRESSED_SIZE		24
+#define FILE_HEADER_FILENAME_LENGTH		28
+#define FILE_HEADER_EXTRA_LENGTH		30
+#define FILE_HEADER_COMMENT_LENGTH		32
+#define FILE_HEADER_DISK_NUMBER			34
+#define FILE_HEADER_ATTRIBUTES_INTERNAL		36
+#define FILE_HEADER_ATTRIBUTES_EXTERNAL		38
+#define FILE_HEADER_OFFSET			42
+#define SIZE_FILE_HEADER			46
=20
-struct zip_data_descriptor {
-	char signature[4]; /* Not mandatory, but recommended by specification. */
-	char crc32[4];
-	char compressed_size[4];
-	char uncompressed_size[4];
-};
+	/* Not mandatory, but recommended by specification. */
+#define DATA_DESCRIPTOR_SIGNATURE		0
+#define DATA_DESCRIPTOR_CRC32			4
+#define DATA_DESCRIPTOR_COMPRESSED_SIZE		8
+#define DATA_DESCRIPTOR_UNCOMPRESSED_SIZE	12
+#define SIZE_DATA_DESCRIPTOR			16
=20
-struct zip_extra_data_local {
-	char time_id[2];
-	char time_size[2];
-	char time_flag[1];
-	char mtime[4];
-	char atime[4];
-	char ctime[4];
-	char unix_id[2];
-	char unix_size[2];
-	char unix_version;
-	char unix_uid_size;
-	char unix_uid[4];
-	char unix_gid_size;
-	char unix_gid[4];
-};
+#define EXTRA_DATA_LOCAL_TIME_ID		0
+#define EXTRA_DATA_LOCAL_TIME_SIZE		2
+#define EXTRA_DATA_LOCAL_TIME_FLAG		4
+#define EXTRA_DATA_LOCAL_MTIME			5
+#define EXTRA_DATA_LOCAL_ATIME			9
+#define EXTRA_DATA_LOCAL_CTIME			13
+#define EXTRA_DATA_LOCAL_UNIX_ID		17
+#define EXTRA_DATA_LOCAL_UNIX_SIZE		19
+#define EXTRA_DATA_LOCAL_UNIX_VERSION		21
+#define EXTRA_DATA_LOCAL_UNIX_UID_SIZE		22
+#define EXTRA_DATA_LOCAL_UNIX_UID		23
+#define EXTRA_DATA_LOCAL_UNIX_GID_SIZE		27
+#define EXTRA_DATA_LOCAL_UNIX_GID		28
+#define SIZE_EXTRA_DATA_LOCAL			32
=20
-struct zip_extra_data_central {
-	char time_id[2];
-	char time_size[2];
-	char time_flag[1];
-	char mtime[4];
-	char unix_id[2];
-	char unix_size[2];
-};
+#define EXTRA_DATA_CENTRAL_TIME_ID		0
+#define EXTRA_DATA_CENTRAL_TIME_SIZE		2
+#define EXTRA_DATA_CENTRAL_TIME_FLAG		4
+#define EXTRA_DATA_CENTRAL_MTIME		5
+#define EXTRA_DATA_CENTRAL_UNIX_ID		9
+#define EXTRA_DATA_CENTRAL_UNIX_SIZE		11
+#define SIZE_EXTRA_DATA_CENTRAL			13
+
+#define CENTRAL_DIRECTORY_END_SIGNATURE		0
+#define CENTRAL_DIRECTORY_END_DISK		4
+#define CENTRAL_DIRECTORY_END_START_DISK	6
+#define CENTRAL_DIRECTORY_END_ENTRIES_DISK	8
+#define CENTRAL_DIRECTORY_END_ENTRIES		10
+#define CENTRAL_DIRECTORY_END_SIZE		12
+#define CENTRAL_DIRECTORY_END_OFFSET		16
+#define CENTRAL_DIRECTORY_END_COMMENT_LENGTH	20
+#define SIZE_CENTRAL_DIRECTORY_END		22
=20
 struct zip_file_header_link {
 	struct zip_file_header_link *next;
@@ -184,7 +190,7 @@
 };
=20
 struct zip {
-	struct zip_data_descriptor data_descriptor;
+	uint8_t data_descriptor[SIZE_DATA_DESCRIPTOR];
 	struct zip_file_header_link *central_directory;
 	struct zip_file_header_link *central_directory_end;
 	int64_t offset;
@@ -203,17 +209,6 @@
 #endif
 };
=20
-struct zip_central_directory_end {
-	char signature[4];
-	char disk[2];
-	char start_disk[2];
-	char entries_disk[2];
-	char entries[2];
-	char size[4];
-	char offset[4];
-	char comment_length[2];
-};
-
 static int
 archive_write_zip_options(struct archive_write *a, const char *key,
     const char *val)
@@ -291,6 +286,7 @@
 	zip->len_buf =3D 65536;
 	zip->buf =3D malloc(zip->len_buf);
 	if (zip->buf =3D=3D NULL) {
+		free(zip);
 		archive_set_error(&a->archive, ENOMEM,
 		    "Can't allocate compression buffer");
 		return (ARCHIVE_FATAL);
@@ -310,7 +306,7 @@
 	a->archive.archive_format =3D ARCHIVE_FORMAT_ZIP;
 	a->archive.archive_format_name =3D "ZIP";
=20
-	archive_le32enc(&zip->data_descriptor.signature,
+	archive_le32enc(&zip->data_descriptor[DATA_DESCRIPTOR_SIGNATURE],
 	    ZIP_SIGNATURE_DATA_DESCRIPTOR);
=20
 	return (ARCHIVE_OK);
@@ -332,9 +328,9 @@
 archive_write_zip_header(struct archive_write *a, struct archive_entry *en=
try)
 {
 	struct zip *zip;
-	struct zip_local_file_header h;
-	struct zip_extra_data_local e;
-	struct zip_data_descriptor *d;
+	uint8_t h[SIZE_LOCAL_FILE_HEADER];
+	uint8_t e[SIZE_EXTRA_DATA_LOCAL];
+	uint8_t *d;
 	struct zip_file_header_link *l;
 	struct archive_string_conv *sconv;
 	int ret, ret2 =3D ARCHIVE_OK;
@@ -374,7 +370,7 @@
 #endif
 		}
 	}
-	d =3D &zip->data_descriptor;
+	d =3D zip->data_descriptor;
 	size =3D archive_entry_size(entry);
 	zip->remaining_data_bytes =3D size;
=20
@@ -411,21 +407,47 @@
=20
 		if (archive_entry_pathname_l(entry, &p, &len, sconv) !=3D 0) {
 			if (errno =3D=3D ENOMEM) {
+				archive_entry_free(l->entry);
+				free(l);
 				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",
+			    "Can't translate Pathname '%s' to %s",
 			    archive_entry_pathname(entry),
 			    archive_string_conversion_charset_name(sconv));
 			ret2 =3D ARCHIVE_WARN;
 		}
 		if (len > 0)
 			archive_entry_set_pathname(l->entry, p);
+
+		/*
+		 * Although there is no character-set regulation for Symlink,
+		 * it is suitable to convert a character-set of Symlinke to
+		 * what those of the Pathname has been converted to.
+		 */
+		if (type =3D=3D AE_IFLNK) {
+			if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
+				if (errno =3D=3D ENOMEM) {
+					archive_entry_free(l->entry);
+					free(l);
+					archive_set_error(&a->archive, ENOMEM,
+					    "Can't allocate memory "
+					    " for Symlink");
+					return (ARCHIVE_FATAL);
+				}
+				/*
+				 * Even if the strng conversion failed,
+				 * we should not report the error since
+				 * thre is no regulation for.
+				 */
+			} else if (len > 0)
+				archive_entry_set_symlink(l->entry, p);
+		}
 	}
-	/* If all character of a filename is ASCII, Reset UTF-8 Name flag. */
+	/* If all characters in a filename are ASCII, Reset UTF-8 Name flag. */
 	if ((l->flags & ZIP_FLAGS_UTF8_NAME) !=3D 0 &&
 	    is_all_ascii(archive_entry_pathname(l->entry)))
 		l->flags &=3D ~ZIP_FLAGS_UTF8_NAME;
@@ -458,13 +480,16 @@
 	 * directory. */
 	l->offset =3D zip->written_bytes;
=20
-	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, 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(l->entry));
+	memset(h, 0, sizeof(h));
+	archive_le32enc(&h[LOCAL_FILE_HEADER_SIGNATURE],
+		ZIP_SIGNATURE_LOCAL_FILE_HEADER);
+	archive_le16enc(&h[LOCAL_FILE_HEADER_VERSION], ZIP_VERSION_EXTRACT);
+	archive_le16enc(&h[LOCAL_FILE_HEADER_FLAGS], l->flags);
+	archive_le16enc(&h[LOCAL_FILE_HEADER_COMPRESSION], l->compression);
+	archive_le32enc(&h[LOCAL_FILE_HEADER_TIMEDATE],
+		dos_time(archive_entry_mtime(entry)));
+	archive_le16enc(&h[LOCAL_FILE_HEADER_FILENAME_LENGTH],
+		(uint16_t)path_length(l->entry));
=20
 	switch (l->compression) {
 	case COMPRESSION_STORE:
@@ -472,12 +497,15 @@
 		 * 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);
+		archive_le32enc(&h[LOCAL_FILE_HEADER_COMPRESSED_SIZE],
+		    (uint32_t)size);
+		archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
+		    (uint32_t)size);
 		break;
 #ifdef HAVE_ZLIB_H
 	case COMPRESSION_DEFLATE:
-		archive_le32enc(&h.uncompressed_size, size);
+		archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
+		    (uint32_t)size);
=20
 		zip->stream.zalloc =3D Z_NULL;
 		zip->stream.zfree =3D Z_NULL;
@@ -495,28 +523,33 @@
 	}
=20
 	/* Formatting extra data. */
-	archive_le16enc(&h.extra_length, sizeof(e));
-	archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
-	archive_le16enc(&e.time_size, sizeof(e.time_flag) +
-	    sizeof(e.mtime) + sizeof(e.atime) + sizeof(e.ctime));
-	e.time_flag[0] =3D 0x07;
-	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(&h[LOCAL_FILE_HEADER_EXTRA_LENGTH], sizeof(e));
+	archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_ID],
+		ZIP_SIGNATURE_EXTRA_TIMESTAMP);
+	archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_SIZE], 1 + 4 * 3);
+	e[EXTRA_DATA_LOCAL_TIME_FLAG] =3D 0x07;
+	archive_le32enc(&e[EXTRA_DATA_LOCAL_MTIME],
+	    (uint32_t)archive_entry_mtime(entry));
+	archive_le32enc(&e[EXTRA_DATA_LOCAL_ATIME],
+	    (uint32_t)archive_entry_atime(entry));
+	archive_le32enc(&e[EXTRA_DATA_LOCAL_CTIME],
+	    (uint32_t)archive_entry_ctime(entry));
=20
-	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 =3D 1;
-	e.unix_uid_size =3D 4;
-	archive_le32enc(&e.unix_uid, archive_entry_uid(entry));
-	e.unix_gid_size =3D 4;
-	archive_le32enc(&e.unix_gid, archive_entry_gid(entry));
+	archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_ID],
+		ZIP_SIGNATURE_EXTRA_NEW_UNIX);
+	archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_SIZE], 1 + (1 + 4) * 2);
+	e[EXTRA_DATA_LOCAL_UNIX_VERSION] =3D 1;
+	e[EXTRA_DATA_LOCAL_UNIX_UID_SIZE] =3D 4;
+	archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_UID],
+		(uint32_t)archive_entry_uid(entry));
+	e[EXTRA_DATA_LOCAL_UNIX_GID_SIZE] =3D 4;
+	archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_GID],
+		(uint32_t)archive_entry_gid(entry));
=20
-	archive_le32enc(&d->uncompressed_size, size);
+	archive_le32enc(&d[DATA_DESCRIPTOR_UNCOMPRESSED_SIZE],
+	    (uint32_t)size);
=20
-	ret =3D __archive_write_output(a, &h, sizeof(h));
+	ret =3D __archive_write_output(a, h, sizeof(h));
 	if (ret !=3D ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
 	zip->written_bytes +=3D sizeof(h);
@@ -526,7 +559,7 @@
 		return (ARCHIVE_FATAL);
 	zip->written_bytes +=3D ret;
=20
-	ret =3D __archive_write_output(a, &e, sizeof(e));
+	ret =3D __archive_write_output(a, e, sizeof(e));
 	if (ret !=3D ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
 	zip->written_bytes +=3D sizeof(e);
@@ -535,11 +568,11 @@
 		const unsigned char *p;
=20
 		p =3D (const unsigned char *)archive_entry_symlink(l->entry);
-		ret =3D __archive_write_output(a, p, size);
+		ret =3D __archive_write_output(a, p, (size_t)size);
 		if (ret !=3D ARCHIVE_OK)
 			return (ARCHIVE_FATAL);
 		zip->written_bytes +=3D size;
-		l->crc32 =3D crc32(l->crc32, p, size);
+		l->crc32 =3D crc32(l->crc32, p, (unsigned)size);
 	}
=20
 	if (ret2 !=3D ARCHIVE_OK)
@@ -606,7 +639,7 @@
 	/* Write the data descripter after file data has been written. */
 	int ret;
 	struct zip *zip =3D a->format_data;
-	struct zip_data_descriptor *d =3D &zip->data_descriptor;
+	uint8_t *d =3D zip->data_descriptor;
 	struct zip_file_header_link *l =3D zip->central_directory_end;
 #if HAVE_ZLIB_H
 	size_t reminder;
@@ -637,12 +670,13 @@
 #endif
 	}
=20
-	archive_le32enc(&d->crc32, l->crc32);
-	archive_le32enc(&d->compressed_size, l->compressed_size);
-	ret =3D __archive_write_output(a, d, sizeof(*d));
+	archive_le32enc(&d[DATA_DESCRIPTOR_CRC32], l->crc32);
+	archive_le32enc(&d[DATA_DESCRIPTOR_COMPRESSED_SIZE],
+		(uint32_t)l->compressed_size);
+	ret =3D __archive_write_output(a, d, SIZE_DATA_DESCRIPTOR);
 	if (ret !=3D ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
-	zip->written_bytes +=3D sizeof(*d);
+	zip->written_bytes +=3D SIZE_DATA_DESCRIPTOR;
 	return (ARCHIVE_OK);
 }
=20
@@ -651,9 +685,9 @@
 {
 	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;
+	uint8_t h[SIZE_FILE_HEADER];
+	uint8_t end[SIZE_CENTRAL_DIRECTORY_END];
+	uint8_t e[SIZE_EXTRA_DATA_CENTRAL];
 	int64_t offset_start, offset_end;
 	int entries;
 	int ret;
@@ -670,10 +704,10 @@
 	 *   - disk_number
 	 *   - attributes_internal
 	 */
-	memset(&h, 0, sizeof(h));
-	archive_le32enc(&h.signature, ZIP_SIGNATURE_FILE_HEADER);
-	archive_le16enc(&h.version_by, ZIP_VERSION_BY);
-	archive_le16enc(&h.version_extract, ZIP_VERSION_EXTRACT);
+	memset(h, 0, sizeof(h));
+	archive_le32enc(&h[FILE_HEADER_SIGNATURE], ZIP_SIGNATURE_FILE_HEADER);
+	archive_le16enc(&h[FILE_HEADER_VERSION_BY], ZIP_VERSION_BY);
+	archive_le16enc(&h[FILE_HEADER_VERSION_EXTRACT], ZIP_VERSION_EXTRACT);
=20
 	entries =3D 0;
 	offset_start =3D zip->written_bytes;
@@ -681,31 +715,34 @@
 	/* Formatting individual header fields per entry and
 	 * writing each entry. */
 	while (l !=3D NULL) {
-		archive_le16enc(&h.flags, l->flags);
-		archive_le16enc(&h.compression, l->compression);
-		archive_le32enc(&h.timedate,
+		archive_le16enc(&h[FILE_HEADER_FLAGS], l->flags);
+		archive_le16enc(&h[FILE_HEADER_COMPRESSION], l->compression);
+		archive_le32enc(&h[FILE_HEADER_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,
+		archive_le32enc(&h[FILE_HEADER_CRC32], l->crc32);
+		archive_le32enc(&h[FILE_HEADER_COMPRESSED_SIZE],
+			(uint32_t)l->compressed_size);
+		archive_le32enc(&h[FILE_HEADER_UNCOMPRESSED_SIZE],
+			(uint32_t)archive_entry_size(l->entry));
+		archive_le16enc(&h[FILE_HEADER_FILENAME_LENGTH],
 			(uint16_t)path_length(l->entry));
-		archive_le16enc(&h.extra_length, sizeof(e));
-		archive_le16enc(&h.attributes_external[2],
+		archive_le16enc(&h[FILE_HEADER_EXTRA_LENGTH], sizeof(e));
+		archive_le16enc(&h[FILE_HEADER_ATTRIBUTES_EXTERNAL+2],
 			archive_entry_mode(l->entry));
-		archive_le32enc(&h.offset, l->offset);
+		archive_le32enc(&h[FILE_HEADER_OFFSET], (uint32_t)l->offset);
=20
 		/* Formatting extra data. */
-		archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
-		archive_le16enc(&e.time_size,
-			sizeof(e.mtime) + sizeof(e.time_flag));
-		e.time_flag[0] =3D 0x07;
-		archive_le32enc(&e.mtime, archive_entry_mtime(l->entry));
-		archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_NEW_UNIX);
-		archive_le16enc(&e.unix_size, 0x0000);
+		archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_ID],
+			ZIP_SIGNATURE_EXTRA_TIMESTAMP);
+		archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_SIZE], 1 + 4);
+		e[EXTRA_DATA_CENTRAL_TIME_FLAG] =3D 0x07;
+		archive_le32enc(&e[EXTRA_DATA_CENTRAL_MTIME],
+			(uint32_t)archive_entry_mtime(l->entry));
+		archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_ID],
+			ZIP_SIGNATURE_EXTRA_NEW_UNIX);
+		archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_SIZE], 0x0000);
=20
-		ret =3D __archive_write_output(a, &h, sizeof(h));
+		ret =3D __archive_write_output(a, h, sizeof(h));
 		if (ret !=3D ARCHIVE_OK)
 			return (ARCHIVE_FATAL);
 		zip->written_bytes +=3D sizeof(h);
@@ -715,7 +752,7 @@
 			return (ARCHIVE_FATAL);
 		zip->written_bytes +=3D ret;
=20
-		ret =3D __archive_write_output(a, &e, sizeof(e));
+		ret =3D __archive_write_output(a, e, sizeof(e));
 		if (ret !=3D ARCHIVE_OK)
 			return (ARCHIVE_FATAL);
 		zip->written_bytes +=3D sizeof(e);
@@ -726,15 +763,18 @@
 	offset_end =3D zip->written_bytes;
=20
 	/* Formatting end of central directory. */
-	memset(&end, 0, sizeof(end));
-	archive_le32enc(&end.signature, ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
-	archive_le16enc(&end.entries_disk, entries);
-	archive_le16enc(&end.entries, entries);
-	archive_le32enc(&end.size, offset_end - offset_start);
-	archive_le32enc(&end.offset, offset_start);
+	memset(end, 0, sizeof(end));
+	archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIGNATURE],
+		ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
+	archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES_DISK], entries);
+	archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES], entries);
+	archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIZE],
+		(uint32_t)(offset_end - offset_start));
+	archive_le32enc(&end[CENTRAL_DIRECTORY_END_OFFSET],
+		(uint32_t)offset_start);
=20
 	/* Writing end of central directory. */
-	ret =3D __archive_write_output(a, &end, sizeof(end));
+	ret =3D __archive_write_output(a, end, sizeof(end));
 	if (ret !=3D ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
 	zip->written_bytes +=3D sizeof(end);
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/arc=
hive_write_set_options.3
--- a/head/contrib/libarchive/libarchive/archive_write_set_options.3	Mon Ju=
l 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/archive_write_set_options.3	Fri Au=
g 10 14:19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" 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 $
+.\" $FreeBSD$
 .\"
-.Dd Feb 27, 2010
+.Dd February 2, 2012
 .Dt ARCHIVE_WRITE_OPTIONS 3
 .Os
 .Sh NAME
@@ -33,8 +33,8 @@
 .Nm archive_write_set_option ,
 .Nm archive_write_set_options
 .Nd functions controlling options for reading archives
-.Sh SYNOPSIS
-.\"
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
 .Sh SYNOPSIS
 .Ft int
 .Fo archive_write_set_filter_option
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/cpi=
o.5
--- a/head/contrib/libarchive/libarchive/cpio.5	Mon Jul 30 11:44:18 2012 +0=
300
+++ b/head/contrib/libarchive/libarchive/cpio.5	Fri Aug 10 14:19:25 2012 +0=
300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/cpio.5 228773 2011-12-21 =
15:18:52Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/cpio.5 238856 2012-07-28 =
06:38:44Z mm $
 .\"
-.Dd October 5, 2007
+.Dd December 23, 2011
 .Dt CPIO 5
 .Os
 .Sh NAME
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/lib=
archive-formats.5
--- a/head/contrib/libarchive/libarchive/libarchive-formats.5	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/libarchive-formats.5	Fri Aug 10 14=
:19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/libarchive-formats.5 2321=
53 2012-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/libarchive-formats.5 2388=
56 2012-07-28 06:38:44Z mm $
 .\"
-.Dd December 27, 2009
+.Dd March 18, 2012
 .Dt LIBARCHIVE-FORMATS 5
 .Os
 .Sh NAME
@@ -51,11 +51,11 @@
 The
 .Xr libarchive 3
 library can read most tar archives.
-However, it only writes POSIX-standard
+It can write POSIX-standard
 .Dq ustar
 and
 .Dq pax interchange
-formats.
+formats and a subset of the legacy GNU tar format.
 .Pp
 All tar formats store each entry in one or more 512-byte records.
 The first record is used for file metadata, including filename,
@@ -70,13 +70,18 @@
 .It Cm gnutar
 The
 .Xr libarchive 3
-library can read GNU-format tar archives.
+library can read most GNU-format tar archives.
 It currently supports the most popular GNU extensions, including
 modern long filename and linkname support, as well as atime and ctime data.
 The libarchive library does not support multi-volume
 archives, nor the old GNU long filename format.
 It can read GNU sparse file entries, including the new POSIX-based
-formats, but cannot write GNU sparse file entries.
+formats.
+.Pp
+The
+.Xr libarchive 3
+library can write GNU tar format, including long filename
+and linkname support, as well as atime and ctime data.
 .It Cm pax
 The
 .Xr libarchive 3
@@ -98,6 +103,14 @@
 The libarchive library can read most of the SCHILY keys
 and most of the GNU keys introduced by GNU tar.
 It silently ignores any keywords that it does not understand.
+.Pp
+The pax interchange format converts filenames to Unicode
+and stores them using the UTF-8 encoding.
+Prior to libarchive 3.0, libarchive erroneously assumed
+that the system wide-character routines natively supported
+Unicode.
+This caused it to mis-handle non-ASCII filenames on systems
+that did not satisfy this assumption.
 .It Cm restricted pax
 The libarchive library can also write pax archives in which it
 attempts to suppress the extended attributes entry whenever
@@ -135,6 +148,8 @@
 Archive entries are limited to 8 gigabytes in size.
 .El
 Note that the pax interchange format has none of these restrictions.
+The ustar format is old and widely supported.
+It is recommended when compatibility is the primary concern.
 .El
 .Pp
 The libarchive library also reads a variety of commonly-used extensions to
@@ -268,19 +283,68 @@
 used and the Rockridge extensions will be ignored.
 In particular, this can create problems with hardlinks and symlinks,
 which are supported by Rockridge but not by Joliet.
+.Pp
+Libarchive reads ISO9660 images using a streaming strategy.
+This allows it to read compressed images directly
+(decompressing on the fly) and allows it to read images
+directly from network sockets, pipes, and other non-seekable
+data sources.
+This strategy works well for optimized ISO9660 images created
+by many popular programs.
+Such programs collect all directory information at the beginning
+of the ISO9660 image so it can be read from a physical disk
+with a minimum of seeking.
+However, not all ISO9660 images can be read in this fashion.
+.Pp
+Libarchive can also write ISO9660 images.
+Such images are fully optimized with the directory information
+preceding all file data.
+This is done by storing all file data to a temporary file
+while collecting directory information in memory.
+When the image is finished, libarchive writes out the
+directory structure followed by the file data.
+The location used for the temporary file can be changed
+by the usual environment variables.
 .Ss Zip format
 Libarchive can read and write zip format archives that have
 uncompressed entries and entries compressed with the
 .Dq deflate
 algorithm.
-Older zip compression algorithms are not supported.
-It can extract jar archives, archives that use Zip64 extensions and many
+Other zip compression algorithms are not supported.
+It can extract jar archives, archives that use Zip64 extensions and
 self-extracting zip archives.
-Libarchive reads Zip archives as they are being streamed,
-which allows it to read archives of arbitrary size.
-It currently does not use the central directory; this
-limits libarchive's ability to support some self-extracting
-archives and ones that have been modified in certain ways.
+Libarchive can use either of two different strategies for
+reading Zip archives:
+a streaming strategy which is fast and can handle extremely
+large archives, and a seeking strategy which can correctly
+process self-extracting Zip archives and archives with
+deleted members or other in-place modifications.
+.Pp
+The streaming reader processes Zip archives as they are read.
+It can read archives of arbitrary size from tape or
+network sockets, and can decode Zip archives that have
+been separately compressed or encoded.
+However, self-extracting Zip archives and archives with
+certain types of modifications cannot be correctly
+handled.
+Such archives require that the reader first process the
+Central Directory, which is ordinarily located
+at the end of a Zip archive and is thus inaccessible
+to the streaming reader.
+If the program using libarchive has enabled seek support, then
+libarchive will use this to processes the central directory first.
+.Pp
+In particular, the seeking reader must be used to
+correctly handle self-extracting archives.
+Such archives consist of a program followed by a regular
+Zip archive.
+The streaming reader cannot parse the initial program
+portion, but the seeking reader starts by reading the
+Central Directory from the end of the archive.
+Similarly, Zip archives that have been modified in-place
+can have deleted entries or other garbage data that
+can only be accurately detected by first reading the
+Central Directory.
 .Ss Archive (library) file format
 The Unix archive format (commonly created by the
 .Xr ar 1
@@ -342,12 +406,18 @@
 If it cannot locate and open the file on disk, libarchive
 will return an error for any attempt to read the entry
 body.
+.Ss LHA
+XXX Information about libarchive's LHA support XXX
+.Ss CAB
+XXX Information about libarchive's CAB support XXX
+.Ss XAR
+XXX Information about libarchive's XAR support XXX
 .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.
+Libarchive has limited support for reading RAR format archives.
+Currently, libarchive can read RARv3 format archives
+which have been either created uncompressed, or compressed using
+any of the compression methods supported by the RARv3 format.
+Libarchive can also read self-extracting RAR archives.
 .Sh SEE ALSO
 .Xr ar 1 ,
 .Xr cpio 1 ,
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/lib=
archive.3
--- a/head/contrib/libarchive/libarchive/libarchive.3	Mon Jul 30 11:44:18 2=
012 +0300
+++ b/head/contrib/libarchive/libarchive/libarchive.3	Fri Aug 10 14:19:25 2=
012 +0300
@@ -22,16 +22,14 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/libarchive.3 232153 2012-=
02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/libarchive.3 238856 2012-=
07-28 06:38:44Z mm $
 .\"
-.Dd February 6, 2010
+.Dd March 18, 2012
 .Dt LIBARCHIVE 3
 .Os
 .Sh NAME
 .Nm libarchive
 .Nd functions for reading and writing streaming archives
-.Sh LIBRARY
-.Lb libarchive
 .Sh OVERVIEW
 The
 .Nm
@@ -66,15 +64,33 @@
 .It
 ISO9660 CD images (including RockRidge and Joliet extensions),
 .It
-Zip archives.
+Zip archives,
+.It
+ar archives (including GNU/SysV and BSD extensions),
+.It
+Microsoft CAB archives,
+.It
+LHA archives,
+.It
+mtree file tree descriptions,
+.It
+RAR archives,
+.It
+XAR archives.
 .El
 The library automatically detects archives compressed with
 .Xr gzip 1 ,
 .Xr bzip2 1 ,
 .Xr xz 1 ,
+.Xr lzip 1 ,
 or
 .Xr compress 1
 and decompresses them transparently.
+It can similarly detect and decode archives processed with
+.Xr uuencode 1
+or which have an
+.Xr rpm 1
+header.
 .Pp
 When writing an archive, you can specify the compression
 to be used and the format to use.
@@ -93,7 +109,17 @@
 .It
 Zip archive,
 .It
-two different variants of shar archives.
+two different variants of shar archives,
+.It
+ISO9660 CD images,
+.It
+7-Zip archives,
+.It
+ar archives,
+.It
+mtree file tree descriptions,
+.It
+XAR archives.
 .El
 Pax interchange format is an extension of the tar archive format that
 eliminates essentially all of the limitations of historic tar formats
@@ -145,9 +171,21 @@
 .Sh READING ENTRIES FROM DISK
 The
 .Xr archive_read_disk 3
-provides some support for populating
+supports for populating
 .Xr archive_entry 3
 objects from information in the filesystem.
+This includes the information accessible from the
+.Xr stat 2
+system call as well as ACLs, extended attributes,
+and other metadata.
+The
+.Xr archive_read_disk 3
+API also supports iterating over directory trees,
+which allows directories of files to be read using
+an API compatible with
+the
+.Xr archive_read 3
+API.
 .Sh DESCRIPTION
 Detailed descriptions of each function are provided by the
 corresponding manual pages.
@@ -227,7 +265,7 @@
 .An -nosplit
 The
 .Nm libarchive
-library was written by
+library was originally written by
 .An Tim Kientzle Aq kientzle at acm.org .
 .Sh BUGS
 Some archive formats support information that is not supported by
@@ -244,13 +282,8 @@
 For example, cpio formats do not support nanosecond timestamps;
 old tar formats do not support large device numbers.
 .Pp
-The
-.Xr archive_read_disk 3
-API should support iterating over filesystems;
-that would make it possible to share code among
-disk-to-archive, archive-to-archive, archive-to-disk,
-and disk-to-disk operations.
-Currently, it only supports reading the
-information for a single file.
-(Which is still quite useful, as it hides a lot
-of system-specific details.)
+The ISO9660 reader cannot yet read all ISO9660 images;
+it should learn how to seek.
+.Pp
+The AR writer requires the client program to use
+two passes, unlike all other libarchive writers.
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/lib=
archive_changes.3
--- a/head/contrib/libarchive/libarchive/libarchive_changes.3	Mon Jul 30 11=
:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/libarchive_changes.3	Fri Aug 10 14=
:19:25 2012 +0300
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 27, 2011
+.Dd December 23, 2011
 .Dt LIBARCHIVE_CHANGES 3
 .Os
 .Sh NAME
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/lib=
archive_internals.3
--- a/head/contrib/libarchive/libarchive/libarchive_internals.3	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/libarchive_internals.3	Fri Aug 10 =
14:19:25 2012 +0300
@@ -22,10 +22,10 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/libarchive_internals.3 23=
2153 2012-02-25 10:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/libarchive_internals.3 23=
8856 2012-07-28 06:38:44Z mm $
 .\"
-.Dd April 16, 2007
-.Dt LIBARCHIVE 3
+.Dd January 26, 2011
+.Dt LIBARCHIVE_INTERNALS 3
 .Os
 .Sh NAME
 .Nm libarchive_internals
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tar=
.5
--- a/head/contrib/libarchive/libarchive/tar.5	Mon Jul 30 11:44:18 2012 +03=
00
+++ b/head/contrib/libarchive/libarchive/tar.5	Fri Aug 10 14:19:25 2012 +03=
00
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/libarchive/tar.5 232153 2012-02-25 1=
0:58:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/libarchive/tar.5 238856 2012-07-28 0=
6:38:44Z mm $
 .\"
-.Dd December 27, 2009
+.Dd December 23, 2011
 .Dt TAR 5
 .Os
 .Sh NAME
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/main.c
--- a/head/contrib/libarchive/libarchive/test/main.c	Mon Jul 30 11:44:18 20=
12 +0300
+++ b/head/contrib/libarchive/libarchive/test/main.c	Fri Aug 10 14:19:25 20=
12 +0300
@@ -24,6 +24,9 @@
  */
=20
 #include "test.h"
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
@@ -31,6 +34,16 @@
 #ifdef HAVE_ICONV_H
 #include <iconv.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
 #include <limits.h>
 #include <locale.h>
 #ifdef HAVE_SIGNAL_H
@@ -46,7 +59,7 @@
  * TODO: Move this into a separate configuration header, have all test
  * suites share one copy of this file.
  */
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/main.c 232153 =
2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/main.c 238856 =
2012-07-28 06:38:44Z mm $");
 #define KNOWNREF	"test_compat_gtar_1.tar.uu"
 #define	ENVBASE "LIBARCHIVE" /* Prefix for environment variables. */
 #undef	PROGRAM              /* Testing a library, not a program. */
@@ -114,7 +127,14 @@
 #endif
=20
 #if defined(_WIN32) && !defined(__CYGWIN__)
-void *GetFunctionKernel32(const char *name)
+static void	*GetFunctionKernel32(const char *);
+static int	 my_CreateSymbolicLinkA(const char *, const char *, int);
+static int	 my_CreateHardLinkA(const char *, const char *);
+static int	 my_GetFileInformationByName(const char *,
+		     BY_HANDLE_FILE_INFORMATION *);
+
+static void *
+GetFunctionKernel32(const char *name)
 {
 	static HINSTANCE lib;
 	static int set;
@@ -153,7 +173,7 @@
 	return f =3D=3D NULL ? 0 : (*f)(linkname, target, NULL);
 }
=20
-int
+static int
 my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *=
bhfi)
 {
 	HANDLE h;
@@ -1505,7 +1525,7 @@
 /* Create a file with the specified contents and report any failures. */
 int
 assertion_make_file(const char *file, int line,
-    const char *path, int mode, const char *contents)
+    const char *path, int mode, int csize, const void *contents)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
 	/* TODO: Rework this to set file mode as well. */
@@ -1519,8 +1539,13 @@
 		return (0);
 	}
 	if (contents !=3D NULL) {
-		if (strlen(contents)
-		    !=3D fwrite(contents, 1, strlen(contents), f)) {
+		size_t wsize;
+
+		if (csize < 0)
+			wsize =3D strlen(contents);
+		else
+			wsize =3D (size_t)csize;
+		if (wsize !=3D fwrite(contents, 1, wsize, f)) {
 			fclose(f);
 			failure_start(file, line,
 			    "Could not write file %s", path);
@@ -1540,10 +1565,16 @@
 		return (0);
 	}
 	if (contents !=3D NULL) {
-		if ((ssize_t)strlen(contents)
-		    !=3D write(fd, contents, strlen(contents))) {
+		ssize_t wsize;
+
+		if (csize < 0)
+			wsize =3D (ssize_t)strlen(contents);
+		else
+			wsize =3D (ssize_t)csize;
+		if (wsize !=3D write(fd, contents, wsize)) {
 			close(fd);
-			failure_start(file, line, "Could not write to %s", path);
+			failure_start(file, line,
+			    "Could not write to %s", path);
 			failure_finish(NULL);
 			return (0);
 		}
@@ -1714,6 +1745,52 @@
 #endif /* defined(_WIN32) && !defined(__CYGWIN__) */
 }
=20
+/* Set nodump, report failures. */
+int
+assertion_nodump(const char *file, int line, const char *pathname)
+{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+	int r;
+
+	assertion_count(file, line);
+	r =3D chflags(pathname, UF_NODUMP);
+	if (r < 0) {
+		failure_start(file, line, "Can't set nodump %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS=
)\
+	 && defined(EXT2_NODUMP_FL)
+	int fd, r, flags;
+
+	assertion_count(file, line);
+	fd =3D open(pathname, O_RDONLY | O_NONBLOCK);
+	if (fd < 0) {
+		failure_start(file, line, "Can't open %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0) {
+		failure_start(file, line, "Can't get flags %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	flags |=3D EXT2_NODUMP_FL;
+	r =3D ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+	if (r < 0) {
+		failure_start(file, line, "Can't set nodump %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	close(fd);
+#else
+	(void)pathname; /* UNUSED */
+	assertion_count(file, line);
+#endif
+	return (1);
+}
+
 /*
  *
  *  UTILITIES for use by tests.
@@ -1742,7 +1819,7 @@
 		return (value);
=20
 	++tested;
-	assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+	assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
 	/* Note: Cygwin has its own symlink() emulation that does not
 	 * use the Win32 CreateSymbolicLink() function. */
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1792,6 +1869,70 @@
 }
=20
 /*
+ * Can this filesystem handle nodump flags.
+ */
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+
+int
+canNodump(void)
+{
+	const char *path =3D "cannodumptest";
+	struct stat sb;
+
+	assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
+	if (chflags(path, UF_NODUMP) < 0)
+		return (0);
+	if (stat(path, &sb) < 0)
+		return (0);
+	if (sb.st_flags & UF_NODUMP)
+		return (1);
+	return (0);
+}
+
+#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS=
)\
+	 && defined(EXT2_NODUMP_FL)
+
+int
+canNodump(void)
+{
+	const char *path =3D "cannodumptest";
+	int fd, r, flags;
+
+	assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
+	fd =3D open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return (0);
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	flags |=3D EXT2_NODUMP_FL;
+	r =3D ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	close(fd);
+	fd =3D open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return (0);
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	close(fd);
+	if (flags & EXT2_NODUMP_FL)
+		return (1);
+	return (0);
+}
+
+#else
+
+int
+canNodump()
+{
+	return (0);
+}
+
+#endif
+
+/*
  * Sleep as needed; useful for verifying disk timestamp changes by
  * ensuring that the wall-clock time has actually changed before we
  * go back to re-read something from disk.
@@ -2234,17 +2375,77 @@
 	return strdup(buff);
 }
=20
+static int
+get_test_set(int *test_set, int limit, const char *test)
+{
+	int start, end;
+	int idx =3D 0;
+
+	if (test =3D=3D NULL) {
+		/* Default: Run all tests. */
+		for (;idx < limit; idx++)
+			test_set[idx] =3D idx;
+		return (limit);
+	}
+	if (*test >=3D '0' && *test <=3D '9') {
+		const char *vp =3D test;
+		start =3D 0;
+		while (*vp >=3D '0' && *vp <=3D '9') {
+			start *=3D 10;
+			start +=3D *vp - '0';
+			++vp;
+		}
+		if (*vp =3D=3D '\0') {
+			end =3D start;
+		} else if (*vp =3D=3D '-') {
+			++vp;
+			if (*vp =3D=3D '\0') {
+				end =3D limit - 1;
+			} else {
+				end =3D 0;
+				while (*vp >=3D '0' && *vp <=3D '9') {
+					end *=3D 10;
+					end +=3D *vp - '0';
+					++vp;
+				}
+			}
+		} else
+			return (-1);
+		if (start < 0 || end >=3D limit || start > end)
+			return (-1);
+		while (start <=3D end)
+			test_set[idx++] =3D start++;
+	} else {
+		size_t len =3D strlen(test);
+		for (start =3D 0; start < limit; ++start) {
+			const char *name =3D tests[start].name;
+			const char *p;
+
+			while ((p =3D strchr(name, test[0])) !=3D NULL) {
+				if (strncmp(p, test, len) =3D=3D 0) {
+					test_set[idx++] =3D start;
+					break;
+				} else
+					name =3D p + 1;
+			}
+
+		}
+	}
+	return ((idx =3D=3D 0)?-1:idx);
+}
+
 int
 main(int argc, char **argv)
 {
 	static const int limit =3D sizeof(tests) / sizeof(tests[0]);
-	int i =3D 0, j =3D 0, start, end, tests_run =3D 0, tests_failed =3D 0, op=
tion;
+	int test_set[sizeof(tests) / sizeof(tests[0])];
+	int i =3D 0, j =3D 0, tests_run =3D 0, tests_failed =3D 0, option;
 	time_t now;
 	char *refdir_alloc =3D NULL;
 	const char *progname;
 	char **saved_argv;
 	const char *tmp, *option_arg, *p;
-	char tmpdir[256], *pwd, *testprogdir, *tmp2 =3D NULL;
+	char tmpdir[256], *pwd, *testprogdir, *tmp2 =3D NULL, *vlevel =3D NULL;
 	char tmpdir_timestamp[256];
=20
 	(void)argc; /* UNUSED */
@@ -2330,6 +2531,19 @@
 	if (getenv(ENVBASE "_DEBUG") !=3D NULL)
 		dump_on_failure =3D 1;
=20
+	/* Allow -v to be controlled through the environment. */
+	if (getenv("_VERBOSITY_LEVEL") !=3D NULL)
+	{
+		vlevel =3D getenv("_VERBOSITY_LEVEL");
+		verbosity =3D atoi(vlevel);
+		if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL)
+		{
+			/* Unsupported verbosity levels are silently ignored */
+			vlevel =3D NULL;
+			verbosity =3D VERBOSITY_PASSFAIL;
+		}
+	}
+
 	/* Get the directory holding test files from environment. */
 	refdir =3D getenv(ENVBASE "_TEST_FILES");
=20
@@ -2377,7 +2591,8 @@
 #endif
 				break;
 			case 'q':
-				verbosity--;
+				if (!vlevel)
+					verbosity--;
 				break;
 			case 'r':
 				refdir =3D option_arg;
@@ -2386,7 +2601,8 @@
 				until_failure++;
 				break;
 			case 'v':
-				verbosity++;
+				if (!vlevel)
+					verbosity++;
 				break;
 			default:
 				fprintf(stderr, "Unrecognized option '%c'\n",
@@ -2499,78 +2715,27 @@
 	saved_argv =3D argv;
 	do {
 		argv =3D saved_argv;
-		if (*argv =3D=3D NULL) {
-			/* Default: Run all tests. */
-			for (i =3D 0; i < limit; i++) {
+		do {
+			int test_num;
+
+			test_num =3D get_test_set(test_set, limit, *argv);
+			if (test_num < 0) {
+				printf("*** INVALID Test %s\n", *argv);
+				free(refdir_alloc);
+				usage(progname);
+				return (1);
+			}
+			for (i =3D 0; i < test_num; i++) {
 				tests_run++;
-				if (test_run(i, tmpdir)) {
+				if (test_run(test_set[i], tmpdir)) {
 					tests_failed++;
 					if (until_failure)
 						goto finish;
 				}
 			}
-		} else {
-			while (*(argv) !=3D NULL) {
-				if (**argv >=3D '0' && **argv <=3D '9') {
-					char *vp =3D *argv;
-					start =3D 0;
-					while (*vp >=3D '0' && *vp <=3D '9') {
-						start *=3D 10;
-						start +=3D *vp - '0';
-						++vp;
-					}
-					if (*vp =3D=3D '\0') {
-						end =3D start;
-					} else if (*vp =3D=3D '-') {
-						++vp;
-						if (*vp =3D=3D '\0') {
-							end =3D limit - 1;
-						} else {
-							end =3D 0;
-							while (*vp >=3D '0' && *vp <=3D '9') {
-								end *=3D 10;
-								end +=3D *vp - '0';
-								++vp;
-							}
-						}
-					} else {
-						printf("*** INVALID Test %s\n", *argv);
-						free(refdir_alloc);
-						usage(progname);
-						return (1);
-					}
-					if (start < 0 || end >=3D limit || start > end) {
-						printf("*** INVALID Test %s\n", *argv);
-						free(refdir_alloc);
-						usage(progname);
-						return (1);
-					}
-				} else {
-					for (start =3D 0; start < limit; ++start) {
-						if (strcmp(*argv, tests[start].name) =3D=3D 0)
-							break;
-					}
-					end =3D start;
-					if (start >=3D limit) {
-						printf("*** INVALID Test ``%s''\n",
-						    *argv);
-						free(refdir_alloc);
-						usage(progname);
-						/* usage() never returns */
-					}
-				}
-				while (start <=3D end) {
-					tests_run++;
-					if (test_run(start, tmpdir)) {
-						tests_failed++;
-						if (until_failure)
-							goto finish;
-					}
-					++start;
-				}
+			if (*argv !=3D NULL)
 				argv++;
-			}
-		}
+		} while (*argv !=3D NULL);
 	} while (until_failure);
=20
 finish:
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/read_open_memory.c
--- a/head/contrib/libarchive/libarchive/test/read_open_memory.c	Mon Jul 30=
 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/read_open_memory.c	Fri Aug 10=
 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "test.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/read_open_memo=
ry.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/read_open_memo=
ry.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #include <errno.h>
 #include <stdlib.h>
@@ -68,7 +68,7 @@
  * that internals work correctly with just the minimal entry points.
  */
 int
-read_open_memory2(struct archive *a, void *buff, size_t size, size_t read_=
size)
+read_open_memory_minimal(struct archive *a, void *buff, size_t size, size_=
t read_size)
 {
 	return read_open_memory_internal(a, buff, size, read_size, 1);
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test.h
--- a/head/contrib/libarchive/libarchive/test/test.h	Mon Jul 30 11:44:18 20=
12 +0300
+++ b/head/contrib/libarchive/libarchive/test/test.h	Fri Aug 10 14:19:25 20=
12 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive/test/test.h 232153 2012-02=
-25 10:58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive/test/test.h 238856 2012-07=
-28 06:38:44Z mm $
  */
=20
 /* Every test program should #include "test.h" as the first thing. */
@@ -194,11 +194,15 @@
 #define assertMakeDir(dirname, mode)	\
   assertion_make_dir(__FILE__, __LINE__, dirname, mode)
 #define assertMakeFile(path, mode, contents) \
-  assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+  assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+  assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
 #define assertMakeHardlink(newfile, oldfile)	\
   assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
 #define assertMakeSymlink(newfile, linkto)	\
   assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertNodump(path)	\
+  assertion_nodump(__FILE__, __LINE__, path)
 #define assertUmask(mask)	\
   assertion_umask(__FILE__, __LINE__, mask)
 #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec)	\
@@ -241,9 +245,10 @@
 int assertion_is_reg(const char *, int, const char *, int);
 int assertion_is_symlink(const char *, int, const char *, const char *);
 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_file(const char *, int, const char *, int, int, const v=
oid *);
 int assertion_make_hardlink(const char *, int, const char *newpath, const =
char *);
 int assertion_make_symlink(const char *, int, const char *newpath, const c=
har *);
+int assertion_nodump(const char *, int, const char *);
 int assertion_non_empty_file(const char *, int, const char *);
 int assertion_text_file_contents(const char *, int, const char *buff, cons=
t char *f);
 int assertion_umask(const char *, int, int);
@@ -267,6 +272,9 @@
 /* Return true if this platform can run the "gunzip" program. */
 int canGunzip(void);
=20
+/* Return true if this filesystem can handle nodump flags. */
+int canNodump(void);
+
 /* Return true if the file has large i-node number(>0xffffffff). */
 int is_LargeInode(const char *);
=20
@@ -289,8 +297,8 @@
=20
 /* Special customized read-from-memory interface. */
 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);
+/* _minimal version exercises a slightly different set of libarchive APIs.=
 */
+int read_open_memory_minimal(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);
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_acl_freebsd_nfs4.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c	Fri A=
ug 10 14:19:25 2012 +0300
@@ -0,0 +1,1094 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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$");
+
+#if defined(__FreeBSD__) && __FreeBSD__ >=3D 8
+#define _ACL_PRIVATE
+#include <sys/acl.h>
+
+struct myacl_t {
+	int type;
+	int permset;
+	int tag;
+	int qual; /* GID or UID of user/group, depending on tag. */
+	const char *name; /* Name of user/group, depending on tag. */
+};
+
+static struct myacl_t acls_reg[] =3D {
+	/* For this test, we need the file owner to be able to read and write the=
 ACL. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTR=
Y_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_RE=
AD_ATTRIBUTES,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
+
+	/* An entry for each type. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_USER, 109, "user109" },
+
+	/* 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_WRITE_DATA,
+	  ARCHIVE_ENTRY_ACL_USER, 115, "user115" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA,
+	  ARCHIVE_ENTRY_ACL_USER, 117, "user117" },
+	{ 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_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 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, "" }
+};
+
+
+static struct myacl_t acls_dir[] =3D {
+	/* For this test, we need to be able to read and write the ACL. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
+
+	/* An entry for each type. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 101, "user101" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 102, "user102" },
+
+	/* An entry for each permission. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 201, "user201" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE,
+	  ARCHIVE_ENTRY_ACL_USER, 202, "user202" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 203, "user203" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
+	  ARCHIVE_ENTRY_ACL_USER, 204, "user204" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
+	  ARCHIVE_ENTRY_ACL_USER, 205, "user205" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD,
+	  ARCHIVE_ENTRY_ACL_USER, 206, "user206" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
+	  ARCHIVE_ENTRY_ACL_USER, 207, "user207" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
+	  ARCHIVE_ENTRY_ACL_USER, 208, "user208" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
+	  ARCHIVE_ENTRY_ACL_USER, 209, "user209" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+	  ARCHIVE_ENTRY_ACL_USER, 210, "user210" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
+	  ARCHIVE_ENTRY_ACL_USER, 211, "user211" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
+	  ARCHIVE_ENTRY_ACL_USER, 212, "user212" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_USER, 213, "user213" },
+
+	/* 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, 301, "user301" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
+	  ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
+#if 0
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHE=
RIT,
+	  ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
+	  ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
+#endif
+
+#if 0
+	/* FreeBSD does not support audit entries. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
+	  ARCHIVE_ENTRY_ACL_USER, 401, "user401" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
+	  ARCHIVE_ENTRY_ACL_USER, 402, "user402" },
+#endif
+
+	/* One entry for each qualifier. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
+};
+
+static void
+set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int en=
d)
+{
+	int i;
+
+	archive_entry_acl_clear(ae);
+	if (start > 0) {
+		assertEqualInt(ARCHIVE_OK,
+			archive_entry_acl_add_entry(ae,
+			    acls[0].type, acls[0].permset, acls[0].tag,
+			    acls[0].qual, acls[0].name));
+	}
+	for (i =3D start; i < end; i++) {
+		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_permset_to_bitmap(acl_permset_t opaque_ps)
+{
+	static struct { int machine; int portable; } perms[] =3D {
+		{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
+		{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
+		{ACL_READ, ARCHIVE_ENTRY_ACL_READ},
+		{ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
+		{ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
+		{ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
+		{ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
+		{ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
+		{ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
+		{ACL_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
+		{ACL_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
+		{ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
+		{ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
+		{ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
+		{ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
+		{ACL_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
+		{ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
+		{ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
+		{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
+	};
+	int i, permset =3D 0;
+
+	for (i =3D 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
+		if (acl_get_perm_np(opaque_ps, perms[i].machine))
+			permset |=3D perms[i].portable;
+	return permset;
+}
+
+static int
+acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
+{
+	static struct { int machine; int portable; } flags[] =3D {
+		{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
+		{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
+		{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_IN=
HERIT},
+		{ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
+	};
+	int i, flagset =3D 0;
+
+	for (i =3D 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
+		if (acl_get_flag_np(opaque_fs, flags[i].machine))
+			flagset |=3D flags[i].portable;
+	return flagset;
+}
+
+static int
+acl_match(acl_entry_t aclent, struct myacl_t *myacl)
+{
+	gid_t g, *gp;
+	uid_t u, *up;
+	acl_tag_t tag_type;
+	acl_permset_t opaque_ps;
+	acl_flagset_t opaque_fs;
+	int perms;
+
+	acl_get_tag_type(aclent, &tag_type);
+
+	/* translate the silly opaque permset to a bitmap */
+	acl_get_permset(aclent, &opaque_ps);
+	acl_get_flagset_np(aclent, &opaque_fs);
+	perms =3D acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque=
_fs);
+	if (perms !=3D myacl->permset)
+		return (0);
+
+	switch (tag_type) {
+	case ACL_USER_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
+		break;
+	case ACL_USER:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER)
+			return (0);
+		up =3D acl_get_qualifier(aclent);
+		u =3D *up;
+		acl_free(up);
+		if ((uid_t)myacl->qual !=3D u)
+			return (0);
+		break;
+	case ACL_GROUP_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
+		break;
+	case ACL_GROUP:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP)
+			return (0);
+		gp =3D acl_get_qualifier(aclent);
+		g =3D *gp;
+		acl_free(gp);
+		if ((gid_t)myacl->qual !=3D g)
+			return (0);
+		break;
+	case ACL_MASK:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_MASK) return (0);
+		break;
+	case ACL_EVERYONE:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
+		break;
+	}
+	return (1);
+}
+
+static void
+compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int =
start, int end)
+{
+	int *marker;
+	int entry_id =3D ACL_FIRST_ENTRY;
+	int matched;
+	int i, n;
+	acl_entry_t acl_entry;
+
+	n =3D end - start;
+	marker =3D malloc(sizeof(marker[0]) * (n + 1));
+	for (i =3D 0; i < n; i++)
+		marker[i] =3D i + start;
+	/* Always include the first ACE. */
+	if (start > 0) {
+	  marker[n] =3D 0;
+	  ++n;
+	}
+
+	/*
+	 * Iterate over acls in system acl object, try to match each
+	 * one with an item in the myacls array.
+	 */
+	while (1 =3D=3D acl_get_entry(acl, entry_id, &acl_entry)) {
+		/* After the first time... */
+		entry_id =3D ACL_NEXT_ENTRY;
+
+		/* Search for a matching entry (tag and qualifier) */
+		for (i =3D 0, matched =3D 0; i < n && !matched; i++) {
+			if (acl_match(acl_entry, &myacls[marker[i]])) {
+				/* We found a match; remove it. */
+				marker[i] =3D marker[n - 1];
+				n--;
+				matched =3D 1;
+			}
+		}
+
+		failure("ACL entry on file %s that shouldn't be there", filename);
+		assert(matched =3D=3D 1);
+	}
+
+	/* Dump entries in the myacls array that weren't in the system acl. */
+	for (i =3D 0; i < n; ++i) {
+		failure(" ACL entry %d missing from %s: "
+		    "type=3D%d,permset=3D%x,tag=3D%d,qual=3D%d,name=3D``%s''\n",
+		    marker[i], filename,
+		    myacls[marker[i]].type, myacls[marker[i]].permset,
+		    myacls[marker[i]].tag, myacls[marker[i]].qual,
+		    myacls[marker[i]].name);
+		assert(0); /* Record this as a failure. */
+	}
+	free(marker);
+}
+
+static void
+compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const=
 char *filename, int start, int end)
+{
+	int *marker;
+	int matched;
+	int i, n;
+	int type, permset, tag, qual;
+	const char *name;
+
+	/* Count ACL entries in myacls array and allocate an indirect array. */
+	n =3D end - start;
+	marker =3D malloc(sizeof(marker[0]) * (n + 1));
+	for (i =3D 0; i < n; i++)
+		marker[i] =3D i + start;
+	/* Always include the first ACE. */
+	if (start > 0) {
+	  marker[n] =3D 0;
+	  ++n;
+	}
+
+	/*
+	 * Iterate over acls in entry, try to match each
+	 * one with an item in the myacls array.
+	 */
+	assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4=
));
+	while (ARCHIVE_OK =3D=3D archive_entry_acl_next(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
+
+		/* Search for a matching entry (tag and qualifier) */
+		for (i =3D 0, matched =3D 0; i < n && !matched; i++) {
+			if (tag =3D=3D myacls[marker[i]].tag
+			    && qual =3D=3D myacls[marker[i]].qual
+			    && permset =3D=3D myacls[marker[i]].permset
+			    && type =3D=3D myacls[marker[i]].type) {
+				/* We found a match; remove it. */
+				marker[i] =3D marker[n - 1];
+				n--;
+				matched =3D 1;
+			}
+		}
+
+		failure("ACL entry on file that shouldn't be there: "
+			"type=3D%d,permset=3D%x,tag=3D%d,qual=3D%d",
+			type,permset,tag,qual);
+		assert(matched =3D=3D 1);
+	}
+
+	/* Dump entries in the myacls array that weren't in the system acl. */
+	for (i =3D 0; i < n; ++i) {
+		failure(" ACL entry %d missing from %s: "
+		    "type=3D%d,permset=3D%x,tag=3D%d,qual=3D%d,name=3D``%s''\n",
+		    marker[i], filename,
+		    myacls[marker[i]].type, myacls[marker[i]].permset,
+		    myacls[marker[i]].tag, myacls[marker[i]].qual,
+		    myacls[marker[i]].name);
+		assert(0); /* Record this as a failure. */
+	}
+	free(marker);
+}
+#endif
+
+/*
+ * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
+ */
+
+DEFINE_TEST(test_acl_freebsd_nfs4)
+{
+#if !defined(__FreeBSD__)
+	skipping("FreeBSD-specific NFS4 ACL restore test");
+#elif __FreeBSD__ < 8
+	skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
+#else
+	char buff[64];
+	struct stat st;
+	struct archive *a;
+	struct archive_entry *ae;
+	int i, n;
+	acl_t acl;
+
+	/*
+	 * First, do a quick manual set/read of ACL data to
+	 * verify that the local filesystem does support ACLs.
+	 * If it doesn't, we'll simply skip the remaining tests.
+	 */
+	acl =3D acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
+	assert((void *)acl !=3D NULL);
+	/* Create a test dir and try to set an ACL on it. */
+	if (!assertMakeDir("pretest", 0755)) {
+		acl_free(acl);
+		return;
+	}
+
+	n =3D acl_set_file("pretest", ACL_TYPE_NFS4, acl);
+	acl_free(acl);
+	if (n !=3D 0 && errno =3D=3D EOPNOTSUPP) {
+		skipping("NFS4 ACL tests require that NFS4 ACLs"
+		    " be enabled on the filesystem");
+		return;
+	}
+	if (n !=3D 0 && errno =3D=3D EINVAL) {
+		skipping("This filesystem does not support NFS4 ACLs");
+		return;
+	}
+	failure("acl_set_file(): errno =3D %d (%s)",
+	    errno, strerror(errno));
+	assertEqualInt(0, n);
+
+	/* Create a write-to-disk object. */
+	assert(NULL !=3D (a =3D archive_write_disk_new()));
+	archive_write_disk_set_options(a,
+	    ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
+
+	/* Populate an archive entry with some metadata, including ACL info */
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "testall");
+	archive_entry_set_filetype(ae, AE_IFREG);
+	archive_entry_set_perm(ae, 0654);
+	archive_entry_set_mtime(ae, 123456, 7890);
+	archive_entry_set_size(ae, 0);
+	set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
+
+	/* Write the entry to disk, including ACLs. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+
+	/* Likewise for a dir. */
+	archive_entry_set_pathname(ae, "dirall");
+	archive_entry_set_filetype(ae, AE_IFDIR);
+	archive_entry_set_perm(ae, 0654);
+	archive_entry_set_mtime(ae, 123456, 7890);
+	set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+
+	for (i =3D 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
+	  sprintf(buff, "dir%d", i);
+	  archive_entry_set_pathname(ae, buff);
+	  archive_entry_set_filetype(ae, AE_IFDIR);
+	  archive_entry_set_perm(ae, 0654);
+	  archive_entry_set_mtime(ae, 123456 + i, 7891 + i);
+	  set_acls(ae, acls_dir, i, i + 1);
+	  assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+	}
+
+	archive_entry_free(ae);
+
+	/* Close the archive. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+	/* Verify the data on disk. */
+	assertEqualInt(0, stat("testall", &st));
+	assertEqualInt(st.st_mtime, 123456);
+	acl =3D acl_get_file("testall", ACL_TYPE_NFS4);
+	assert(acl !=3D (acl_t)NULL);
+	compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(a=
cls_reg[0])));
+	acl_free(acl);
+
+	/* Verify single-permission dirs on disk. */
+	for (i =3D 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
+	  sprintf(buff, "dir%d", i);
+	  assertEqualInt(0, stat(buff, &st));
+	  assertEqualInt(st.st_mtime, 123456 + i);
+	  acl =3D acl_get_file(buff, ACL_TYPE_NFS4);
+	  assert(acl !=3D (acl_t)NULL);
+	  compare_acls(acl, acls_dir, buff, i, i + 1);
+	  acl_free(acl);
+	}
+
+	/* Verify "dirall" on disk. */
+	assertEqualInt(0, stat("dirall", &st));
+	assertEqualInt(st.st_mtime, 123456);
+	acl =3D acl_get_file("dirall", ACL_TYPE_NFS4);
+	assert(acl !=3D (acl_t)NULL);
+	compare_acls(acl, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/sizeof(a=
cls_dir[0])));
+	acl_free(acl);
+
+	/* Read and compare ACL via archive_read_disk */
+	a =3D archive_read_disk_new();
+	assert(a !=3D NULL);
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "testall");
+	assertEqualInt(ARCHIVE_OK,
+		       archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/siz=
eof(acls_reg[0])));
+	archive_entry_free(ae);
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+	/* Read and compare ACL via archive_read_disk */
+	a =3D archive_read_disk_new();
+	assert(a !=3D NULL);
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "dirall");
+	assertEqualInt(ARCHIVE_OK,
+		       archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	compare_entry_acls(ae, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/siz=
eof(acls_dir[0])));
+	archive_entry_free(ae);
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+#endif
+}
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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$");
+
+#if defined(__FreeBSD__) && __FreeBSD__ >=3D 8
+#define _ACL_PRIVATE
+#include <sys/acl.h>
+
+struct myacl_t {
+	int type;
+	int permset;
+	int tag;
+	int qual; /* GID or UID of user/group, depending on tag. */
+	const char *name; /* Name of user/group, depending on tag. */
+};
+
+static struct myacl_t acls_reg[] =3D {
+	/* For this test, we need the file owner to be able to read and write the=
 ACL. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTR=
Y_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_RE=
AD_ATTRIBUTES,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
+
+	/* An entry for each type. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_USER, 109, "user109" },
+
+	/* 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_WRITE_DATA,
+	  ARCHIVE_ENTRY_ACL_USER, 115, "user115" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA,
+	  ARCHIVE_ENTRY_ACL_USER, 117, "user117" },
+	{ 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_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 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, "" }
+};
+
+
+static struct myacl_t acls_dir[] =3D {
+	/* For this test, we need to be able to read and write the ACL. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
+
+	/* An entry for each type. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 101, "user101" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 102, "user102" },
+
+	/* An entry for each permission. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 201, "user201" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE,
+	  ARCHIVE_ENTRY_ACL_USER, 202, "user202" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 203, "user203" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
+	  ARCHIVE_ENTRY_ACL_USER, 204, "user204" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
+	  ARCHIVE_ENTRY_ACL_USER, 205, "user205" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD,
+	  ARCHIVE_ENTRY_ACL_USER, 206, "user206" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
+	  ARCHIVE_ENTRY_ACL_USER, 207, "user207" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
+	  ARCHIVE_ENTRY_ACL_USER, 208, "user208" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
+	  ARCHIVE_ENTRY_ACL_USER, 209, "user209" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+	  ARCHIVE_ENTRY_ACL_USER, 210, "user210" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
+	  ARCHIVE_ENTRY_ACL_USER, 211, "user211" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
+	  ARCHIVE_ENTRY_ACL_USER, 212, "user212" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_USER, 213, "user213" },
+
+	/* 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, 301, "user301" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
+	  ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
+#if 0
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHE=
RIT,
+	  ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
+	  ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
+#endif
+
+#if 0
+	/* FreeBSD does not support audit entries. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
+	  ARCHIVE_ENTRY_ACL_USER, 401, "user401" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+	  ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
+	  ARCHIVE_ENTRY_ACL_USER, 402, "user402" },
+#endif
+
+	/* One entry for each qualifier. */
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+	  ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
+};
+
+static void
+set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int en=
d)
+{
+	int i;
+
+	archive_entry_acl_clear(ae);
+	if (start > 0) {
+		assertEqualInt(ARCHIVE_OK,
+			archive_entry_acl_add_entry(ae,
+			    acls[0].type, acls[0].permset, acls[0].tag,
+			    acls[0].qual, acls[0].name));
+	}
+	for (i =3D start; i < end; i++) {
+		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_permset_to_bitmap(acl_permset_t opaque_ps)
+{
+	static struct { int machine; int portable; } perms[] =3D {
+		{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
+		{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
+		{ACL_READ, ARCHIVE_ENTRY_ACL_READ},
+		{ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
+		{ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
+		{ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
+		{ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
+		{ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
+		{ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
+		{ACL_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
+		{ACL_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
+		{ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
+		{ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
+		{ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
+		{ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
+		{ACL_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
+		{ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
+		{ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
+		{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
+	};
+	int i, permset =3D 0;
+
+	for (i =3D 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
+		if (acl_get_perm_np(opaque_ps, perms[i].machine))
+			permset |=3D perms[i].portable;
+	return permset;
+}
+
+static int
+acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
+{
+	static struct { int machine; int portable; } flags[] =3D {
+		{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
+		{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
+		{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_IN=
HERIT},
+		{ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
+	};
+	int i, flagset =3D 0;
+
+	for (i =3D 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
+		if (acl_get_flag_np(opaque_fs, flags[i].machine))
+			flagset |=3D flags[i].portable;
+	return flagset;
+}
+
+static int
+acl_match(acl_entry_t aclent, struct myacl_t *myacl)
+{
+	gid_t g, *gp;
+	uid_t u, *up;
+	acl_tag_t tag_type;
+	acl_permset_t opaque_ps;
+	acl_flagset_t opaque_fs;
+	int perms;
+
+	acl_get_tag_type(aclent, &tag_type);
+
+	/* translate the silly opaque permset to a bitmap */
+	acl_get_permset(aclent, &opaque_ps);
+	acl_get_flagset_np(aclent, &opaque_fs);
+	perms =3D acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque=
_fs);
+	if (perms !=3D myacl->permset)
+		return (0);
+
+	switch (tag_type) {
+	case ACL_USER_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
+		break;
+	case ACL_USER:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER)
+			return (0);
+		up =3D acl_get_qualifier(aclent);
+		u =3D *up;
+		acl_free(up);
+		if ((uid_t)myacl->qual !=3D u)
+			return (0);
+		break;
+	case ACL_GROUP_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
+		break;
+	case ACL_GROUP:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP)
+			return (0);
+		gp =3D acl_get_qualifier(aclent);
+		g =3D *gp;
+		acl_free(gp);
+		if ((gid_t)myacl->qual !=3D g)
+			return (0);
+		break;
+	case ACL_MASK:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_MASK) return (0);
+		break;
+	case ACL_EVERYONE:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
+		break;
+	}
+	return (1);
+}
+
+static void
+compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int =
start, int end)
+{
+	int *marker;
+	int entry_id =3D ACL_FIRST_ENTRY;
+	int matched;
+	int i, n;
+	acl_entry_t acl_entry;
+
+	n =3D end - start;
+	marker =3D malloc(sizeof(marker[0]) * (n + 1));
+	for (i =3D 0; i < n; i++)
+		marker[i] =3D i + start;
+	/* Always include the first ACE. */
+	if (start > 0) {
+	  marker[n] =3D 0;
+	  ++n;
+	}
+
+	/*
+	 * Iterate over acls in system acl object, try to match each
+	 * one with an item in the myacls array.
+	 */
+	while (1 =3D=3D acl_get_entry(acl, entry_id, &acl_entry)) {
+		/* After the first time... */
+		entry_id =3D ACL_NEXT_ENTRY;
+
+		/* Search for a matching entry (tag and qualifier) */
+		for (i =3D 0, matched =3D 0; i < n && !matched; i++) {
+			if (acl_match(acl_entry, &myacls[marker[i]])) {
+				/* We found a match; remove it. */
+				marker[i] =3D marker[n - 1];
+				n--;
+				matched =3D 1;
+			}
+		}
+
+		failure("ACL entry on file %s that shouldn't be there", filename);
+		assert(matched =3D=3D 1);
+	}
+
+	/* Dump entries in the myacls array that weren't in the system acl. */
+	for (i =3D 0; i < n; ++i) {
+		failure(" ACL entry %d missing from %s: "
+		    "type=3D%d,permset=3D%x,tag=3D%d,qual=3D%d,name=3D``%s''\n",
+		    marker[i], filename,
+		    myacls[marker[i]].type, myacls[marker[i]].permset,
+		    myacls[marker[i]].tag, myacls[marker[i]].qual,
+		    myacls[marker[i]].name);
+		assert(0); /* Record this as a failure. */
+	}
+	free(marker);
+}
+
+static void
+compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const=
 char *filename, int start, int end)
+{
+	int *marker;
+	int matched;
+	int i, n;
+	int type, permset, tag, qual;
+	const char *name;
+
+	/* Count ACL entries in myacls array and allocate an indirect array. */
+	n =3D end - start;
+	marker =3D malloc(sizeof(marker[0]) * (n + 1));
+	for (i =3D 0; i < n; i++)
+		marker[i] =3D i + start;
+	/* Always include the first ACE. */
+	if (start > 0) {
+	  marker[n] =3D 0;
+	  ++n;
+	}
+
+	/*
+	 * Iterate over acls in entry, try to match each
+	 * one with an item in the myacls array.
+	 */
+	assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4=
));
+	while (ARCHIVE_OK =3D=3D archive_entry_acl_next(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
+
+		/* Search for a matching entry (tag and qualifier) */
+		for (i =3D 0, matched =3D 0; i < n && !matched; i++) {
+			if (tag =3D=3D myacls[marker[i]].tag
+			    && qual =3D=3D myacls[marker[i]].qual
+			    && permset =3D=3D myacls[marker[i]].permset
+			    && type =3D=3D myacls[marker[i]].type) {
+				/* We found a match; remove it. */
+				marker[i] =3D marker[n - 1];
+				n--;
+				matched =3D 1;
+			}
+		}
+
+		failure("ACL entry on file that shouldn't be there: "
+			"type=3D%d,permset=3D%x,tag=3D%d,qual=3D%d",
+			type,permset,tag,qual);
+		assert(matched =3D=3D 1);
+	}
+
+	/* Dump entries in the myacls array that weren't in the system acl. */
+	for (i =3D 0; i < n; ++i) {
+		failure(" ACL entry %d missing from %s: "
+		    "type=3D%d,permset=3D%x,tag=3D%d,qual=3D%d,name=3D``%s''\n",
+		    marker[i], filename,
+		    myacls[marker[i]].type, myacls[marker[i]].permset,
+		    myacls[marker[i]].tag, myacls[marker[i]].qual,
+		    myacls[marker[i]].name);
+		assert(0); /* Record this as a failure. */
+	}
+	free(marker);
+}
+#endif
+
+/*
+ * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
+ */
+
+DEFINE_TEST(test_acl_freebsd_nfs4)
+{
+#if !defined(__FreeBSD__)
+	skipping("FreeBSD-specific NFS4 ACL restore test");
+#elif __FreeBSD__ < 8
+	skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
+#else
+	char buff[64];
+	struct stat st;
+	struct archive *a;
+	struct archive_entry *ae;
+	int i, n;
+	acl_t acl;
+
+	/*
+	 * First, do a quick manual set/read of ACL data to
+	 * verify that the local filesystem does support ACLs.
+	 * If it doesn't, we'll simply skip the remaining tests.
+	 */
+	acl =3D acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
+	assert((void *)acl !=3D NULL);
+	/* Create a test dir and try to set an ACL on it. */
+	if (!assertMakeDir("pretest", 0755)) {
+		acl_free(acl);
+		return;
+	}
+
+	n =3D acl_set_file("pretest", ACL_TYPE_NFS4, acl);
+	acl_free(acl);
+	if (n !=3D 0 && errno =3D=3D EOPNOTSUPP) {
+		skipping("NFS4 ACL tests require that NFS4 ACLs"
+		    " be enabled on the filesystem");
+		return;
+	}
+	if (n !=3D 0 && errno =3D=3D EINVAL) {
+		skipping("This filesystem does not support NFS4 ACLs");
+		return;
+	}
+	failure("acl_set_file(): errno =3D %d (%s)",
+	    errno, strerror(errno));
+	assertEqualInt(0, n);
+
+	/* Create a write-to-disk object. */
+	assert(NULL !=3D (a =3D archive_write_disk_new()));
+	archive_write_disk_set_options(a,
+	    ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
+
+	/* Populate an archive entry with some metadata, including ACL info */
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "testall");
+	archive_entry_set_filetype(ae, AE_IFREG);
+	archive_entry_set_perm(ae, 0654);
+	archive_entry_set_mtime(ae, 123456, 7890);
+	archive_entry_set_size(ae, 0);
+	set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
+
+	/* Write the entry to disk, including ACLs. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+
+	/* Likewise for a dir. */
+	archive_entry_set_pathname(ae, "dirall");
+	archive_entry_set_filetype(ae, AE_IFDIR);
+	archive_entry_set_perm(ae, 0654);
+	archive_entry_set_mtime(ae, 123456, 7890);
+	set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+
+	for (i =3D 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
+	  sprintf(buff, "dir%d", i);
+	  archive_entry_set_pathname(ae, buff);
+	  archive_entry_set_filetype(ae, AE_IFDIR);
+	  archive_entry_set_perm(ae, 0654);
+	  archive_entry_set_mtime(ae, 123456 + i, 7891 + i);
+	  set_acls(ae, acls_dir, i, i + 1);
+	  assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+	}
+
+	archive_entry_free(ae);
+
+	/* Close the archive. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+	/* Verify the data on disk. */
+	assertEqualInt(0, stat("testall", &st));
+	assertEqualInt(st.st_mtime, 123456);
+	acl =3D acl_get_file("testall", ACL_TYPE_NFS4);
+	assert(acl !=3D (acl_t)NULL);
+	compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(a=
cls_reg[0])));
+	acl_free(acl);
+
+	/* Verify single-permission dirs on disk. */
+	for (i =3D 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
+	  sprintf(buff, "dir%d", i);
+	  assertEqualInt(0, stat(buff, &st));
+	  assertEqualInt(st.st_mtime, 123456 + i);
+	  acl =3D acl_get_file(buff, ACL_TYPE_NFS4);
+	  assert(acl !=3D (acl_t)NULL);
+	  compare_acls(acl, acls_dir, buff, i, i + 1);
+	  acl_free(acl);
+	}
+
+	/* Verify "dirall" on disk. */
+	assertEqualInt(0, stat("dirall", &st));
+	assertEqualInt(st.st_mtime, 123456);
+	acl =3D acl_get_file("dirall", ACL_TYPE_NFS4);
+	assert(acl !=3D (acl_t)NULL);
+	compare_acls(acl, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/sizeof(a=
cls_dir[0])));
+	acl_free(acl);
+
+	/* Read and compare ACL via archive_read_disk */
+	a =3D archive_read_disk_new();
+	assert(a !=3D NULL);
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "testall");
+	assertEqualInt(ARCHIVE_OK,
+		       archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/siz=
eof(acls_reg[0])));
+	archive_entry_free(ae);
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+	/* Read and compare ACL via archive_read_disk */
+	a =3D archive_read_disk_new();
+	assert(a !=3D NULL);
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "dirall");
+	assertEqualInt(ARCHIVE_OK,
+		       archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	compare_entry_acls(ae, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/siz=
eof(acls_dir[0])));
+	archive_entry_free(ae);
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+#endif
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_acl_freebsd_posix1e.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c	Fr=
i Aug 10 14:19:25 2012 +0300
@@ -0,0 +1,520 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_acl_freebsd.c 189427 200=
9-03-06 04:21:23Z kientzle $");
+
+#if defined(__FreeBSD__) && __FreeBSD__ > 4
+#include <sys/acl.h>
+
+struct myacl_t {
+	int type;  /* Type of ACL: "access" or "default" */
+	int permset; /* Permissions for this class of users. */
+	int tag; /* Owner, User, Owning group, group, other, etc. */
+	int qual; /* GID or UID of user/group, depending on tag. */
+	const char *name; /* Name of user/group, depending on tag. */
+};
+
+static struct myacl_t acls2[] =3D {
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTR=
Y_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
+	  ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
+	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+	  ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+	  ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EX=
ECUTE,
+	  ARCHIVE_ENTRY_ACL_MASK, -1, "" },
+	{ 0, 0, 0, 0, NULL }
+};
+
+static void
+set_acls(struct archive_entry *ae, struct myacl_t *acls)
+{
+	int i;
+
+	archive_entry_acl_clear(ae);
+	for (i =3D 0; acls[i].name !=3D NULL; i++) {
+		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(acl_entry_t aclent, struct myacl_t *myacl)
+{
+	gid_t g, *gp;
+	uid_t u, *up;
+	acl_tag_t tag_type;
+	acl_permset_t opaque_ps;
+	int permset =3D 0;
+
+	acl_get_tag_type(aclent, &tag_type);
+
+	/* translate the silly opaque permset to a bitmap */
+	acl_get_permset(aclent, &opaque_ps);
+	if (acl_get_perm_np(opaque_ps, ACL_EXECUTE))
+		permset |=3D ARCHIVE_ENTRY_ACL_EXECUTE;
+	if (acl_get_perm_np(opaque_ps, ACL_WRITE))
+		permset |=3D ARCHIVE_ENTRY_ACL_WRITE;
+	if (acl_get_perm_np(opaque_ps, ACL_READ))
+		permset |=3D ARCHIVE_ENTRY_ACL_READ;
+
+	if (permset !=3D myacl->permset)
+		return (0);
+
+	switch (tag_type) {
+	case ACL_USER_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
+		break;
+	case ACL_USER:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER)
+			return (0);
+		up =3D acl_get_qualifier(aclent);
+		u =3D *up;
+		acl_free(up);
+		if ((uid_t)myacl->qual !=3D u)
+			return (0);
+		break;
+	case ACL_GROUP_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
+		break;
+	case ACL_GROUP:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP)
+			return (0);
+		gp =3D acl_get_qualifier(aclent);
+		g =3D *gp;
+		acl_free(gp);
+		if ((gid_t)myacl->qual !=3D g)
+			return (0);
+		break;
+	case ACL_MASK:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_MASK) return (0);
+		break;
+	case ACL_OTHER:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_OTHER) return (0);
+		break;
+	}
+	return (1);
+}
+
+static void
+compare_acls(acl_t acl, struct myacl_t *myacls)
+{
+	int *marker;
+	int entry_id =3D ACL_FIRST_ENTRY;
+	int matched;
+	int i, n;
+	acl_entry_t acl_entry;
+
+	/* Count ACL entries in myacls array and allocate an indirect array. */
+	for (n =3D 0; myacls[n].name !=3D NULL; ++n)
+		continue;
+	marker =3D malloc(sizeof(marker[0]) * n);
+	for (i =3D 0; i < n; i++)
+		marker[i] =3D i;
+
+	/*
+	 * Iterate over acls in system acl object, try to match each
+	 * one with an item in the myacls array.
+	 */
+	while (1 =3D=3D acl_get_entry(acl, entry_id, &acl_entry)) {
+		/* After the first time... */
+		entry_id =3D ACL_NEXT_ENTRY;
+
+		/* Search for a matching entry (tag and qualifier) */
+		for (i =3D 0, matched =3D 0; i < n && !matched; i++) {
+			if (acl_match(acl_entry, &myacls[marker[i]])) {
+				/* We found a match; remove it. */
+				marker[i] =3D marker[n - 1];
+				n--;
+				matched =3D 1;
+			}
+		}
+
+		/* TODO: Print out more details in this case. */
+		failure("ACL entry on file that shouldn't be there");
+		assert(matched =3D=3D 1);
+	}
+
+	/* Dump entries in the myacls array that weren't in the system acl. */
+	for (i =3D 0; i < n; ++i) {
+		failure(" ACL entry missing from file: "
+		    "type=3D%d,permset=3D%d,tag=3D%d,qual=3D%d,name=3D``%s''\n",
+		    myacls[marker[i]].type, myacls[marker[i]].permset,
+		    myacls[marker[i]].tag, myacls[marker[i]].qual,
+		    myacls[marker[i]].name);
+		assert(0); /* Record this as a failure. */
+	}
+	free(marker);
+}
+
+#endif
+
+
+/*
+ * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
+ */
+
+DEFINE_TEST(test_acl_freebsd_posix1e)
+{
+#if !defined(__FreeBSD__)
+	skipping("FreeBSD-specific ACL restore test");
+#elif __FreeBSD__ < 5
+	skipping("ACL restore supported only on FreeBSD 5.0 and later");
+#else
+	struct stat st;
+	struct archive *a;
+	struct archive_entry *ae;
+	int n, fd;
+	acl_t acl;
+
+	/*
+	 * First, do a quick manual set/read of ACL data to
+	 * verify that the local filesystem does support ACLs.
+	 * If it doesn't, we'll simply skip the remaining tests.
+	 */
+	acl =3D acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
+	assert((void *)acl !=3D NULL);
+	/* Create a test file and try to set an ACL on it. */
+	fd =3D open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
+	failure("Could not create test file?!");
+	if (!assert(fd >=3D 0)) {
+		acl_free(acl);
+		return;
+	}
+
+	n =3D acl_set_fd(fd, acl);
+	acl_free(acl);
+	if (n !=3D 0 && errno =3D=3D EOPNOTSUPP) {
+		close(fd);
+		skipping("ACL tests require that ACL support be enabled on the filesyste=
m");
+		return;
+	}
+	if (n !=3D 0 && errno =3D=3D EINVAL) {
+		close(fd);
+		skipping("This filesystem does not support POSIX.1e ACLs");
+		return;
+	}
+	failure("acl_set_fd(): errno =3D %d (%s)",
+	    errno, strerror(errno));
+	assertEqualInt(0, n);
+	close(fd);
+
+	/* Create a write-to-disk object. */
+	assert(NULL !=3D (a =3D archive_write_disk_new()));
+	archive_write_disk_set_options(a,
+	    ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
+
+	/* Populate an archive entry with some metadata, including ACL info */
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "test0");
+	archive_entry_set_mtime(ae, 123456, 7890);
+	archive_entry_set_size(ae, 0);
+	set_acls(ae, acls2);
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+	archive_entry_free(ae);
+
+	/* Close the archive. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+	/* Verify the data on disk. */
+	assertEqualInt(0, stat("test0", &st));
+	assertEqualInt(st.st_mtime, 123456);
+	acl =3D acl_get_file("test0", ACL_TYPE_ACCESS);
+	assert(acl !=3D (acl_t)NULL);
+	compare_acls(acl, acls2);
+	acl_free(acl);
+#endif
+}
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_acl_freebsd.c 189427 200=
9-03-06 04:21:23Z kientzle $");
+
+#if defined(__FreeBSD__) && __FreeBSD__ > 4
+#include <sys/acl.h>
+
+struct myacl_t {
+	int type;  /* Type of ACL: "access" or "default" */
+	int permset; /* Permissions for this class of users. */
+	int tag; /* Owner, User, Owning group, group, other, etc. */
+	int qual; /* GID or UID of user/group, depending on tag. */
+	const char *name; /* Name of user/group, depending on tag. */
+};
+
+static struct myacl_t acls2[] =3D {
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTR=
Y_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
+	  ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
+	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+	  ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+	  ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EX=
ECUTE,
+	  ARCHIVE_ENTRY_ACL_MASK, -1, "" },
+	{ 0, 0, 0, 0, NULL }
+};
+
+static void
+set_acls(struct archive_entry *ae, struct myacl_t *acls)
+{
+	int i;
+
+	archive_entry_acl_clear(ae);
+	for (i =3D 0; acls[i].name !=3D NULL; i++) {
+		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(acl_entry_t aclent, struct myacl_t *myacl)
+{
+	gid_t g, *gp;
+	uid_t u, *up;
+	acl_tag_t tag_type;
+	acl_permset_t opaque_ps;
+	int permset =3D 0;
+
+	acl_get_tag_type(aclent, &tag_type);
+
+	/* translate the silly opaque permset to a bitmap */
+	acl_get_permset(aclent, &opaque_ps);
+	if (acl_get_perm_np(opaque_ps, ACL_EXECUTE))
+		permset |=3D ARCHIVE_ENTRY_ACL_EXECUTE;
+	if (acl_get_perm_np(opaque_ps, ACL_WRITE))
+		permset |=3D ARCHIVE_ENTRY_ACL_WRITE;
+	if (acl_get_perm_np(opaque_ps, ACL_READ))
+		permset |=3D ARCHIVE_ENTRY_ACL_READ;
+
+	if (permset !=3D myacl->permset)
+		return (0);
+
+	switch (tag_type) {
+	case ACL_USER_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
+		break;
+	case ACL_USER:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_USER)
+			return (0);
+		up =3D acl_get_qualifier(aclent);
+		u =3D *up;
+		acl_free(up);
+		if ((uid_t)myacl->qual !=3D u)
+			return (0);
+		break;
+	case ACL_GROUP_OBJ:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
+		break;
+	case ACL_GROUP:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_GROUP)
+			return (0);
+		gp =3D acl_get_qualifier(aclent);
+		g =3D *gp;
+		acl_free(gp);
+		if ((gid_t)myacl->qual !=3D g)
+			return (0);
+		break;
+	case ACL_MASK:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_MASK) return (0);
+		break;
+	case ACL_OTHER:
+		if (myacl->tag !=3D ARCHIVE_ENTRY_ACL_OTHER) return (0);
+		break;
+	}
+	return (1);
+}
+
+static void
+compare_acls(acl_t acl, struct myacl_t *myacls)
+{
+	int *marker;
+	int entry_id =3D ACL_FIRST_ENTRY;
+	int matched;
+	int i, n;
+	acl_entry_t acl_entry;
+
+	/* Count ACL entries in myacls array and allocate an indirect array. */
+	for (n =3D 0; myacls[n].name !=3D NULL; ++n)
+		continue;
+	marker =3D malloc(sizeof(marker[0]) * n);
+	for (i =3D 0; i < n; i++)
+		marker[i] =3D i;
+
+	/*
+	 * Iterate over acls in system acl object, try to match each
+	 * one with an item in the myacls array.
+	 */
+	while (1 =3D=3D acl_get_entry(acl, entry_id, &acl_entry)) {
+		/* After the first time... */
+		entry_id =3D ACL_NEXT_ENTRY;
+
+		/* Search for a matching entry (tag and qualifier) */
+		for (i =3D 0, matched =3D 0; i < n && !matched; i++) {
+			if (acl_match(acl_entry, &myacls[marker[i]])) {
+				/* We found a match; remove it. */
+				marker[i] =3D marker[n - 1];
+				n--;
+				matched =3D 1;
+			}
+		}
+
+		/* TODO: Print out more details in this case. */
+		failure("ACL entry on file that shouldn't be there");
+		assert(matched =3D=3D 1);
+	}
+
+	/* Dump entries in the myacls array that weren't in the system acl. */
+	for (i =3D 0; i < n; ++i) {
+		failure(" ACL entry missing from file: "
+		    "type=3D%d,permset=3D%d,tag=3D%d,qual=3D%d,name=3D``%s''\n",
+		    myacls[marker[i]].type, myacls[marker[i]].permset,
+		    myacls[marker[i]].tag, myacls[marker[i]].qual,
+		    myacls[marker[i]].name);
+		assert(0); /* Record this as a failure. */
+	}
+	free(marker);
+}
+
+#endif
+
+
+/*
+ * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
+ */
+
+DEFINE_TEST(test_acl_freebsd_posix1e)
+{
+#if !defined(__FreeBSD__)
+	skipping("FreeBSD-specific ACL restore test");
+#elif __FreeBSD__ < 5
+	skipping("ACL restore supported only on FreeBSD 5.0 and later");
+#else
+	struct stat st;
+	struct archive *a;
+	struct archive_entry *ae;
+	int n, fd;
+	acl_t acl;
+
+	/*
+	 * First, do a quick manual set/read of ACL data to
+	 * verify that the local filesystem does support ACLs.
+	 * If it doesn't, we'll simply skip the remaining tests.
+	 */
+	acl =3D acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
+	assert((void *)acl !=3D NULL);
+	/* Create a test file and try to set an ACL on it. */
+	fd =3D open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
+	failure("Could not create test file?!");
+	if (!assert(fd >=3D 0)) {
+		acl_free(acl);
+		return;
+	}
+
+	n =3D acl_set_fd(fd, acl);
+	acl_free(acl);
+	if (n !=3D 0 && errno =3D=3D EOPNOTSUPP) {
+		close(fd);
+		skipping("ACL tests require that ACL support be enabled on the filesyste=
m");
+		return;
+	}
+	if (n !=3D 0 && errno =3D=3D EINVAL) {
+		close(fd);
+		skipping("This filesystem does not support POSIX.1e ACLs");
+		return;
+	}
+	failure("acl_set_fd(): errno =3D %d (%s)",
+	    errno, strerror(errno));
+	assertEqualInt(0, n);
+	close(fd);
+
+	/* Create a write-to-disk object. */
+	assert(NULL !=3D (a =3D archive_write_disk_new()));
+	archive_write_disk_set_options(a,
+	    ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
+
+	/* Populate an archive entry with some metadata, including ACL info */
+	ae =3D archive_entry_new();
+	assert(ae !=3D NULL);
+	archive_entry_set_pathname(ae, "test0");
+	archive_entry_set_mtime(ae, 123456, 7890);
+	archive_entry_set_size(ae, 0);
+	set_acls(ae, acls2);
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+	archive_entry_free(ae);
+
+	/* Close the archive. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+	/* Verify the data on disk. */
+	assertEqualInt(0, stat("test0", &st));
+	assertEqualInt(st.st_mtime, 123456);
+	acl =3D acl_get_file("test0", ACL_TYPE_ACCESS);
+	assert(acl !=3D (acl_t)NULL);
+	compare_acls(acl, acls2);
+	acl_free(acl);
+#endif
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_archive_getdate.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_archive_getdate.c	Fri Au=
g 10 14:19:25 2012 +0300
@@ -0,0 +1,81 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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 <time.h>
+
+/*
+ * Verify that the getdate() function works.
+ */
+
+time_t __archive_get_date(time_t, const char *);
+#define get_date __archive_get_date
+
+DEFINE_TEST(test_archive_getdate)
+{
+	time_t now =3D time(NULL);
+
+	assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0);
+	assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138);
+	assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980);
+	assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000);
+	assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460);
+	/* It's important that we handle ctime() format. */
+	assertEqualInt(get_date(now, "Sun Feb 22 17:38:26 PST 2009"),
+	    1235353106);
+	/* Basic relative offsets. */
+	/* If we use the actual current time as the reference, then
+	 * these tests break around DST changes, so it's actually
+	 * important to use a specific reference time here. */
+	assertEqualInt(get_date(0, "tomorrow"), 24 * 60 * 60);
+	assertEqualInt(get_date(0, "yesterday"), - 24 * 60 * 60);
+	assertEqualInt(get_date(0, "now + 1 hour"), 60 * 60);
+	assertEqualInt(get_date(0, "now + 1 hour + 1 minute"), 60 * 60 + 60);
+	/* Repeat the above for a different start time. */
+	now =3D 1231113600; /* Jan 5, 2009 00:00 UTC */
+	assertEqualInt(get_date(0, "Jan 5, 2009 00:00 UTC"), now);
+	assertEqualInt(get_date(now, "tomorrow"), now + 24 * 60 * 60);
+	assertEqualInt(get_date(now, "yesterday"), now - 24 * 60 * 60);
+	assertEqualInt(get_date(now, "now + 1 hour"), now + 60 * 60);
+	assertEqualInt(get_date(now, "now + 1 hour + 1 minute"),
+	    now + 60 * 60 + 60);
+	assertEqualInt(get_date(now, "tomorrow 5:16am UTC"),
+	    now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60);
+	assertEqualInt(get_date(now, "UTC 5:16am tomorrow"),
+	    now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60);
+
+	/* Jan 5, 2009 was a Monday. */
+	assertEqualInt(get_date(now, "monday UTC"), now);
+	assertEqualInt(get_date(now, "sunday UTC"), now + 6 * 24 * 60 * 60);
+	assertEqualInt(get_date(now, "tuesday UTC"), now + 24 * 60 * 60);
+	/* "next tuesday" is one week after "tuesday" */
+	assertEqualInt(get_date(now, "UTC next tuesday"),
+	    now + 8 * 24 * 60 * 60);
+	/* "last tuesday" is one week before "tuesday" */
+	assertEqualInt(get_date(now, "last tuesday UTC"),
+	    now - 6 * 24 * 60 * 60);
+	/* TODO: Lots more tests here. */
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_archive_match_owner.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_archive_match_owner.c	Fr=
i Aug 10 14:19:25 2012 +0300
@@ -0,0 +1,289 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_uid(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_uid(m, 1000));
+	assertEqualIntA(m, 0, archive_match_include_uid(m, 1002));
+
+	archive_entry_set_uid(ae, 0);
+	failure("uid 0 should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_uid(ae, 1000);
+	failure("uid 1000 should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_uid(ae, 1001);
+	failure("uid 1001 should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_uid(ae, 1002);
+	failure("uid 1002 should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_uid(ae, 1003);
+	failure("uid 1003 should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_gid(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_gid(m, 1000));
+	assertEqualIntA(m, 0, archive_match_include_gid(m, 1002));
+
+	archive_entry_set_gid(ae, 0);
+	failure("uid 0 should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_gid(ae, 1000);
+	failure("uid 1000 should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_gid(ae, 1001);
+	failure("uid 1001 should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_gid(ae, 1002);
+	failure("uid 1002 should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_gid(ae, 1003);
+	failure("uid 1003 should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_uname_mbs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_uname(m, "foo"));
+	assertEqualIntA(m, 0, archive_match_include_uname(m, "bar"));
+
+	archive_entry_copy_uname(ae, "unknown");
+	failure("User 'unknown' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_uname(ae, "foo");
+	failure("User 'foo' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_uname(ae, "foo1");
+	failure("User 'foo1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_uname(ae, "bar");
+	failure("User 'bar' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_uname(ae, "bar1");
+	failure("User 'bar1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_uname_wcs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_uname_w(m, L"foo"));
+	assertEqualIntA(m, 0, archive_match_include_uname_w(m, L"bar"));
+
+	archive_entry_copy_uname_w(ae, L"unknown");
+	failure("User 'unknown' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_uname_w(ae, L"foo");
+	failure("User 'foo' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_uname_w(ae, L"foo1");
+	failure("User 'foo1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_uname_w(ae, L"bar");
+	failure("User 'bar' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_uname_w(ae, L"bar1");
+	failure("User 'bar1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_gname_mbs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_gname(m, "foo"));
+	assertEqualIntA(m, 0, archive_match_include_gname(m, "bar"));
+
+	archive_entry_copy_gname(ae, "unknown");
+	failure("Group 'unknown' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_gname(ae, "foo");
+	failure("Group 'foo' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_gname(ae, "foo1");
+	failure("Group 'foo1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_gname(ae, "bar");
+	failure("Group 'bar' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_gname(ae, "bar1");
+	failure("Group 'bar1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_gname_wcs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_gname_w(m, L"foo"));
+	assertEqualIntA(m, 0, archive_match_include_gname_w(m, L"bar"));
+
+	archive_entry_copy_gname_w(ae, L"unknown");
+	failure("Group 'unknown' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_gname_w(ae, L"foo");
+	failure("Group 'foo' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_gname_w(ae, L"foo1");
+	failure("Group 'foo1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_copy_gname_w(ae, L"bar");
+	failure("Group 'bar' should not be excluded");
+	assertEqualInt(0, archive_match_owner_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_copy_gname_w(ae, L"bar1");
+	failure("Group 'bar1' should be excluded");
+	assertEqualInt(1, archive_match_owner_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+DEFINE_TEST(test_archive_match_owner)
+{
+	test_uid();
+	test_gid();
+	test_uname_mbs();
+	test_uname_wcs();
+	test_gname_mbs();
+	test_gname_wcs();
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_archive_match_path.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_archive_match_path.c	Fri=
 Aug 10 14:19:25 2012 +0300
@@ -0,0 +1,450 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_exclusion_mbs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	/* Test for pattern "^aa*" */
+	assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aa*"));
+
+	/* Test with 'aa1234', which should be excluded. */
+	archive_entry_copy_pathname(ae, "aa1234");
+	failure("'aa1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"aa1234");
+	failure("'aa1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Test with 'a1234', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "a1234");
+	failure("'a1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"a1234");
+	failure("'a1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_exclusion_wcs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	/* Test for pattern "^aa*" */
+	assertEqualIntA(m, 0, archive_match_exclude_pattern_w(m, L"^aa*"));
+
+	/* Test with 'aa1234', which should be excluded. */
+	archive_entry_copy_pathname(ae, "aa1234");
+	failure("'aa1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"aa1234");
+	failure("'aa1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Test with 'a1234', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "a1234");
+	failure("'a1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"a1234");
+	failure("'a1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+exclusion_from_file(struct archive *m)
+{
+	struct archive_entry *ae;
+
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	/* Test with 'first', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "first");
+	failure("'first' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"first");
+	failure("'first' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Test with 'second', which should be excluded. */
+	archive_entry_copy_pathname(ae, "second");
+	failure("'second' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"second");
+	failure("'second' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Test with 'third', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "third");
+	failure("'third' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"third");
+	failure("'third' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Test with 'four', which should be excluded. */
+	archive_entry_copy_pathname(ae, "four");
+	failure("'four' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"four");
+	failure("'four' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+}
+
+static void
+test_exclusion_from_file_mbs(void)
+{
+	struct archive *m;
+
+	/* Test1: read exclusion patterns from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	assertEqualIntA(m, 0,
+	    archive_match_exclude_pattern_from_file(m, "exclusion", 0));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+
+	/* Test2: read exclusion patterns in a null separator from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	/* Test for pattern reading from file */
+	assertEqualIntA(m, 0,
+	    archive_match_exclude_pattern_from_file(m, "exclusion_null", 1));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+}
+
+static void
+test_exclusion_from_file_wcs(void)
+{
+	struct archive *m;
+
+	/* Test1: read exclusion patterns from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	assertEqualIntA(m, 0,
+	    archive_match_exclude_pattern_from_file_w(m, L"exclusion", 0));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+
+	/* Test2: read exclusion patterns in a null separator from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	/* Test for pattern reading from file */
+	assertEqualIntA(m, 0,
+	    archive_match_exclude_pattern_from_file_w(m, L"exclusion_null", 1));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+}
+
+static void
+test_inclusion_mbs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	const char *mp;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	/* Test for pattern "^aa*" */
+	assertEqualIntA(m, 0, archive_match_include_pattern(m, "^aa*"));
+
+	/* Test with 'aa1234', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "aa1234");
+	failure("'aa1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"aa1234");
+	failure("'aa1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Test with 'a1234', which should be excluded. */
+	archive_entry_copy_pathname(ae, "a1234");
+	failure("'a1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"a1234");
+	failure("'a1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify unmatched_inclusions. */
+	assertEqualInt(0, archive_match_path_unmatched_inclusions(m));
+	assertEqualIntA(m, ARCHIVE_EOF,
+	    archive_match_path_unmatched_inclusions_next(m, &mp));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_inclusion_wcs(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	const char *mp;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	/* Test for pattern "^aa*" */
+	assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*"));
+
+	/* Test with 'aa1234', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "aa1234");
+	failure("'aa1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"aa1234");
+	failure("'aa1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Test with 'a1234', which should be excluded. */
+	archive_entry_copy_pathname(ae, "a1234");
+	failure("'a1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"a1234");
+	failure("'a1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify unmatched_inclusions. */
+	assertEqualInt(0, archive_match_path_unmatched_inclusions(m));
+	assertEqualIntA(m, ARCHIVE_EOF,
+	    archive_match_path_unmatched_inclusions_next(m, &mp));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_inclusion_from_file_mbs(void)
+{
+	struct archive *m;
+
+	/* Test1: read inclusion patterns from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	assertEqualIntA(m, 0,
+	    archive_match_include_pattern_from_file(m, "inclusion", 0));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+
+	/* Test2: read inclusion patterns in a null separator from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	assertEqualIntA(m, 0,
+	    archive_match_include_pattern_from_file(m, "inclusion_null", 1));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+}
+
+static void
+test_inclusion_from_file_wcs(void)
+{
+	struct archive *m;
+
+	/* Test1: read inclusion patterns from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	/* Test for pattern reading from file */
+	assertEqualIntA(m, 0,
+	    archive_match_include_pattern_from_file_w(m, L"inclusion", 0));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+
+	/* Test2: read inclusion patterns in a null separator from file */
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	/* Test for pattern reading from file */
+	assertEqualIntA(m, 0,
+	    archive_match_include_pattern_from_file_w(m, L"inclusion_null", 1));
+	exclusion_from_file(m);
+	/* Clean up. */
+	archive_match_free(m);
+}
+
+static void
+test_exclusion_and_inclusion(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	const char *mp;
+	const wchar_t *wp;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aaa*"));
+	assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*"));
+	assertEqualIntA(m, 0, archive_match_include_pattern(m, "^a1*"));
+
+	/* Test with 'aa1234', which should not be excluded. */
+	archive_entry_copy_pathname(ae, "aa1234");
+	failure("'aa1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"aa1234");
+	failure("'aa1234' should not be excluded");
+	assertEqualInt(0, archive_match_path_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Test with 'aaa1234', which should be excluded. */
+	archive_entry_copy_pathname(ae, "aaa1234");
+	failure("'aaa1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname_w(ae, L"aaa1234");
+	failure("'aaa1234' should be excluded");
+	assertEqualInt(1, archive_match_path_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify unmatched_inclusions. */
+	assertEqualInt(1, archive_match_path_unmatched_inclusions(m));
+	/* Verify unmatched inclusion patterns. */
+	assertEqualIntA(m, ARCHIVE_OK,
+	    archive_match_path_unmatched_inclusions_next(m, &mp));
+	assertEqualString("^a1*", mp);
+	assertEqualIntA(m, ARCHIVE_EOF,
+	    archive_match_path_unmatched_inclusions_next(m, &mp));
+	/* Verify unmatched inclusion patterns again in Wide-Char. */
+	assertEqualIntA(m, ARCHIVE_OK,
+	    archive_match_path_unmatched_inclusions_next_w(m, &wp));
+	assertEqualWString(L"^a1*", wp);
+	assertEqualIntA(m, ARCHIVE_EOF,
+	    archive_match_path_unmatched_inclusions_next_w(m, &wp));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+DEFINE_TEST(test_archive_match_path)
+{
+	/* Make exclusion sample files which contain exclusion patterns. */
+	assertMakeFile("exclusion", 0666, "second\nfour\n");
+	assertMakeBinFile("exclusion_null", 0666, 12, "second\0four\0");
+	/* Make inclusion sample files which contain inclusion patterns. */
+	assertMakeFile("inclusion", 0666, "first\nthird\n");
+	assertMakeBinFile("inclusion_null", 0666, 12, "first\0third\0");
+
+	test_exclusion_mbs();
+	test_exclusion_wcs();
+	test_exclusion_from_file_mbs();
+	test_exclusion_from_file_wcs();
+	test_inclusion_mbs();
+	test_inclusion_wcs();
+	test_inclusion_from_file_mbs();
+	test_inclusion_from_file_wcs();
+	test_exclusion_and_inclusion();
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_archive_match_time.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_archive_match_time.c	Fri=
 Aug 10 14:19:25 2012 +0300
@@ -0,0 +1,1358 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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$");
+
+time_t __archive_get_date(time_t, const char *);
+
+static void
+test_newer_time(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_time(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_NEWER, 7880, 0));
+
+	archive_entry_copy_pathname(ae, "file1");
+	archive_entry_set_mtime(ae, 7880, 0);
+	archive_entry_set_ctime(ae, 7880, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7879, 999);
+	archive_entry_set_ctime(ae, 7879, 999);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, 7881, 0);
+	archive_entry_set_ctime(ae, 7881, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, 7880, 1);
+	archive_entry_set_ctime(ae, 7880, 0);
+	failure("Its mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, 7880, 0);
+	archive_entry_set_ctime(ae, 7880, 1);
+	failure("Its ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_newer_time_str(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	time_t now, t;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	time(&now);
+
+	assertEqualIntA(m, 0, archive_match_include_date(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_NEWER, "1980/2/1 0:0:0 UTC"));
+
+	/* Test1: Allow newer time. */
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 1);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Its mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 1);
+	failure("Its ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+
+	/* Test2: Allow equal or newer time. */
+	assertEqualIntA(m, 0, archive_match_include_date(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL,
+	    "1980/2/1 0:0:0 UTC"));
+
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_newer_time_str_w(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	time_t now, t;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	time(&now);
+
+	assertEqualIntA(m, 0, archive_match_include_date_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_NEWER, L"1980/2/1 0:0:0 UTC"));
+
+	/* Test1: Allow newer time. */
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 1);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Its mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 1);
+	failure("Its ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+
+	/* Test2: Allow equal or newer time. */
+	assertEqualIntA(m, 0, archive_match_include_date_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL,
+	    L"1980/2/1 0:0:0 UTC"));
+
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_newer_mtime_than_file_mbs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: newer mtime than a file specified in MBS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "mid_mtime"));
+
+	/* Verify 'old_mtime' file. */
+	archive_entry_copy_pathname(ae, "old_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_mtime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_newer_ctime_than_file_mbs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: newer ctime than a file specified in MBS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "mid_ctime"));
+
+	/* Verify 'old_ctime' file. */
+	archive_entry_copy_pathname(ae, "old_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_newer_mtime_than_file_wcs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: newer mtime than a file specified in WCS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"mid_mtime"));
+
+	/* Verify 'old_mtime' file. */
+	archive_entry_copy_pathname(ae, "old_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_mtime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_newer_ctime_than_file_wcs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: newer ctime than a file specified in WCS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"mid_ctime"));
+
+	/* Verify 'old_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "old_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_time(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	assertEqualIntA(m, 0, archive_match_include_time(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_OLDER, 7880, 0));
+
+	archive_entry_copy_pathname(ae, "file1");
+	archive_entry_set_mtime(ae, 7880, 0);
+	archive_entry_set_ctime(ae, 7880, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7879, 999);
+	archive_entry_set_ctime(ae, 7879, 999);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, 7881, 0);
+	archive_entry_set_ctime(ae, 7881, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, 7880, 1);
+	archive_entry_set_ctime(ae, 7879, 0);
+	failure("Its mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	archive_entry_set_mtime(ae, 7879, 0);
+	archive_entry_set_ctime(ae, 7880, 1);
+	failure("Its ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_time_str(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	time_t now, t;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	time(&now);
+
+	/* Test1: Allow newer time. */
+	assertEqualIntA(m, 0, archive_match_include_date(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_OLDER, "1980/2/1 0:0:0 UTC"));
+
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Its mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Its ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Test2: Allow equal or newer time. */
+	assertEqualIntA(m, 0, archive_match_include_date(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL,
+	    "1980/2/1 0:0:0 UTC"));
+
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_time_str_w(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+	time_t now, t;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	time(&now);
+
+	/* Test1: Allow newer time. */
+	assertEqualIntA(m, 0, archive_match_include_date_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_OLDER, L"1980/2/1 0:0:0 UTC"));
+
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Its mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Its ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Test2: Allow equal or newer time. */
+	assertEqualIntA(m, 0, archive_match_include_date_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
+	    ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL,
+	    L"1980/2/1 0:0:0 UTC"));
+
+	archive_entry_copy_pathname(ae, "file1");
+	t =3D __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	t =3D __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	t =3D __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+	archive_entry_set_mtime(ae, t, 0);
+	archive_entry_set_ctime(ae, t, 0);
+	failure("Both Its mtime and ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_mtime_than_file_mbs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: older mtime than a file specified in MBS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "mid_mtime"));
+
+	/* Verify 'old_mtime' file. */
+	archive_entry_copy_pathname(ae, "old_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_mtime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_ctime_than_file_mbs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: older ctime than a file specified in MBS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "mid_ctime"));
+
+	/* Verify 'old_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "old_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_mtime_than_file_wcs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: older mtime than a file specified in WCS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"mid_mtime"));
+
+	/* Verify 'old_mtime' file. */
+	archive_entry_copy_pathname(ae, "old_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_mtime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_older_ctime_than_file_wcs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: older ctime than a file specified in WCS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"mid_ctime"));
+
+	/* Verify 'old_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "old_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'new_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_mtime_between_files_mbs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: mtime between  file specified in MBS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "old_mtime"));
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "new_mtime"));
+
+	/* Verify 'old_mtime' file. */
+	archive_entry_copy_pathname(ae, "old_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_mtime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'new_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_mtime_between_files_wcs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: mtime between  file specified in WCS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"old_mtime"));
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"new_mtime"));
+
+	/* Verify 'old_mtime' file. */
+	archive_entry_copy_pathname(ae, "old_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_mtime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'new_mtime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_mtime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_mtime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_ctime_between_files_mbs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: ctime between files specified in MBS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "old_ctime"));
+	assertEqualIntA(m, 0, archive_match_include_file_time(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "new_ctime"));
+
+	/* Verify 'old_ctime' file. */
+	archive_entry_copy_pathname(ae, "old_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'new_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+test_ctime_between_files_wcs(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+	if (!assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_match_free(m);
+		archive_entry_free(ae);
+		return;
+	}
+
+	/*
+	 * Test: ctime between files specified in WCS file name.
+	 */
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"old_ctime"));
+	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
+	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"new_ctime"));
+
+	/* Verify 'old_ctime' file. */
+	archive_entry_copy_pathname(ae, "old_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("old_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Verify 'mid_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "mid_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("mid_ctime should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	/* Verify 'new_ctime' file. */
+	archive_entry_clear(ae);
+	archive_entry_copy_pathname(ae, "new_ctime");
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
+	failure("new_ctime should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/* Clean up. */
+	archive_read_free(a);
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+static void
+excluded(struct archive *m)
+{
+	struct archive_entry *ae;
+
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL))
+		return;
+
+	archive_entry_copy_pathname(ae, "file1");
+	archive_entry_set_mtime(ae, 7879, 999);
+	failure("It should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 0);
+	failure("It should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 1);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	archive_entry_copy_pathname(ae, "file2");
+	archive_entry_set_mtime(ae, 7879, 999);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 0);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 1);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+	archive_entry_copy_pathname(ae, "file3");
+	archive_entry_set_mtime(ae, 7879, 999);
+	failure("It should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 0);
+	failure("It should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 1);
+	failure("It should be excluded");
+	assertEqualInt(1, archive_match_time_excluded(m, ae));
+	assertEqualInt(1, archive_match_excluded(m, ae));
+
+	/*
+	 * "file4" is not registered, that sort of a file should not be
+	 * excluded with any mtime.
+	 */
+	archive_entry_copy_pathname(ae, "file4");
+	archive_entry_set_mtime(ae, 7879, 999);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 0);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+	archive_entry_set_mtime(ae, 7880, 1);
+	failure("It should not be excluded");
+	assertEqualInt(0, archive_match_time_excluded(m, ae));
+	assertEqualInt(0, archive_match_excluded(m, ae));
+
+
+	/* Clean up. */
+	archive_entry_free(ae);
+}
+
+static void
+test_pathname_newer_mtime(void)
+{
+	struct archive_entry *ae;
+	struct archive *m;
+
+	if (!assert((m =3D archive_match_new()) !=3D NULL))
+		return;
+	if (!assert((ae =3D archive_entry_new()) !=3D NULL)) {
+		archive_match_free(m);
+		return;
+	}
+
+	archive_entry_copy_pathname(ae, "file1");
+	archive_entry_set_mtime(ae, 7880, 0);
+	assertEqualIntA(m, 0, archive_match_exclude_entry(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
+	    ARCHIVE_MATCH_EQUAL, ae));
+	archive_entry_copy_pathname(ae, "file2");
+	archive_entry_set_mtime(ae, 1, 0);
+	assertEqualIntA(m, 0, archive_match_exclude_entry(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
+	    ARCHIVE_MATCH_EQUAL, ae));
+	archive_entry_copy_pathname(ae, "file3");
+	archive_entry_set_mtime(ae, 99999, 0);
+	assertEqualIntA(m, 0, archive_match_exclude_entry(m,
+	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
+	    ARCHIVE_MATCH_EQUAL, ae));
+
+	excluded(m);
+
+	/* Clean up. */
+	archive_entry_free(ae);
+	archive_match_free(m);
+}
+
+DEFINE_TEST(test_archive_match_time)
+{
+	struct stat st;
+
+	/* Test: matching newer times. */
+	test_newer_time();
+	test_newer_time_str();
+	test_newer_time_str_w();
+	/* Test: matching older times. */
+	test_older_time();
+	test_older_time_str();
+	test_older_time_str_w();
+
+	/*
+	 * Create sample files for tests matching mtime.
+	 * ctimes of those files may be all the same or the ctime of
+	 * new_mtime may be older than old_mtime.
+	 */
+	assertMakeFile("new_mtime", 0666, "new");
+	assertUtimes("new_mtime", 10002, 0, 10002, 0);
+	assertMakeFile("mid_mtime", 0666, "mid");
+	assertUtimes("mid_mtime", 10001, 0, 10001, 0);
+	assertMakeFile("old_mtime", 0666, "old");
+	assertUtimes("old_mtime", 10000, 0, 10000, 0);
+
+	/*
+	 * Create sample files for tests matching ctime.
+	 * the mtime of mid_ctime is older than old_ctime and also the mtime
+	 * of new_ctime is older than both mid_ctime and old_ctime.
+	 */
+	assertMakeFile("old_ctime", 0666, "old");
+	assertUtimes("old_ctime", 10002, 0, 10002, 0);
+	assertEqualInt(0, stat("old_ctime", &st));
+	sleepUntilAfter(st.st_ctime);
+	assertMakeFile("mid_ctime", 0666, "mid");
+	assertUtimes("mid_ctime", 10001, 0, 10001, 0);
+	assertEqualInt(0, stat("mid_ctime", &st));
+	sleepUntilAfter(st.st_ctime);
+	assertMakeFile("new_ctime", 0666, "new");
+	assertUtimes("new_ctime", 10000, 0, 10000, 0);
+
+	/*
+	 * Test: matching mtime which indicated by files on the disk.
+	 */
+	test_newer_mtime_than_file_mbs();
+	test_newer_mtime_than_file_wcs();
+	test_older_mtime_than_file_mbs();
+	test_older_mtime_than_file_wcs();
+	test_mtime_between_files_mbs();
+	test_mtime_between_files_wcs();
+
+	/*
+	 * Test: matching ctime which indicated by files on the disk.
+	 */
+	test_newer_ctime_than_file_mbs();
+	test_newer_ctime_than_file_wcs();
+	test_older_ctime_than_file_mbs();
+	test_older_ctime_than_file_wcs();
+	test_ctime_between_files_mbs();
+	test_ctime_between_files_wcs();
+
+	/* Test: matching both pathname and mtime. */
+	test_pathname_newer_mtime();
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_archive_pathmatch.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/libarchive/test/test_archive_pathmatch.c	Fri =
Aug 10 14:19:25 2012 +0300
@@ -0,0 +1,244 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_pathmatch.h"
+
+/*
+ * Verify that the pattern matcher implements the wildcard logic specified
+ * in SUSv2 for the cpio command.  This is essentially the
+ * shell glob syntax:
+ *   * - matches any sequence of chars, including '/'
+ *   ? - matches any single char, including '/'
+ *   [...] - matches any of a set of chars, '-' specifies a range,
+ *        initial '!' is undefined
+ *
+ * The specification in SUSv2 is a bit incomplete, I assume the following:
+ *   Trailing '-' in [...] is not special.
+ *
+ * TODO: Figure out if there's a good way to extend this to handle
+ * Windows paths that use '\' as a path separator.  <sigh>
+ */
+
+DEFINE_TEST(test_archive_pathmatch)
+{
+	assertEqualInt(1, archive_pathmatch("a/b/c", "a/b/c", 0));
+	assertEqualInt(0, archive_pathmatch("a/b/", "a/b/c", 0));
+	assertEqualInt(0, archive_pathmatch("a/b", "a/b/c", 0));
+	assertEqualInt(0, archive_pathmatch("a/b/c", "a/b/", 0));
+	assertEqualInt(0, archive_pathmatch("a/b/c", "a/b", 0));
+
+	/* Empty pattern only matches empty string. */
+	assertEqualInt(1, archive_pathmatch("","", 0));
+	assertEqualInt(0, archive_pathmatch("","a", 0));
+	assertEqualInt(1, archive_pathmatch("*","", 0));
+	assertEqualInt(1, archive_pathmatch("*","a", 0));
+	assertEqualInt(1, archive_pathmatch("*","abcd", 0));
+	/* SUSv2: * matches / */
+	assertEqualInt(1, archive_pathmatch("*","abcd/efgh/ijkl", 0));
+	assertEqualInt(1, archive_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0)=
);
+	assertEqualInt(1, archive_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", =
0));
+	assertEqualInt(1, archive_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl",=
 0));
+	assertEqualInt(0, archive_pathmatch("?", "", 0));
+	assertEqualInt(0, archive_pathmatch("?", "\0", 0));
+	assertEqualInt(1, archive_pathmatch("?", "a", 0));
+	assertEqualInt(0, archive_pathmatch("?", "ab", 0));
+	assertEqualInt(1, archive_pathmatch("?", ".", 0));
+	assertEqualInt(1, archive_pathmatch("?", "?", 0));
+	assertEqualInt(1, archive_pathmatch("a", "a", 0));
+	assertEqualInt(0, archive_pathmatch("a", "ab", 0));
+	assertEqualInt(0, archive_pathmatch("a", "ab", 0));
+	assertEqualInt(1, archive_pathmatch("a?c", "abc", 0));
+	/* SUSv2: ? matches / */
+	assertEqualInt(1, archive_pathmatch("a?c", "a/c", 0));
+	assertEqualInt(1, archive_pathmatch("a?*c*", "a/c", 0));
+	assertEqualInt(1, archive_pathmatch("*a*", "a/c", 0));
+	assertEqualInt(1, archive_pathmatch("*a*", "/a/c", 0));
+	assertEqualInt(1, archive_pathmatch("*a*", "defaaaaaaa", 0));
+	assertEqualInt(0, archive_pathmatch("a*", "defghi", 0));
+	assertEqualInt(0, archive_pathmatch("*a*", "defghi", 0));
+
+	/* Character classes */
+	assertEqualInt(1, archive_pathmatch("abc[def", "abc[def", 0));
+	assertEqualInt(0, archive_pathmatch("abc[def]", "abc[def", 0));
+	assertEqualInt(0, archive_pathmatch("abc[def", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[def]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[def]", "abce", 0));
+	assertEqualInt(1, archive_pathmatch("abc[def]", "abcf", 0));
+	assertEqualInt(0, archive_pathmatch("abc[def]", "abcg", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d*f]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d*f]", "abc*", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d*f]", "abcdefghi", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d*", "abcdefghi", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d*", "abc[defghi", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-f]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-f]", "abce", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-f]", "abcf", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d-f]", "abcg", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abca", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abce", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcf", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abcg", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abch", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abci", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcj", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abck", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abcl", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abc-", 0));
+
+	/* [] matches nothing, [!] is the same as ? */
+	assertEqualInt(0, archive_pathmatch("abc[]efg", "abcdefg", 0));
+	assertEqualInt(0, archive_pathmatch("abc[]efg", "abcqefg", 0));
+	assertEqualInt(0, archive_pathmatch("abc[]efg", "abcefg", 0));
+	assertEqualInt(1, archive_pathmatch("abc[!]efg", "abcdefg", 0));
+	assertEqualInt(1, archive_pathmatch("abc[!]efg", "abcqefg", 0));
+	assertEqualInt(0, archive_pathmatch("abc[!]efg", "abcefg", 0));
+
+	/* I assume: Trailing '-' is non-special. */
+	assertEqualInt(0, archive_pathmatch("abc[d-fh-]", "abcl", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abch", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abc-", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abc-", 0));
+
+	/* ']' can be backslash-quoted within a character class. */
+	assertEqualInt(1, archive_pathmatch("abc[\\]]", "abc]", 0));
+	assertEqualInt(1, archive_pathmatch("abc[\\]d]", "abc]", 0));
+	assertEqualInt(1, archive_pathmatch("abc[\\]d]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d\\]]", "abc]", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d\\]]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d]e]", "abcde]", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d\\]e]", "abc]", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d\\]e]", "abcd]e", 0));
+	assertEqualInt(0, archive_pathmatch("abc[d]e]", "abc]", 0));
+
+	/* backslash-quoted chars can appear as either end of a range. */
+	assertEqualInt(1, archive_pathmatch("abc[\\d-f]gh", "abcegh", 0));
+	assertEqualInt(0, archive_pathmatch("abc[\\d-f]gh", "abcggh", 0));
+	assertEqualInt(0, archive_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d-\\f]gh", "abcegh", 0));
+	assertEqualInt(1, archive_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
+	assertEqualInt(1, archive_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
+	/* backslash-quoted '-' isn't special. */
+	assertEqualInt(0, archive_pathmatch("abc[d\\-f]gh", "abcegh", 0));
+	assertEqualInt(1, archive_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
+
+	/* Leading '!' negates a character class. */
+	assertEqualInt(0, archive_pathmatch("abc[!d]", "abcd", 0));
+	assertEqualInt(1, archive_pathmatch("abc[!d]", "abce", 0));
+	assertEqualInt(1, archive_pathmatch("abc[!d]", "abcc", 0));
+	assertEqualInt(0, archive_pathmatch("abc[!d-z]", "abcq", 0));
+	assertEqualInt(1, archive_pathmatch("abc[!d-gi-z]", "abch", 0));
+	assertEqualInt(1, archive_pathmatch("abc[!fgijkl]", "abch", 0));
+	assertEqualInt(0, archive_pathmatch("abc[!fghijkl]", "abch", 0));
+
+	/* Backslash quotes next character. */
+	assertEqualInt(0, archive_pathmatch("abc\\[def]", "abc\\d", 0));
+	assertEqualInt(1, archive_pathmatch("abc\\[def]", "abc[def]", 0));
+	assertEqualInt(0, archive_pathmatch("abc\\\\[def]", "abc[def]", 0));
+	assertEqualInt(0, archive_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
+	assertEqualInt(1, archive_pathmatch("abc\\\\[def]", "abc\\d", 0));
+	assertEqualInt(1, archive_pathmatch("abcd\\", "abcd\\", 0));
+	assertEqualInt(0, archive_pathmatch("abcd\\", "abcd\\[", 0));
+	assertEqualInt(0, archive_pathmatch("abcd\\", "abcde", 0));
+	assertEqualInt(0, archive_pathmatch("abcd\\[", "abcd\\", 0));
+
+	/*
+	 * Because '.' and '/' have special meanings, we can
+	 * identify many equivalent paths even if they're expressed
+	 * differently.  (But quoting a character with '\\' suppresses
+	 * special meanings!)
+	 */
+	assertEqualInt(0, archive_pathmatch("a/b/", "a/bc", 0));
+	assertEqualInt(1, archive_pathmatch("a/./b", "a/b", 0));
+	assertEqualInt(0, archive_pathmatch("a\\/./b", "a/b", 0));
+	assertEqualInt(0, archive_pathmatch("a/\\./b", "a/b", 0));
+	assertEqualInt(0, archive_pathmatch("a/.\\/b", "a/b", 0));
+	assertEqualInt(0, archive_pathmatch("a\\/\\.\\/b", "a/b", 0));
+	assertEqualInt(1, archive_pathmatch("./abc/./def/", "abc/def/", 0));
+	assertEqualInt(1, archive_pathmatch("abc/def", "./././abc/./def", 0));
+	assertEqualInt(1, archive_pathmatch("abc/def/././//", "./././abc/./def/",=
 0));
+	assertEqualInt(1, archive_pathmatch(".////abc/.//def", "./././abc/./def",=
 0));
+	assertEqualInt(1, archive_pathmatch("./abc?def/", "abc/def/", 0));
+	failure("\"?./\" is not the same as \"/./\"");
+	assertEqualInt(0, archive_pathmatch("./abc?./def/", "abc/def/", 0));
+	failure("Trailing '/' should match no trailing '/'");
+	assertEqualInt(1, archive_pathmatch("./abc/./def/", "abc/def", 0));
+	failure("Trailing '/./' is still the same directory.");
+	assertEqualInt(1, archive_pathmatch("./abc/./def/./", "abc/def", 0));
+	failure("Trailing '/.' is still the same directory.");
+	assertEqualInt(1, archive_pathmatch("./abc/./def/.", "abc/def", 0));
+	assertEqualInt(1, archive_pathmatch("./abc/./def", "abc/def/", 0));
+	failure("Trailing '/./' is still the same directory.");
+	assertEqualInt(1, archive_pathmatch("./abc/./def", "abc/def/./", 0));
+	failure("Trailing '/.' is still the same directory.");
+	assertEqualInt(1, archive_pathmatch("./abc*/./def", "abc/def/.", 0));
+
+	/* Matches not anchored at beginning. */
+	assertEqualInt(0,
+	    archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
+	assertEqualInt(1,
+	    archive_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
+	assertEqualInt(0,
+	    archive_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
+	assertEqualInt(1,
+	    archive_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
+	assertEqualInt(0,
+	    archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
+	assertEqualInt(0,
+	    archive_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
+
+	/* Matches not anchored at end. */
+	assertEqualInt(0,
+	    archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(0,
+	    archive_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(0,
+	    archive_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(0,
+	    archive_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(1,
+	    archive_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
+	assertEqualInt(0,
+	    archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_archive_string_conversion.c
--- a/head/contrib/libarchive/libarchive/test/test_archive_string_conversio=
n.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_archive_string_conversio=
n.c	Fri Aug 10 14:19:25 2012 +0300
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2011 Michihiro NAKAJIMA
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
 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
+# This requires http://unicode.org/Public/6.0.0/ucd/NormalizationTest.txt
 #
 if=3D"NormalizationTest.txt"
 if [ ! -f ${if} ]; then
@@ -158,7 +158,7 @@
  */
 static int
 scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le,
-    const char *pattern, int exclude_mac_nfd)
+    const char *pattern, int mac_nfd)
 {
 	unsigned uc =3D 0;
 	const char *p =3D pattern;
@@ -166,6 +166,7 @@
 	wchar_t *owp =3D wout;
 	char *op16be =3D u16be;
 	char *op16le =3D u16le;
+	int ret =3D 0;
=20
 	for (;;) {
 		if (*p >=3D '0' && *p <=3D '9')
@@ -173,14 +174,31 @@
 		else if (*p >=3D 'A' && *p <=3D 'F')
 			uc =3D (uc << 4) + (*p - 'A' + 0x0a);
 		else {
-			if (exclude_mac_nfd) {
+			if (mac_nfd && op =3D=3D out) {
 				/*
 				 * These are not converted to NFD on Mac OS.
+ 				 * U+2000 - U+2FFF
+				 * U+F900 - U+FAFF
+				 * U+2F800 - U+2FAFF
 				 */
-				if ((uc >=3D 0x2000 && uc <=3D 0x2FFF) ||
-				    (uc >=3D 0xF900 && uc <=3D 0xFAFF) ||
-				    (uc >=3D 0x2F800 && uc <=3D 0x2FAFF))
-					return (-1);
+				switch (uc) {
+				case 0x2194: case 0x219A: case 0x219B:
+				case 0x21AE: case 0x21CD: case 0x21CE:
+				case 0x21CF: case 0x2204: case 0x2209:
+				case 0x220C: case 0x2224: case 0x2226:
+				case 0x2241: case 0x2244: case 0x2247:
+				case 0x2249: case 0x2260: case 0x2262:
+				case 0x226D: case 0x226E: case 0x226F:
+				case 0x2270: case 0x2271: case 0x2274:
+				case 0x2275: case 0x2276: case 0x2278:
+				case 0x2279: case 0x227A: case 0x227B:
+				case 0x2280: case 0x2281: case 0x2284:
+				case 0x2285: case 0x2288: case 0x2289:
+				case 0x22AC: case 0x22AD: case 0x22AE:
+				case 0x22AF: case 0x22E0: case 0x22E1:
+				case 0x22E2: case 0x22E3: case 0x22EA:
+				case 0x22EB: case 0x22EC: case 0x22ED:
+			=09
 				/*
 				 * Those code points are not converted to
 				 * NFD on Mac OS. I do not know the reason
@@ -190,9 +208,10 @@
 				 *   1109C  =3D=3D> 1109B 110BA
 				 *   110AB  =3D=3D> 110A5 110BA
 				 */
-				if (uc =3D=3D 0x1109A || uc =3D=3D 0x1109C ||
-				    uc =3D=3D 0x110AB)
-					return (-1);
+				case 0x1109A: case 0x1109C: case 0x110AB:
+					ret =3D 1;
+					break;
+				}
 			}
 			op16be +=3D unicode_to_utf16be(op16be, uc);
 			op16le +=3D unicode_to_utf16le(op16le, uc);
@@ -211,7 +230,7 @@
 		}
 		p++;
 	}
-	return (0);
+	return (ret);
 }
=20
 static int
@@ -230,27 +249,26 @@
  * On other platforms, the characters to be Form C.
  */
 static void
-test_archive_string_normalization(void)
+test_archive_string_normalization_nfc(const char *testdata)
 {
 	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[] =3D "test_archive_string_conversion.txt.Z";
-	ssize_t size;
 	int line =3D 0;
 	int locale_is_utf8, wc_is_unicode;
+	int sconv_opt =3D SCONV_SET_OPT_NORMALIZATION_C;
=20
 	locale_is_utf8 =3D (NULL !=3D setlocale(LC_ALL, "en_US.UTF-8"));
 	wc_is_unicode =3D 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");
+		skipping("A test of string normalization for NFC requires "
+		    "a suitable locale; en_US.UTF-8 not available on this "
+		    "system");
 		return;
 	}
=20
@@ -258,27 +276,9 @@
 	memset(&mstr, 0, sizeof(mstr));
=20
 	/*
-	 * Extract a test pattern file.
-	 */
-	extract_reference_file(reffile);
-	assert((a =3D archive_read_new()) !=3D 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 =3D fopen("testdata.txt", "w")) !=3D NULL);
-	while ((size =3D archive_read_data(a, buff, 512)) > 0)
-		fwrite(buff, 1, size, fp);
-	fclose(fp);
-
-	/* Open a test pattern file. */
-	assert((fp =3D fopen("testdata.txt", "r")) !=3D NULL);
-
-	/*
 	 * Create string conversion objects.
 	 */
+	assert((a =3D archive_read_new()) !=3D NULL);
 	assertA(NULL !=3D (f_sconv8 =3D
 	    archive_string_conversion_from_charset(a, "UTF-8", 0)));
 	assertA(NULL !=3D (f_sconv16be =3D
@@ -289,13 +289,18 @@
 	assertA(NULL !=3D (t_sconv8 =3D
 	    archive_string_conversion_to_charset(a2, "UTF-8", 0)));
 	if (f_sconv8 =3D=3D NULL || f_sconv16be =3D=3D NULL || f_sconv16le =3D=3D=
 NULL ||
-	    t_sconv8 =3D=3D NULL || fp =3D=3D NULL) {
+	    t_sconv8 =3D=3D NULL) {
 		/* We cannot continue this test. */
-		if (fp !=3D NULL)
-			fclose(fp);
 		assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 		return;
 	}
+	archive_string_conversion_set_opt(f_sconv8, sconv_opt);
+	archive_string_conversion_set_opt(f_sconv16be, sconv_opt);
+	archive_string_conversion_set_opt(f_sconv16le, sconv_opt);
+	archive_string_conversion_set_opt(t_sconv8, sconv_opt);
+
+	/* Open a test pattern file. */
+	assert((fp =3D fopen(testdata, "r")) !=3D NULL);
=20
 	/*
 	 * Read test data.
@@ -311,6 +316,9 @@
 		char utf16le_nfc[80], utf16le_nfd[80];
 		wchar_t wc_nfc[40], wc_nfd[40];
 		char *e, *p;
+		const wchar_t *wp;
+		const char *mp;
+		size_t mplen;
=20
 		line++;
 		if (buff[0] =3D=3D '#')
@@ -332,74 +340,22 @@
 		nfd[sizeof(nfd)-1] =3D '\0';
=20
 		/*
-		 * Convert an NFC pattern to UTF-8 bytes.
+		 * Get an NFC patterns.
 		 */
-#if defined(__APPLE__)
-		if (scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc,
-		    nfc, 1) !=3D 0)
-			continue;
-#else
 		scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc,
 		    nfc, 0);
-#endif
=20
 		/*
-		 * Convert an NFD pattern to UTF-8 bytes.
+		 * Get an NFD patterns.
 		 */
 		scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd,
 		    nfd, 0);
=20
 		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(
+			assertEqualInt(0, archive_strcpy_l(
 			    &utf8, utf8_nfd, f_sconv8));
 			failure("NFD(%s) should be converted to NFC(%s):%d",
 			    nfd, nfc, line);
@@ -408,7 +364,7 @@
 			/*
 			 * Normalize an NFC string for import.
 			 */
-			assertEqualInt(0, archive_strcpy_in_locale(
+			assertEqualInt(0, archive_strcpy_l(
 			    &utf8, utf8_nfc, f_sconv8));
 			failure("NFC(%s) should not be any changed:%d",
 			    nfc, line);
@@ -417,7 +373,7 @@
 			/*
 			 * Copy an NFC string for export.
 			 */
-			assertEqualInt(0, archive_strcpy_in_locale(
+			assertEqualInt(0, archive_strcpy_l(
 			    &utf8, utf8_nfc, t_sconv8));
 			failure("NFC(%s) should not be any changed:%d",
 			    nfc, line);
@@ -426,7 +382,7 @@
 			/*
 			 * Normalize an NFD string in UTF-16BE for import.
 			 */
-			assertEqualInt(0, archive_strncpy_in_locale(
+			assertEqualInt(0, archive_strncpy_l(
 			    &utf8, utf16be_nfd, 100000, f_sconv16be));
 			failure("NFD(%s) should be converted to NFC(%s):%d",
 			    nfd, nfc, line);
@@ -435,12 +391,11 @@
 			/*
 			 * Normalize an NFD string in UTF-16LE for import.
 			 */
-			assertEqualInt(0, archive_strncpy_in_locale(
+			assertEqualInt(0, archive_strncpy_l(
 			    &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
 		}
=20
 		/*
@@ -451,55 +406,6 @@
 		 * 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.
 			 */
@@ -536,14 +442,263 @@
 			/*
 			 * Copy an NFC wide-string for export.
 			 */
-			assertEqualInt(0, archive_mstring_copy_wcs(
-			    &mstr, wc_nfc));
+			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_normalization_mac_nfd(const char *testdata)
+{
+	struct archive *a, *a2;
+	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];
+	int line =3D 0;
+	int locale_is_utf8, wc_is_unicode;
+	int sconv_opt =3D SCONV_SET_OPT_NORMALIZATION_D;
+
+	locale_is_utf8 =3D (NULL !=3D setlocale(LC_ALL, "en_US.UTF-8"));
+	wc_is_unicode =3D is_wc_unicode();
+	/* If it doesn't exist, just warn and return. */
+	if (!locale_is_utf8 && !wc_is_unicode) {
+		skipping("A test of string normalization for NFD requires "
+		    "a suitable locale; en_US.UTF-8 not available on this "
+		    "system");
+		return;
+	}
+
+	archive_string_init(&utf8);
+	memset(&mstr, 0, sizeof(mstr));
+
+	/*
+	 * Create string conversion objects.
+	 */
+	assert((a =3D archive_read_new()) !=3D NULL);
+	assertA(NULL !=3D (f_sconv8 =3D
+	    archive_string_conversion_from_charset(a, "UTF-8", 0)));
+	assertA(NULL !=3D (f_sconv16be =3D
+	    archive_string_conversion_from_charset(a, "UTF-16BE", 0)));
+	assertA(NULL !=3D (f_sconv16le =3D
+	    archive_string_conversion_from_charset(a, "UTF-16LE", 0)));
+	assert((a2 =3D archive_write_new()) !=3D NULL);
+	assertA(NULL !=3D (t_sconv8 =3D
+	    archive_string_conversion_to_charset(a2, "UTF-8", 0)));
+	if (f_sconv8 =3D=3D NULL || f_sconv16be =3D=3D NULL || f_sconv16le =3D=3D=
 NULL ||
+	    t_sconv8 =3D=3D NULL) {
+		/* We cannot continue this test. */
+		assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+		return;
+	}
+	archive_string_conversion_set_opt(f_sconv8, sconv_opt);
+	archive_string_conversion_set_opt(f_sconv16be, sconv_opt);
+	archive_string_conversion_set_opt(f_sconv16le, sconv_opt);
+	archive_string_conversion_set_opt(t_sconv8, sconv_opt);
+
+	/* Open a test pattern file. */
+	assert((fp =3D fopen(testdata, "r")) !=3D NULL);
+
+	/*
+	 * 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) !=3D 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;
+		const wchar_t *wp;
+		const char *mp;
+		size_t mplen;
+		int should_be_nfc;
+
+		line++;
+		if (buff[0] =3D=3D '#')
+			continue;
+		p =3D strchr(buff, ';');
+		if (p =3D=3D NULL)
+			continue;
+		*p++ =3D '\0';
+		/* Copy an NFC pattern */
+		strncpy(nfc, buff, sizeof(nfc)-1);
+		nfc[sizeof(nfc)-1] =3D '\0';
+		e =3D p;
+		p =3D strchr(p, '\n');
+		if (p =3D=3D NULL)
+			continue;
+		*p =3D '\0';
+		/* Copy an NFD pattern */
+		strncpy(nfd, e, sizeof(nfd)-1);
+		nfd[sizeof(nfd)-1] =3D '\0';
+
+		/*
+		 * Get an NFC patterns.
+		 */
+		should_be_nfc =3D scan_unicode_pattern(utf8_nfc, wc_nfc,
+			utf16be_nfc, utf16le_nfc, nfc, 1);
+
+		/*
+		 * Get an NFD patterns.
+		 */
+		scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd,
+		    nfd, 0);
+
+		if (locale_is_utf8) {
+			/*
+			 * Normalize an NFC string for import.
+			 */
+			assertEqualInt(0, archive_strcpy_l(
+			    &utf8, utf8_nfc, f_sconv8));
+			if (should_be_nfc) {
+				failure("NFC(%s) should not be converted to"
+				    " NFD(%s):%d", nfc, nfd, line);
+				assertEqualUTF8String(utf8_nfc, utf8.s);
+			} else {
+				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_l(
+			    &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_l(
+			    &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_l(
+			    &utf8, utf16be_nfc, 100000, f_sconv16be));
+			if (should_be_nfc) {
+				failure("NFC(%s) should not be converted to"
+				    " NFD(%s):%d", nfc, nfd, line);
+				assertEqualUTF8String(utf8_nfc, utf8.s);
+			} else {
+				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_l(
+			    &utf8, utf16le_nfc, 100000, f_sconv16le));
+			if (should_be_nfc) {
+				failure("NFC(%s) should not be converted to"
+				    " NFD(%s):%d", nfc, nfd, line);
+				assertEqualUTF8String(utf8_nfc, utf8.s);
+			} else {
+				failure("NFC(%s) should be converted to"
+				    " NFD(%s):%d", nfc, nfd, line);
+				assertEqualUTF8String(utf8_nfd, utf8.s);
+			}
+		}
+
+		/*
+		 * 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) {
+			/*
+			 * 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));
+			if (should_be_nfc) {
+				failure("UTF-8 NFC(%s) should not be converted "
+				    "to WCS NFD(%s):%d", nfc, nfd, line);
+				assertEqualWString(wc_nfc, wp);
+			} else {
+				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));
+			if (should_be_nfc) {
+				failure("UTF-16BE NFC(%s) should not be "
+				    "converted to WCS NFD(%s):%d",
+				    nfc, nfd, line);
+				assertEqualWString(wc_nfc, wp);
+			} else {
+				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));
+			if (should_be_nfc) {
+				failure("UTF-16LE NFC(%s) should not be "
+				    "converted to WCS NFD(%s):%d",
+				    nfc, nfd, line);
+				assertEqualWString(wc_nfc, wp);
+			} else {
+				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);
 		}
 	}
=20
@@ -624,6 +779,32 @@
=20
 DEFINE_TEST(test_archive_string_conversion)
 {
-	test_archive_string_normalization();
+	static const char reffile[] =3D "test_archive_string_conversion.txt.Z";
+	static const char testdata[] =3D "testdata.txt";
+	struct archive *a;
+	struct archive_entry *ae;
+	char buff[512];
+	ssize_t size;
+	FILE *fp;
+
+	/*
+	 * Extract a test pattern file.
+	 */
+	extract_reference_file(reffile);
+	assert((a =3D archive_read_new()) !=3D 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 =3D fopen(testdata, "w")) !=3D NULL);
+	while ((size =3D archive_read_data(a, buff, 512)) > 0)
+		fwrite(buff, 1, size, fp);
+	fclose(fp);
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+	test_archive_string_normalization_nfc(testdata);
+	test_archive_string_normalization_mac_nfd(testdata);
 	test_archive_string_canonicalization();
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_compat_zip.c
--- a/head/contrib/libarchive/libarchive/test/test_compat_zip.c	Mon Jul 30 =
11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_compat_zip.c	Fri Aug 10 =
14:19:25 2012 +0300
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_compat_zi=
p.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_compat_zi=
p.c 238856 2012-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_LIBZ
 static const int libz_enabled =3D 1;
@@ -238,19 +238,19 @@
 	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));
+	assertEqualInt(0666, archive_entry_perm(ae));
=20
 	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));
+	assertEqualInt(0666, archive_entry_perm(ae));
=20
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
 	assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_ent=
ry_pathname(ae));
 	assertEqualInt(1495, archive_entry_size(ae));
 	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
-	assertEqualInt(0777, archive_entry_perm(ae));
+	assertEqualInt(0666, 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. */
@@ -298,21 +298,21 @@
 	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));
+	assertEqualInt(0666, archive_entry_perm(ae));
=20
 	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));
+	assertEqualInt(0666, archive_entry_perm(ae));
=20
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
 	assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_ent=
ry_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));
+	assertEqualInt(0666, archive_entry_perm(ae));
=20
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
 	assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_p=
athname(ae));
@@ -420,7 +420,7 @@
 	for (i =3D 1; i < 1000; ++i) {
 		assert((a =3D archive_read_new()) !=3D 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, read_open_memory_minimal(a, p, s, i));
=20
 		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
 		assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_disk_directory_traversals.c
--- a/head/contrib/libarchive/libarchive/test/test_read_disk_directory_trav=
ersals.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_disk_directory_trav=
ersals.c	Fri Aug 10 14:19:25 2012 +0300
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,9 @@
 	size_t size;
 	int64_t offset;
 	int file_count;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	wchar_t *wcwd, *wp, *fullpath;
+#endif
=20
 	assertMakeDir("dir1", 0755);
 	assertMakeFile("dir1/file1", 0644, "0123456789");
@@ -89,6 +92,7 @@
 		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
 		if (strcmp(archive_entry_pathname(ae), "dir1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/file1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -102,6 +106,7 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/file2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -115,9 +120,11 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 11);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub1/file1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -131,9 +138,11 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2/file1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -147,6 +156,7 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2/file2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -160,15 +170,19 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2/sub1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2/sub2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2/sub3") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (strcmp(archive_entry_pathname(ae),
 		    "dir1/sub2/sub3/file") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -182,6 +196,7 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 3);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		}
 		if (archive_entry_filetype(ae) =3D=3D AE_IFDIR) {
 			/* Descend into the current object */
@@ -205,6 +220,7 @@
 		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
 		if (wcscmp(archive_entry_pathname_w(ae), L"dir1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/file1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -218,6 +234,7 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/file2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -231,9 +248,11 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 11);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub1/file1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -247,9 +266,11 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2/file1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -263,6 +284,7 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2/file2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -276,15 +298,19 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 10);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2/sub1") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2/sub2") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2/sub3") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+			assertEqualInt(1, archive_read_disk_can_descend(a));
 		} else if (wcscmp(archive_entry_pathname_w(ae),
 		    L"dir1/sub2/sub3/file") =3D=3D 0) {
 			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
@@ -298,6 +324,7 @@
 			    archive_read_data_block(a, &p, &size, &offset));
 			assertEqualInt((int)size, 0);
 			assertEqualInt((int)offset, 3);
+			assertEqualInt(0, archive_read_disk_can_descend(a));
 		}
 		if (archive_entry_filetype(ae) =3D=3D AE_IFDIR) {
 			/* Descend into the current object */
@@ -318,6 +345,7 @@
=20
 	/* dir1/file1 */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(0, archive_read_disk_can_descend(a));
 	assertEqualString(archive_entry_pathname(ae), "dir1/file1");
 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
 	assertEqualInt(archive_entry_size(ae), 10);
@@ -342,6 +370,7 @@
=20
 	/* dir1/file1 */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(0, archive_read_disk_can_descend(a));
 	assertEqualString(archive_entry_pathname(ae), "dir1/file1");
 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
 	assertEqualInt(archive_entry_size(ae), 10);
@@ -353,6 +382,7 @@
=20
 	/* dir1/sub1 */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(1, archive_read_disk_can_descend(a));
 	assertEqualString(archive_entry_pathname(ae), "dir1/sub1");
 	assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
=20
@@ -361,6 +391,7 @@
=20
 	/* dir1/sub1/file1 */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(0, archive_read_disk_can_descend(a));
 	assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1");
 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
 	assertEqualInt(archive_entry_size(ae), 10);
@@ -375,6 +406,96 @@
=20
 	/* Close the disk object. */
 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+	/*
+	 * Test for a full-path beginning with "//?/"
+	 */
+	wcwd =3D _wgetcwd(NULL, 0);
+	fullpath =3D malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32));
+	wcscpy(fullpath, L"//?/");
+	wcscat(fullpath, wcwd);
+	wcscat(fullpath, L"/dir1/file1");
+	free(wcwd);
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath));
+	while ((wcwd =3D wcschr(fullpath, L'\\')) !=3D NULL)
+		*wcwd =3D L'/';
+
+	/* dir1/file1 */
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(0, archive_read_disk_can_descend(a));
+	assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+	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));
+	free(fullpath);
+
+	/*
+	 * Test for wild card '*' or '?' with "//?/" prefix.
+	 */
+	wcwd =3D _wgetcwd(NULL, 0);
+	fullpath =3D malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32));
+	wcscpy(fullpath, L"//?/");
+	wcscat(fullpath, wcwd);
+	wcscat(fullpath, L"/dir1/*1");
+	free(wcwd);
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath));
+	while ((wcwd =3D wcschr(fullpath, L'\\')) !=3D NULL)
+		*wcwd =3D L'/';
+
+	/* dir1/file1 */
+	wp =3D wcsrchr(fullpath, L'/');
+	wcscpy(wp+1, L"file1");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(0, archive_read_disk_can_descend(a));
+	assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+	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 */
+	wcscpy(wp+1, L"sub1");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(1, archive_read_disk_can_descend(a));
+	assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+	assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+
+	/* Descend into the current object */
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
+
+	/* dir1/sub1/file1 */
+	wcscpy(wp+1, L"sub1/file1");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+	assertEqualInt(0, archive_read_disk_can_descend(a));
+	assertEqualWString(archive_entry_pathname_w(ae), fullpath);
+	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));
+	free(fullpath);
+
 #endif
=20
 	/*
@@ -969,11 +1090,13 @@
 	failure("There must be no entry");
 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
=20
-	failure("Atime must not be restored");
+	failure("Atime should be restored");
 	assertFileAtimeRecent("at");
+	failure("Atime should be restored");
 	assertFileAtimeRecent("at/f1");
+	failure("Atime should be restored");
 	assertFileAtimeRecent("at/f2");
-	failure("The atime of a empty file must not be changed");
+	failure("The atime of a empty file should not be changed");
 	assertFileAtime("at/fe", 886611, 0);
=20
 	/* Close the disk object. */
@@ -1033,13 +1156,403 @@
 	failure("There must be no entry");
 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
=20
-	failure("Atime must be restored");
+	failure("Atime should be restored");
 	assertFileAtime("at", 886622, 0);
+	failure("Atime should be restored");
 	assertFileAtime("at/f1", 886600, 0);
+	failure("Atime should be restored");
 	assertFileAtime("at/f2", 886611, 0);
-	failure("The atime of a empty file must not be changed");
+	failure("The atime of a empty file should not be changed");
 	assertFileAtime("at/fe", 886611, 0);
=20
+	/* Close the disk object. */
+	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+	/*
+	 * Test3: Traversals with archive_read_disk_set_atime_restored() but
+	 * no data read as a listing.
+	 */
+	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 =3D 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") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+		} else if (strcmp(archive_entry_pathname(ae), "at/f1") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 10);
+		} else if (strcmp(archive_entry_pathname(ae), "at/f2") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 11);
+		} else if (strcmp(archive_entry_pathname(ae), "at/fe") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 0);
+		}
+		if (archive_entry_filetype(ae) =3D=3D 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 should be restored");
+	assertFileAtime("at", 886622, 0);
+	failure("Atime should be restored");
+	assertFileAtime("at/f1", 886600, 0);
+	failure("Atime should be restored");
+	assertFileAtime("at/f2", 886611, 0);
+	failure("The atime of a empty file should not be changed");
+	assertFileAtime("at/fe", 886611, 0);
+
+	if (!canNodump()) {
+		/* Destroy the disk object. */
+		assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+		archive_entry_free(ae);
+		skipping("Can't test atime with nodump on this filesystem");
+		return;
+	}
+
+	/* Close the disk object. */
+	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+	/*
+	 * Test4: Traversals with archive_read_disk_set_atime_restored() and
+	 * archive_read_disk_honor_nodump().
+	 */
+	assertNodump("at/f1");
+	assertNodump("at/f2");
+	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 =3D 2;
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a,
+		ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP));
+	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") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+		} else if (strcmp(archive_entry_pathname(ae), "at/fe") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 0);
+		}
+		if (archive_entry_filetype(ae) =3D=3D 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 should be restored");
+	assertFileAtime("at", 886622, 0);
+	failure("Atime should be restored");
+	assertFileAtime("at/f1", 886600, 0);
+	failure("Atime should be restored");
+	assertFileAtime("at/f2", 886611, 0);
+	failure("The atime of a empty file should not be changed");
+	assertFileAtime("at/fe", 886611, 0);
+
+	/* Destroy the disk object. */
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+	archive_entry_free(ae);
+}
+
+static int
+metadata_filter(struct archive *a, void *data, struct archive_entry *ae)
+{
+	(void)data; /* UNUSED */
+
+	failure("CTime should be set");
+	assertEqualInt(8, archive_entry_ctime_is_set(ae));
+	failure("MTime should be set");
+	assertEqualInt(16, archive_entry_mtime_is_set(ae));
+
+	if (archive_entry_mtime(ae) < 886611)
+		return (0);
+	if (archive_read_disk_can_descend(a)) {
+		/* Descend into the current object */
+		failure("archive_read_disk_can_descend should work"
+			" in metadata filter");
+		assertEqualIntA(a, 1, archive_read_disk_can_descend(a));
+		failure("archive_read_disk_descend should work"
+			" in metadata filter");
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
+	}
+	return (1);
+}
+
+static void
+test_callbacks(void)
+{
+	struct archive *a;
+	struct archive *m;
+	struct archive_entry *ae;
+	const void *p;
+	size_t size;
+	int64_t offset;
+	int file_count;
+
+	assertMakeDir("cb", 0755);
+	assertMakeFile("cb/f1", 0644, "0123456789");
+	assertMakeFile("cb/f2", 0644, "hello world");
+	assertMakeFile("cb/fe", 0644, NULL);
+	assertUtimes("cb/f1", 886600, 0, 886600, 0);
+	assertUtimes("cb/f2", 886611, 0, 886611, 0);
+	assertUtimes("cb/fe", 886611, 0, 886611, 0);
+	assertUtimes("cb", 886622, 0, 886622, 0);
+
+	assert((ae =3D archive_entry_new()) !=3D NULL);
+	if (assert((a =3D archive_read_disk_new()) !=3D NULL)) {
+		archive_entry_free(ae);
+		return;
+	}
+	if (assert((m =3D archive_match_new()) !=3D NULL)) {
+		archive_entry_free(ae);
+		archive_read_free(a);
+		return;
+	}
+
+	/*
+	 * Test1: Traversals with a name filter.
+	 */
+	file_count =3D 3;
+	assertEqualIntA(m, ARCHIVE_OK,
+	    archive_match_exclude_pattern(m, "cb/f2"));
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_set_matching(a, m, NULL, NULL));
+	failure("Directory traversals should work as well");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb"));
+	while (file_count--) {
+		archive_entry_clear(ae);
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+		failure("File 'cb/f2' should be exclueded");
+		assert(strcmp(archive_entry_pathname(ae), "cb/f2") !=3D 0);
+		if (strcmp(archive_entry_pathname(ae), "cb") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+		} else if (strcmp(archive_entry_pathname(ae), "cb/f1") =3D=3D 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), "cb/fe") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 0);
+		}
+		if (archive_read_disk_can_descend(a)) {
+			/* Descend into the current object */
+			assertEqualIntA(a, ARCHIVE_OK,
+			    archive_read_disk_descend(a));
+		}
+	}
+	/* There is no entry. */
+	failure("There should be no entry");
+	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+	/* Close the disk object. */
+	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+	/*
+	 * Test2: Traversals with a metadata filter.
+	 */
+	assertUtimes("cb/f1", 886600, 0, 886600, 0);
+	assertUtimes("cb/f2", 886611, 0, 886611, 0);
+	assertUtimes("cb/fe", 886611, 0, 886611, 0);
+	assertUtimes("cb", 886622, 0, 886622, 0);
+	file_count =3D 3;
+	assertEqualIntA(a, ARCHIVE_OK,
+	    archive_read_disk_set_metadata_filter_callback(a, metadata_filter,
+		    NULL));
+	failure("Directory traversals should work as well");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb"));
+
+	while (file_count--) {
+		archive_entry_clear(ae);
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+		failure("File 'cb/f1' should be exclueded");
+		assert(strcmp(archive_entry_pathname(ae), "cb/f1") !=3D 0);
+		if (strcmp(archive_entry_pathname(ae), "cb") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+		} else if (strcmp(archive_entry_pathname(ae), "cb/f2") =3D=3D 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), "cb/fe") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 0);
+		}
+	}
+	/* There is no entry. */
+	failure("There should be no entry");
+	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+	/* Destroy the disk object. */
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+	assertEqualInt(ARCHIVE_OK, archive_match_free(m));
+	archive_entry_free(ae);
+}
+
+static void
+test_nodump(void)
+{
+	struct archive *a;
+	struct archive_entry *ae;
+	const void *p;
+	size_t size;
+	int64_t offset;
+	int file_count;
+
+	if (!canNodump()) {
+		skipping("Can't test nodump on this filesystem");
+		return;
+	}
+
+	assertMakeDir("nd", 0755);
+	assertMakeFile("nd/f1", 0644, "0123456789");
+	assertMakeFile("nd/f2", 0644, "hello world");
+	assertMakeFile("nd/fe", 0644, NULL);
+	assertNodump("nd/f2");
+	assertUtimes("nd/f1", 886600, 0, 886600, 0);
+	assertUtimes("nd/f2", 886611, 0, 886611, 0);
+	assertUtimes("nd/fe", 886611, 0, 886611, 0);
+	assertUtimes("nd", 886622, 0, 886622, 0);
+
+	assert((ae =3D archive_entry_new()) !=3D NULL);
+	assert((a =3D archive_read_disk_new()) !=3D NULL);
+
+	/*
+	 * Test1: Traversals without archive_read_disk_honor_nodump().
+	 */
+	failure("Directory traversals should work as well");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd"));
+
+	file_count =3D 4;
+	while (file_count--) {
+		archive_entry_clear(ae);
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+		if (strcmp(archive_entry_pathname(ae), "nd") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+		} else if (strcmp(archive_entry_pathname(ae), "nd/f1") =3D=3D 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), "nd/f2") =3D=3D 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), "nd/fe") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 0);
+		}
+		if (archive_read_disk_can_descend(a)) {
+			/* Descend into the current object */
+			assertEqualIntA(a, ARCHIVE_OK,
+			    archive_read_disk_descend(a));
+		}
+	}
+	/* There is no entry. */
+	failure("There should be no entry");
+	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+	/* Close the disk object. */
+	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+	/*
+	 * Test2: Traversals with archive_read_disk_honor_nodump().
+	 */
+	assertUtimes("nd/f1", 886600, 0, 886600, 0);
+	assertUtimes("nd/f2", 886611, 0, 886611, 0);
+	assertUtimes("nd/fe", 886611, 0, 886611, 0);
+	assertUtimes("nd", 886622, 0, 886622, 0);
+
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a,
+		ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP));
+	failure("Directory traversals should work as well");
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd"));
+
+	file_count =3D 3;
+	while (file_count--) {
+		archive_entry_clear(ae);
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+		failure("File 'nd/f2' should be exclueded");
+		assert(strcmp(archive_entry_pathname(ae), "nd/f2") !=3D 0);
+		if (strcmp(archive_entry_pathname(ae), "nd") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+		} else if (strcmp(archive_entry_pathname(ae), "nd/f1") =3D=3D 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), "nd/fe") =3D=3D 0) {
+			assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+			assertEqualInt(archive_entry_size(ae), 0);
+		}
+		if (archive_read_disk_can_descend(a)) {
+			/* Descend into the current object */
+			assertEqualIntA(a, ARCHIVE_OK,
+			    archive_read_disk_descend(a));
+		}
+	}
+	/* There is no entry. */
+	failure("There should be no entry");
+	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+	failure("Atime should be restored");
+	assertFileAtime("nd/f2", 886611, 0);
+
 	/* Destroy the disk object. */
 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 	archive_entry_free(ae);
@@ -1057,4 +1570,8 @@
 	test_symlink_logical_loop();
 	/* Test to restore atime. */
 	test_restore_atime();
+	/* Test callbacks. */
+	test_callbacks();
+	/* Test nodump. */
+	test_nodump();
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_7zip.c
--- a/head/contrib/libarchive/libarchive/test/test_read_format_7zip.c	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_7zip.c	Fri A=
ug 10 14:19:25 2012 +0300
@@ -26,8 +26,8 @@
 __FBSDID("$FreeBSD");
=20
 /*
- * Extract a non-encorded file.
- * The header of the 7z archive files is not encdoed.
+ * Extract a non-encoded file.
+ * The header of the 7z archive files is not encoded.
  */
 static void
 test_copy()
@@ -46,7 +46,7 @@
=20
 	/* Verify regular file1. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-	assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+	assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
 	assertEqualString("file1", archive_entry_pathname(ae));
 	assertEqualInt(86401, archive_entry_mtime(ae));
 	assertEqualInt(60, archive_entry_size(ae));
@@ -139,7 +139,7 @@
=20
 /*
  * Extract an encoded file.
- * The header of the 7z archive files is not encdoed.
+ * The header of the 7z archive files is not encoded.
  */
 static void
 test_plain_header(const char *refname)
@@ -180,7 +180,7 @@
=20
 /*
  * Extract multi files.
- * The header of the 7z archive files is encdoed with LZMA.
+ * The header of the 7z archive files is encoded with LZMA.
  */
 static void
 test_extract_all_files(const char *refname)
@@ -255,7 +255,7 @@
=20
 /*
  * Extract last file.
- * The header of the 7z archive files is encdoed with LZMA.
+ * The header of the 7z archive files is encoded with LZMA.
  */
 static void
 test_extract_last_file(const char *refname)
@@ -323,7 +323,7 @@
 }
=20
 /*
- * Extract a mixed archive file which has both  LZMA and LZMA2 encoded fil=
es.
+ * Extract a mixed archive file which has both LZMA and LZMA2 encoded file=
s.
  *  LZMA: file1, file2, file3, file4
  *  LZMA2: zfile1, zfile2, zfile3, zfile4
  */
@@ -510,7 +510,7 @@
=20
 	/* Verify regular x86exe. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-	assertEqualInt((AE_IFREG | 0555), archive_entry_mode(ae));
+	assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae) & ~0111);
 	assertEqualString("x86exe", archive_entry_pathname(ae));
 	assertEqualInt(172802, archive_entry_mtime(ae));
 	assertEqualInt(27328, archive_entry_size(ae));
@@ -565,7 +565,7 @@
=20
 	/* Verify regular file1. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-	assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+	assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
 	assertEqualString("ppmd_test.txt", archive_entry_pathname(ae));
 	assertEqualInt(1322464589, archive_entry_mtime(ae));
 	assertEqualInt(102400, archive_entry_size(ae));
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_cab.c
--- a/head/contrib/libarchive/libarchive/test/test_read_format_cab.c	Mon Ju=
l 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_cab.c	Fri Au=
g 10 14:19:25 2012 +0300
@@ -199,7 +199,7 @@
=20
 	/* Verify regular empty. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-	assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+	assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
 	assertEqualString("empty", archive_entry_pathname(ae));
 	assertEqualInt(0, archive_entry_uid(ae));
 	assertEqualInt(0, archive_entry_gid(ae));
@@ -211,7 +211,7 @@
 		 * 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));
+		assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
 		assertEqualString("zero", archive_entry_pathname(ae));
 		assertEqualInt(0, archive_entry_uid(ae));
 		assertEqualInt(0, archive_entry_gid(ae));
@@ -232,7 +232,7 @@
=20
 	/* Verify regular file1. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-	assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+	assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
 	assertEqualString("dir1/file1", archive_entry_pathname(ae));
 	assertEqualInt(0, archive_entry_uid(ae));
 	assertEqualInt(0, archive_entry_gid(ae));
@@ -242,7 +242,7 @@
=20
 	/* Verify regular file2. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-	assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+	assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
 	assertEqualString("dir2/file2", archive_entry_pathname(ae));
 	assertEqualInt(0, archive_entry_uid(ae));
 	assertEqualInt(0, archive_entry_gid(ae));
@@ -269,13 +269,121 @@
 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 }
=20
+/*
+ * Skip beginning files and Read the last file.
+ */
+static void
+verify2(const char *refname, enum comp_type comp)
+{
+	struct archive_entry *ae;
+	struct archive *a;
+	char buff[128];
+	char zero[128];
+
+	memset(zero, 0, sizeof(zero));
+	extract_reference_file(refname);
+	assert((a =3D archive_read_new()) !=3D 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));
+	if (comp !=3D STORE) {
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+	}
+	/* Verify regular file1. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+	/* Verify regular file2. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+	assertEqualInt((AE_IFREG | 0666), 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 !=3D 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. */
+	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Skip all file like 'bsdtar tvf foo.cab'.
+ */
+static void
+verify3(const char *refname, enum comp_type comp)
+{
+	struct archive_entry *ae;
+	struct archive *a;
+	char zero[128];
+
+	memset(zero, 0, sizeof(zero));
+	extract_reference_file(refname);
+	assert((a =3D archive_read_new()) !=3D 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));
+	if (comp !=3D STORE) {
+		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+	}
+	/* Verify regular file1. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+	/* Verify regular file2. */
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+	/* End of archive. */
+	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+	if (comp !=3D 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. */
+	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);
+	verify2("test_read_format_cab_1.cab", STORE);
+	verify3("test_read_format_cab_1.cab", STORE);
 	/* Verify Cabinet file in MSZIP. */
 	verify("test_read_format_cab_2.cab", MSZIP);
+	verify2("test_read_format_cab_2.cab", MSZIP);
+	verify3("test_read_format_cab_2.cab", MSZIP);
 	/* Verify Cabinet file in LZX. */
 	verify("test_read_format_cab_3.cab", LZX);
+	verify2("test_read_format_cab_3.cab", LZX);
+	verify3("test_read_format_cab_3.cab", LZX);
 }
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_cpio_svr4_bzip2_rpm.c
--- a/head/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bz=
ip2_rpm.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bz=
ip2_rpm.c	Fri Aug 10 14:19:25 2012 +0300
@@ -51,7 +51,7 @@
 Version: 1.0.0
 Release: 1
 License: BSD
-URL: http://code.google.com/p/libarchive
+URL: http://libarchive.github.com/
 BuildArch: noarch
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_cpio_svr4_gzip_rpm.c
--- a/head/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gz=
ip_rpm.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gz=
ip_rpm.c	Fri Aug 10 14:19:25 2012 +0300
@@ -51,7 +51,7 @@
 Version: 1.0.0
 Release: 1
 License: BSD
-URL: http://code.google.com/p/libarchive
+URL: http://libarchive.github.com/
 BuildArch: noarch
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_rar.c
--- a/head/contrib/libarchive/libarchive/test/test_read_format_rar.c	Mon Ju=
l 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_rar.c	Fri Au=
g 10 14:19:25 2012 +0300
@@ -1,6 +1,7 @@
 /*-
  * Copyright (c) 2003-2007 Tim Kientzle
  * Copyright (c) 2011 Andres Mejia
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -278,9 +279,19 @@
   assertEqualInt(41453, archive_entry_mode(ae));
   assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
=20
+  /* Sixth header */
+  assertA(0 =3D=3D archive_read_next_header(a, &ae));
+  assertEqualUTF8String(
+    "abcdefghijklmnopqrs\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88.txt",
+    archive_entry_pathname(ae));
+  assertA((int)archive_entry_mtime(ae));
+  assertEqualInt(16, archive_entry_size(ae));
+  assertEqualInt(33204, archive_entry_mode(ae));
+  assertEqualIntA(a, 16, archive_read_data(a, buff, sizeof(buff)));
+
   /* Test EOF */
   assertA(1 =3D=3D archive_read_next_header(a, &ae));
-  assertEqualInt(5, archive_file_count(a));
+  assertEqualInt(6, archive_file_count(a));
   assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
   assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 }
@@ -364,9 +375,19 @@
   assertEqualInt(41453, archive_entry_mode(ae));
   assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
=20
+  /* Sixth header */
+  assertA(0 =3D=3D archive_read_next_header(a, &ae));
+  assertEqualUTF8String(
+    "abcdefghijklmnopqrs\x83\x65\x83\x58\x83\x67.txt",
+    archive_entry_pathname(ae));
+  assertA((int)archive_entry_mtime(ae));
+  assertEqualInt(16, archive_entry_size(ae));
+  assertEqualInt(33204, archive_entry_mode(ae));
+  assertEqualIntA(a, 16, archive_read_data(a, buff, sizeof(buff)));
+
   /* Test EOF */
   assertA(1 =3D=3D archive_read_next_header(a, &ae));
-  assertEqualInt(5, archive_file_count(a));
+  assertEqualInt(6, archive_file_count(a));
   assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
   assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_rar_unicode.rar.uu
--- a/head/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.=
rar.uu	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.=
rar.uu	Fri Aug 10 14:19:25 2012 +0300
@@ -11,7 +11,8 @@
 M=3D."2,P````````````(`````#VGA/A0P#@`0````E5R"OH+F`(AH:&`PB#``
 M\.H)?ED.=3D"""2``V````-@````,E at OM=3D6%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=3D,0]>P!`
-"!P``
+ME>."H>."I..#J^60C6QO;F<M9FEL96YA;64M:6XMYKRBY:V7+G1X=3D)MJ=3D""`
+M0``/````$`````,%T+85W81G0!TS(`"T at 0``86)C9&5F9VAI:FML;6YO<'%R
+D<^.#AN."N>.#B"YT>'0`D/\0?^2Y_">#,#TN'-+$/7L`0`<`
 `
 end
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_format_tar_filename.c
--- a/head/contrib/libarchive/libarchive/test/test_read_format_tar_filename=
.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_format_tar_filename=
.c	Fri Aug 10 14:19:25 2012 +0300
@@ -34,7 +34,7 @@
  * - 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.
+ * filename of second file, which is stored in UTF-8 by default.
  */
=20
 static void
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_pax_truncated.c
--- a/head/contrib/libarchive/libarchive/test/test_read_pax_truncated.c	Mon=
 Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_pax_truncated.c	Fri=
 Aug 10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_read_pax_=
truncated.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_read_pax_=
truncated.c 238856 2012-07-28 06:38:44Z mm $");
=20
 DEFINE_TEST(test_read_pax_truncated)
 {
@@ -71,10 +71,10 @@
 		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));
+			assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory_minimal(a, buff, i, =
13));
 			goto wrap_up;
 		} else {
-			assertEqualIntA(a, ARCHIVE_OK, read_open_memory2(a, buff, i, 13));
+			assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, buff, i, 13)=
);
 		}
=20
 		/* If it's truncated in a header, the header read should fail. */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_read_position.c
--- a/head/contrib/libarchive/libarchive/test/test_read_position.c	Mon Jul =
30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_read_position.c	Fri Aug =
10 14:19:25 2012 +0300
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_read_posi=
tion.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_read_posi=
tion.c 238856 2012-07-28 06:38:44Z mm $");
=20
 static unsigned char nulls[1000];
 static unsigned char tmp[1000];
@@ -105,7 +105,7 @@
 	/* Read the archive back without a skip function. */
 	assert(NULL !=3D (a =3D archive_read_new()));
 	assertA(0 =3D=3D archive_read_support_format_tar(a));
-	assertA(0 =3D=3D read_open_memory2(a, buff, sizeof(buff), 512));
+	assertA(0 =3D=3D read_open_memory_minimal(a, buff, sizeof(buff), 512));
 	verify_read_positions(a);
 	archive_read_free(a);
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_sparse_basic.c
--- a/head/contrib/libarchive/libarchive/test/test_sparse_basic.c	Mon Jul 3=
0 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_sparse_basic.c	Fri Aug 1=
0 14:19:25 2012 +0300
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,6 @@
 #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
@@ -169,31 +166,12 @@
 		{ 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 =3D "can_sparse";
=20
 	(void)path; /* UNUSED */
-	memset(&ut, 0, sizeof(ut));
-	assertEqualInt(uname(&ut), 0);
-	p =3D ut.release;
-	d =3D strtol(p, &e, 10);
-	if (d < 2 || *e !=3D '.')
-		return (0);
-	if (d =3D=3D 2) {
-		p =3D e + 1;
-		d =3D strtol(p, &e, 10);
-		if (d < 6 || *e !=3D '.')
-			return (0);
-		p =3D e + 1;
-		d =3D strtol(p, NULL, 10);
-		if (d < 28)
-			return (0);
-	}
 	create_sparse_file(testfile, sparse_file);
 	fd =3D open(testfile,  O_RDWR);
 	if (fd < 0)
@@ -205,11 +183,9 @@
 	fm->fm_extent_count =3D (sizeof(buff) - sizeof(*fm))/
 		sizeof(struct fiemap_extent);
 	r =3D ioctl(fd, FS_IOC_FIEMAP, fm);
-	if (r < 0 && (errno =3D=3D ENOTTY || errno =3D=3D EOPNOTSUPP))
-		return (0);/* Not supported. */
 	close(fd);
 	unlink(testfile);
-	return (1);
+	return (r >=3D 0);
 }
=20
 #else
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive/tes=
t/test_write_format_zip.c
--- a/head/contrib/libarchive/libarchive/test/test_write_format_zip.c	Mon J=
ul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/libarchive/test/test_write_format_zip.c	Fri A=
ug 10 14:19:25 2012 +0300
@@ -29,7 +29,7 @@
  */
=20
 #include "test.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_write_for=
mat_zip.c 232153 2012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_write_for=
mat_zip.c 238856 2012-07-28 06:38:44Z mm $");
=20
 static void
 verify_contents(struct archive *a, int expect_details)
@@ -91,7 +91,7 @@
 		assertEqualInt(0, archive_entry_size(ae));
 		assertEqualString("file1", archive_entry_symlink(ae));
 	} else {
-		assertEqualInt(AE_IFREG | 0777, archive_entry_mode(ae));
+		assertEqualInt(AE_IFREG | 0666, archive_entry_mode(ae));
 		assertEqualInt(0, archive_entry_size(ae));
 	}
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive_fe/=
err.c
--- a/head/contrib/libarchive/libarchive_fe/err.c	Mon Jul 30 11:44:18 2012 =
+0300
+++ b/head/contrib/libarchive/libarchive_fe/err.c	Fri Aug 10 14:19:25 2012 =
+0300
@@ -25,7 +25,7 @@
  */
=20
 #include "lafe_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive_fe/err.c 228763 201=
1-12-21 11:13:29Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive_fe/err.c 238856 201=
2-07-28 06:38:44Z mm $");
=20
 #ifdef HAVE_STDARG_H
 #include <stdarg.h>
@@ -40,6 +40,8 @@
=20
 #include "err.h"
=20
+static void lafe_vwarnc(int, const char *, va_list) __LA_PRINTFLIKE(2, 0);
+
 const char *lafe_progname;
=20
 static void
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive_fe/=
err.h
--- a/head/contrib/libarchive/libarchive_fe/err.h	Mon Jul 30 11:44:18 2012 =
+0300
+++ b/head/contrib/libarchive/libarchive_fe/err.h	Fri Aug 10 14:19:25 2012 =
+0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/libarchive_fe/err.h 228774 2011-12-21=
 15:20:17Z mm $
+ * $FreeBSD: head/contrib/libarchive/libarchive_fe/err.h 238856 2012-07-28=
 06:38:44Z mm $
  */
=20
 #ifndef LAFE_ERR_H
@@ -35,9 +35,17 @@
 #define __LA_DEAD
 #endif
=20
+#if defined(__GNUC__) && (__GNUC__ > 2 || \
+			  (__GNUC__ =3D=3D 2 && __GNUC_MINOR__ >=3D 7))
+#define	__LA_PRINTFLIKE(f,a)	__attribute__((__format__(__printf__, f, a)))
+#else
+#define	__LA_PRINTFLIKE(f,a)
+#endif
+
 extern const char *lafe_progname;
=20
-void	lafe_warnc(int code, const char *fmt, ...);
-void	lafe_errc(int eval, int code, const char *fmt, ...) __LA_DEAD;
+void	lafe_warnc(int code, const char *fmt, ...) __LA_PRINTFLIKE(2, 3);
+void	lafe_errc(int eval, int code, const char *fmt, ...) __LA_DEAD
+		  __LA_PRINTFLIKE(3, 4);
=20
 #endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive_fe/=
matching.c
--- a/head/contrib/libarchive/libarchive_fe/matching.c	Mon Jul 30 11:44:18 =
2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +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 WARRANTI=
ES
- * 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 US=
E,
- * 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 "lafe_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive_fe/matching.c 23215=
3 2012-02-25 10:58:02Z mm $");
-
-#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 "err.h"
-#include "line_reader.h"
-#include "matching.h"
-#include "pathmatch.h"
-
-struct match {
-	struct match	 *next;
-	int		  matches;
-	char		  pattern[1];
-};
-
-struct lafe_matching {
-	struct match	 *exclusions;
-	int		  exclusions_count;
-	struct match	 *inclusions;
-	int		  inclusions_count;
-	int		  inclusions_unmatched_count;
-};
-
-static void	add_pattern(struct match **list, const char *pattern);
-static void	initialize_matching(struct lafe_matching **);
-static int	match_exclusion(struct match *, const char *pathname);
-static int	match_inclusion(struct match *, const char *pathname);
-
-/*
- * The matching logic here needs to be re-thought.  I started out to
- * try to mimic gtar's matching logic, but it's not entirely
- * consistent.  In particular 'tar -t' and 'tar -x' interpret patterns
- * on the command line as anchored, but --exclude doesn't.
- */
-
-/*
- * Utility functions to manage exclusion/inclusion patterns
- */
-
-int
-lafe_exclude(struct lafe_matching **matching, const char *pattern)
-{
-
-	if (*matching =3D=3D NULL)
-		initialize_matching(matching);
-	add_pattern(&((*matching)->exclusions), pattern);
-	(*matching)->exclusions_count++;
-	return (0);
-}
-
-int
-lafe_exclude_from_file(struct lafe_matching **matching, const char *pathna=
me)
-{
-	struct lafe_line_reader *lr;
-	const char *p;
-	int ret =3D 0;
-
-	lr =3D lafe_line_reader(pathname, 0);
-	while ((p =3D lafe_line_reader_next(lr)) !=3D NULL) {
-		if (lafe_exclude(matching, p) !=3D 0)
-			ret =3D -1;
-	}
-	lafe_line_reader_free(lr);
-	return (ret);
-}
-
-int
-lafe_include(struct lafe_matching **matching, const char *pattern)
-{
-
-	if (*matching =3D=3D NULL)
-		initialize_matching(matching);
-	add_pattern(&((*matching)->inclusions), pattern);
-	(*matching)->inclusions_count++;
-	(*matching)->inclusions_unmatched_count++;
-	return (0);
-}
-
-int
-lafe_include_from_file(struct lafe_matching **matching, const char *pathna=
me,
-    int nullSeparator)
-{
-	struct lafe_line_reader *lr;
-	const char *p;
-	int ret =3D 0;
-
-	lr =3D lafe_line_reader(pathname, nullSeparator);
-	while ((p =3D lafe_line_reader_next(lr)) !=3D NULL) {
-		if (lafe_include(matching, p) !=3D 0)
-			ret =3D -1;
-	}
-	lafe_line_reader_free(lr);
-	return (ret);
-}
-
-static void
-add_pattern(struct match **list, const char *pattern)
-{
-	struct match *match;
-	size_t len;
-
-	len =3D strlen(pattern);
-	match =3D malloc(sizeof(*match) + len + 1);
-	if (match =3D=3D NULL)
-		lafe_errc(1, errno, "Out of memory");
-	strcpy(match->pattern, pattern);
-	/* Both "foo/" and "foo" should match "foo/bar". */
-	if (len && match->pattern[len - 1] =3D=3D '/')
-		match->pattern[len - 1] =3D '\0';
-	match->next =3D *list;
-	*list =3D match;
-	match->matches =3D 0;
-}
-
-
-int
-lafe_excluded(struct lafe_matching *matching, const char *pathname)
-{
-	struct match *match;
-	struct match *matched;
-
-	if (matching =3D=3D 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 =3D NULL;
-	for (match =3D matching->inclusions; match !=3D NULL; match =3D match->ne=
xt){
-		if (match->matches =3D=3D 0
-		    && match_inclusion(match, pathname)) {
-			matching->inclusions_unmatched_count--;
-			match->matches++;
-			matched =3D match;
-		}
-	}
-
-	/* Exclusions take priority */
-	for (match =3D matching->exclusions; match !=3D NULL; match =3D match->ne=
xt){
-		if (match_exclusion(match, pathname))
-			return (1);
-	}
-
-	/* It's not excluded and we found an inclusion above, so it's included. */
-	if (matched !=3D NULL)
-		return (0);
-
-
-	/* We didn't find an unmatched inclusion, check the remaining ones. */
-	for (match =3D matching->inclusions; match !=3D NULL; match =3D match->ne=
xt){
-		/* We looked at previously-unmatched inclusions already. */
-		if (match->matches > 0
-		    && match_inclusion(match, pathname)) {
-			match->matches++;
-			return (0);
-		}
-	}
-
-	/* If there were inclusions, default is to exclude. */
-	if (matching->inclusions !=3D NULL)
-	    return (1);
-
-	/* No explicit inclusions, default is to match. */
-	return (0);
-}
-
-/*
- * This is a little odd, but it matches the default behavior of
- * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
- *
- */
-static int
-match_exclusion(struct match *match, const char *pathname)
-{
-	return (lafe_pathmatch(match->pattern,
-		    pathname,
-		    PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
-}
-
-/*
- * Again, mimic gtar:  inclusions are always anchored (have to match
- * the beginning of the path) even though exclusions are not anchored.
- */
-static int
-match_inclusion(struct match *match, const char *pathname)
-{
-	return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END)=
);
-}
-
-void
-lafe_cleanup_exclusions(struct lafe_matching **matching)
-{
-	struct match *p, *q;
-
-	if (*matching =3D=3D NULL)
-		return;
-
-	for (p =3D (*matching)->inclusions; p !=3D NULL; ) {
-		q =3D p;
-		p =3D p->next;
-		free(q);
-	}
-
-	for (p =3D (*matching)->exclusions; p !=3D NULL; ) {
-		q =3D p;
-		p =3D p->next;
-		free(q);
-	}
-
-	free(*matching);
-	*matching =3D NULL;
-}
-
-static void
-initialize_matching(struct lafe_matching **matching)
-{
-	*matching =3D calloc(sizeof(**matching), 1);
-	if (*matching =3D=3D NULL)
-		lafe_errc(1, errno, "No memory");
-}
-
-int
-lafe_unmatched_inclusions(struct lafe_matching *matching)
-{
-
-	if (matching =3D=3D NULL)
-		return (0);
-	return (matching->inclusions_unmatched_count);
-}
-
-int
-lafe_unmatched_inclusions_warn(struct lafe_matching *matching, const char =
*msg)
-{
-	struct match *p;
-
-	if (matching =3D=3D NULL)
-		return (0);
-
-	for (p =3D matching->inclusions; p !=3D NULL; p =3D p->next) {
-		if (p->matches =3D=3D 0)
-			lafe_warnc(0, "%s: %s", p->pattern, msg);
-	}
-
-	return (matching->inclusions_unmatched_count);
-}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive_fe/=
matching.h
--- a/head/contrib/libarchive/libarchive_fe/matching.h	Mon Jul 30 11:44:18 =
2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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
- *    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 WARRANTI=
ES
- * 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 US=
E,
- * 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/contrib/libarchive/libarchive_fe/matching.h 228763 2011-=
12-21 11:13:29Z mm $
- */
-
-#ifndef MATCHING_H
-#define MATCHING_H
-
-struct lafe_matching;
-
-int	lafe_exclude(struct lafe_matching **matching, const char *pattern);
-int	lafe_exclude_from_file(struct lafe_matching **matching,
-			       const char *pathname);
-int	lafe_include(struct lafe_matching **matching, const char *pattern);
-int	lafe_include_from_file(struct lafe_matching **matching,
-			       const char *pathname, int nullSeparator);
-
-int	lafe_excluded(struct lafe_matching *, const char *pathname);
-void	lafe_cleanup_exclusions(struct lafe_matching **);
-int	lafe_unmatched_inclusions(struct lafe_matching *);
-int	lafe_unmatched_inclusions_warn(struct lafe_matching *, const char *msg=
);
-
-#endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive_fe/=
pathmatch.c
--- a/head/contrib/libarchive/libarchive_fe/pathmatch.c	Mon Jul 30 11:44:18=
 2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,255 +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
- *    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 WARRANTI=
ES
- * 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 US=
E,
- * 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 "lafe_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive_fe/pathmatch.c 2321=
53 2012-02-25 10:58:02Z mm $");
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "pathmatch.h"
-
-/*
- * Check whether a character 'c' is matched by a list specification [...]:
- *    * Leading '!' or '^' negates the class.
- *    * <char>-<char> is a range of characters
- *    * \<char> removes any special meaning for <char>
- *
- * Some interesting boundary cases:
- *   a-d-e is one range (a-d) followed by two single characters - and e.
- *   \a-\d is same as a-d
- *   a\-d is three single characters: a, d, -
- *   Trailing - is not special (so [a-] is two characters a and -).
- *   Initial - is not special ([a-] is same as [-a] is same as [\\-a])
- *   This function never sees a trailing \.
- *   [] always fails
- *   [!] always succeeds
- */
-static int
-pm_list(const char *start, const char *end, const char c, int flags)
-{
-	const char *p =3D start;
-	char rangeStart =3D '\0', nextRangeStart;
-	int match =3D 1, nomatch =3D 0;
-
-	/* This will be used soon... */
-	(void)flags; /* UNUSED */
-
-	/* If this is a negated class, return success for nomatch. */
-	if ((*p =3D=3D '!' || *p =3D=3D '^') && p < end) {
-		match =3D 0;
-		nomatch =3D 1;
-		++p;
-	}
-
-	while (p < end) {
-		nextRangeStart =3D '\0';
-		switch (*p) {
-		case '-':
-			/* Trailing or initial '-' is not special. */
-			if ((rangeStart =3D=3D '\0') || (p =3D=3D end - 1)) {
-				if (*p =3D=3D c)
-					return (match);
-			} else {
-				char rangeEnd =3D *++p;
-				if (rangeEnd =3D=3D '\\')
-					rangeEnd =3D *++p;
-				if ((rangeStart <=3D c) && (c <=3D rangeEnd))
-					return (match);
-			}
-			break;
-		case '\\':
-			++p;
-			/* Fall through */
-		default:
-			if (*p =3D=3D c)
-				return (match);
-			nextRangeStart =3D *p; /* Possible start of range. */
-		}
-		rangeStart =3D nextRangeStart;
-		++p;
-	}
-	return (nomatch);
-}
-
-/*
- * If s is pointing to "./", ".//", "./././" or the like, skip it.
- */
-static const char *
-pm_slashskip(const char *s) {
-	while ((*s =3D=3D '/')
-	    || (s[0] =3D=3D '.' && s[1] =3D=3D '/')
-	    || (s[0] =3D=3D '.' && s[1] =3D=3D '\0'))
-		++s;
-	return (s);
-}
-
-static int
-pm(const char *p, const char *s, int flags)
-{
-	const char *end;
-
-	/*
-	 * Ignore leading './', './/', '././', etc.
-	 */
-	if (s[0] =3D=3D '.' && s[1] =3D=3D '/')
-		s =3D pm_slashskip(s + 1);
-	if (p[0] =3D=3D '.' && p[1] =3D=3D '/')
-		p =3D pm_slashskip(p + 1);
-
-	for (;;) {
-		switch (*p) {
-		case '\0':
-			if (s[0] =3D=3D '/') {
-				if (flags & PATHMATCH_NO_ANCHOR_END)
-					return (1);
-				/* "dir" =3D=3D "dir/" =3D=3D "dir/." */
-				s =3D pm_slashskip(s);
-			}
-			return (*s =3D=3D '\0');
-		case '?':
-			/* ? always succeeds, unless we hit end of 's' */
-			if (*s =3D=3D '\0')
-				return (0);
-			break;
-		case '*':
-			/* "*" =3D=3D "**" =3D=3D "***" ... */
-			while (*p =3D=3D '*')
-				++p;
-			/* Trailing '*' always succeeds. */
-			if (*p =3D=3D '\0')
-				return (1);
-			while (*s) {
-				if (lafe_pathmatch(p, s, flags))
-					return (1);
-				++s;
-			}
-			return (0);
-		case '[':
-			/*
-			 * Find the end of the [...] character class,
-			 * ignoring \] that might occur within the class.
-			 */
-			end =3D p + 1;
-			while (*end !=3D '\0' && *end !=3D ']') {
-				if (*end =3D=3D '\\' && end[1] !=3D '\0')
-					++end;
-				++end;
-			}
-			if (*end =3D=3D ']') {
-				/* We found [...], try to match it. */
-				if (!pm_list(p + 1, end, *s, flags))
-					return (0);
-				p =3D end; /* Jump to trailing ']' char. */
-				break;
-			} else
-				/* No final ']', so just match '['. */
-				if (*p !=3D *s)
-					return (0);
-			break;
-		case '\\':
-			/* Trailing '\\' matches itself. */
-			if (p[1] =3D=3D '\0') {
-				if (*s !=3D '\\')
-					return (0);
-			} else {
-				++p;
-				if (*p !=3D *s)
-					return (0);
-			}
-			break;
-		case '/':
-			if (*s !=3D '/' && *s !=3D '\0')
-				return (0);
-			/* Note: pattern "/\./" won't match "/";
-			 * pm_slashskip() correctly stops at backslash. */
-			p =3D pm_slashskip(p);
-			s =3D pm_slashskip(s);
-			if (*p =3D=3D '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
-				return (1);
-			--p; /* Counteract the increment below. */
-			--s;
-			break;
-		case '$':
-			/* '$' is special only at end of pattern and only
-			 * if PATHMATCH_NO_ANCHOR_END is specified. */
-			if (p[1] =3D=3D '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
-				/* "dir" =3D=3D "dir/" =3D=3D "dir/." */
-				return (*pm_slashskip(s) =3D=3D '\0');
-			}
-			/* Otherwise, '$' is not special. */
-			/* FALL THROUGH */
-		default:
-			if (*p !=3D *s)
-				return (0);
-			break;
-		}
-		++p;
-		++s;
-	}
-}
-
-/* Main entry point. */
-int
-lafe_pathmatch(const char *p, const char *s, int flags)
-{
-	/* Empty pattern only matches the empty string. */
-	if (p =3D=3D NULL || *p =3D=3D '\0')
-		return (s =3D=3D NULL || *s =3D=3D '\0');
-
-	/* Leading '^' anchors the start of the pattern. */
-	if (*p =3D=3D '^') {
-		++p;
-		flags &=3D ~PATHMATCH_NO_ANCHOR_START;
-	}
-
-	if (*p =3D=3D '/' && *s !=3D '/')
-		return (0);
-
-	/* Certain patterns and file names anchor implicitly. */
-	if (*p =3D=3D '*' || *p =3D=3D '/' || *p =3D=3D '/') {
-		while (*p =3D=3D '/')
-			++p;
-		while (*s =3D=3D '/')
-			++s;
-		return (pm(p, s, flags));
-	}
-
-	/* If start is unanchored, try to match start of each path element. */
-	if (flags & PATHMATCH_NO_ANCHOR_START) {
-		for ( ; s !=3D NULL; s =3D strchr(s, '/')) {
-			if (*s =3D=3D '/')
-				s++;
-			if (pm(p, s, flags))
-				return (1);
-		}
-		return (0);
-	}
-
-	/* Default: Match from beginning. */
-	return (pm(p, s, flags));
-}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/libarchive_fe/=
pathmatch.h
--- a/head/contrib/libarchive/libarchive_fe/pathmatch.h	Mon Jul 30 11:44:18=
 2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +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
- *    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 WARRANTI=
ES
- * 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 US=
E,
- * 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/contrib/libarchive/libarchive_fe/pathmatch.h 228763 2011=
-12-21 11:13:29Z mm $
- */
-
-#ifndef LAFE_PATHMATCH_H
-#define LAFE_PATHMATCH_H
-
-/* Don't anchor at beginning unless the pattern starts with "^" */
-#define PATHMATCH_NO_ANCHOR_START	1
-/* Don't anchor at end unless the pattern ends with "$" */
-#define PATHMATCH_NO_ANCHOR_END 	2
-
-/* Note that "^" and "$" are not special unless you set the corresponding
- * flag above. */
-
-int lafe_pathmatch(const char *p, const char *s, int flags);
-
-#endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/bsdtar.1
--- a/head/contrib/libarchive/tar/bsdtar.1	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/tar/bsdtar.1	Fri Aug 10 14:19:25 2012 +0300
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/contrib/libarchive/tar/bsdtar.1 232153 2012-02-25 10:58=
:02Z mm $
+.\" $FreeBSD: head/contrib/libarchive/tar/bsdtar.1 238856 2012-07-28 06:38=
:44Z mm $
 .\"
-.Dd Oct 12, 2009
+.Dd December 24, 2011
 .Dt TAR 1
 .Os
 .Sh NAME
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/bsdtar.c
--- a/head/contrib/libarchive/tar/bsdtar.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/tar/bsdtar.c	Fri Aug 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/tar/bsdtar.c 232153 2012-02-25=
 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/tar/bsdtar.c 238856 2012-07-28=
 06:38:44Z mm $");
=20
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
@@ -118,9 +118,6 @@
 }
 #endif
=20
-/* External function to parse a date/time string */
-time_t get_date(time_t, const char *);
-
 static void		 long_help(void);
 static void		 only_mode(struct bsdtar *, const char *opt,
 			     const char *valid);
@@ -140,7 +137,6 @@
 	char			 option_o;
 	char			 possible_help_request;
 	char			 buff[16];
-	time_t			 now;
=20
 	/*
 	 * Use a pointer for consistency, but stack-allocated storage
@@ -192,8 +188,6 @@
 			lafe_progname =3D *argv;
 	}
=20
-	time(&now);
-
 #if HAVE_SETLOCALE
 	if (setlocale(LC_ALL, "") =3D=3D NULL)
 		lafe_warnc(0, "Failed to set default locale");
@@ -241,11 +235,14 @@
 	 * Enable Mac OS "copyfile()" extension by default.
 	 * This has no effect on other platforms.
 	 */
-	bsdtar->enable_copyfile =3D 1;
+	bsdtar->readdisk_flags |=3D ARCHIVE_READDISK_MAC_COPYFILE;
 #ifdef COPYFILE_DISABLE_VAR
 	if (getenv(COPYFILE_DISABLE_VAR))
-		bsdtar->enable_copyfile =3D 0;
+		bsdtar->readdisk_flags &=3D ~ARCHIVE_READDISK_MAC_COPYFILE;
 #endif
+	bsdtar->matching =3D archive_match_new();
+	if (bsdtar->matching =3D=3D NULL)
+		lafe_errc(1, errno, "Out of memory");
=20
 	bsdtar->argv =3D argv;
 	bsdtar->argc =3D argc;
@@ -287,10 +284,11 @@
 			bsdtar->option_chroot =3D 1;
 			break;
 		case OPTION_DISABLE_COPYFILE: /* Mac OS X */
-			bsdtar->enable_copyfile =3D 0;
+			bsdtar->readdisk_flags &=3D ~ARCHIVE_READDISK_MAC_COPYFILE;
 			break;
 		case OPTION_EXCLUDE: /* GNU tar */
-			if (lafe_exclude(&bsdtar->matching, bsdtar->argument))
+			if (archive_match_exclude_pattern(
+			    bsdtar->matching, bsdtar->argument) !=3D ARCHIVE_OK)
 				lafe_errc(1, 0,
 				    "Couldn't exclude %s\n", bsdtar->argument);
 			break;
@@ -341,7 +339,8 @@
 			 * no one else needs this to filter entries
 			 * when transforming archives.
 			 */
-			if (lafe_include(&bsdtar->matching, bsdtar->argument))
+			if (archive_match_include_pattern(bsdtar->matching,
+			    bsdtar->argument) !=3D ARCHIVE_OK)
 				lafe_errc(1, 0,
 				    "Failed to add %s to inclusion list",
 				    bsdtar->argument);
@@ -395,39 +394,35 @@
 		 * TODO: Add corresponding "older" options to reverse these.
 		 */
 		case OPTION_NEWER_CTIME: /* GNU tar */
-			bsdtar->newer_ctime_filter =3D 1;
-			bsdtar->newer_ctime_sec =3D get_date(now, bsdtar->argument);
+			if (archive_match_include_date(bsdtar->matching,
+			    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER,
+			    bsdtar->argument) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(bsdtar->matching));
 			break;
 		case OPTION_NEWER_CTIME_THAN:
-			{
-				struct stat st;
-				if (stat(bsdtar->argument, &st) !=3D 0)
-					lafe_errc(1, 0,
-					    "Can't open file %s", bsdtar->argument);
-				bsdtar->newer_ctime_filter =3D 1;
-				bsdtar->newer_ctime_sec =3D st.st_ctime;
-				bsdtar->newer_ctime_nsec =3D
-				    ARCHIVE_STAT_CTIME_NANOS(&st);
-			}
+			if (archive_match_include_file_time(bsdtar->matching,
+			    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER,
+			    bsdtar->argument) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(bsdtar->matching));
 			break;
 		case OPTION_NEWER_MTIME: /* GNU tar */
-			bsdtar->newer_mtime_filter =3D 1;
-			bsdtar->newer_mtime_sec =3D get_date(now, bsdtar->argument);
+			if (archive_match_include_date(bsdtar->matching,
+			    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER,
+			    bsdtar->argument) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(bsdtar->matching));
 			break;
 		case OPTION_NEWER_MTIME_THAN:
-			{
-				struct stat st;
-				if (stat(bsdtar->argument, &st) !=3D 0)
-					lafe_errc(1, 0,
-					    "Can't open file %s", bsdtar->argument);
-				bsdtar->newer_mtime_filter =3D 1;
-				bsdtar->newer_mtime_sec =3D st.st_mtime;
-				bsdtar->newer_mtime_nsec =3D
-				    ARCHIVE_STAT_MTIME_NANOS(&st);
-			}
+			if (archive_match_include_file_time(bsdtar->matching,
+			    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER,
+			    bsdtar->argument) !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(bsdtar->matching));
 			break;
 		case OPTION_NODUMP: /* star */
-			bsdtar->option_honor_nodump =3D 1;
+			bsdtar->readdisk_flags |=3D ARCHIVE_READDISK_HONOR_NODUMP;
 			break;
 		case OPTION_NO_SAME_OWNER: /* GNU tar */
 			bsdtar->extract_flags &=3D ~ARCHIVE_EXTRACT_OWNER;
@@ -454,7 +449,8 @@
 			option_o =3D 1; /* Record it and resolve it later. */
 			break;
 		case OPTION_ONE_FILE_SYSTEM: /* GNU tar */
-			bsdtar->option_dont_traverse_mounts =3D 1;
+			bsdtar->readdisk_flags |=3D
+			    ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS;
 			break;
 		case OPTION_OPTIONS:
 			bsdtar->option_options =3D bsdtar->argument;
@@ -559,10 +555,11 @@
 			bsdtar->option_interactive =3D 1;
 			break;
 		case 'X': /* GNU tar */
-			if (lafe_exclude_from_file(&bsdtar->matching, bsdtar->argument))
-				lafe_errc(1, 0,
-				    "failed to process exclusions from file %s",
-				    bsdtar->argument);
+			if (archive_match_exclude_pattern_from_file(
+			    bsdtar->matching, bsdtar->argument, 0)
+			    !=3D ARCHIVE_OK)
+				lafe_errc(1, 0, "Error : %s",
+				    archive_error_string(bsdtar->matching));
 			break;
 		case 'x': /* SUSv2 */
 			set_mode(bsdtar, opt);
@@ -612,11 +609,11 @@
 		    "Must specify one of -c, -r, -t, -u, -x");
=20
 	/* Check boolean options only permitted in certain modes. */
-	if (bsdtar->option_dont_traverse_mounts)
+	if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
 		only_mode(bsdtar, "--one-file-system", "cru");
 	if (bsdtar->option_fast_read)
 		only_mode(bsdtar, "--fast-read", "xt");
-	if (bsdtar->option_honor_nodump)
+	if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP)
 		only_mode(bsdtar, "--nodump", "cru");
 	if (option_o > 0) {
 		switch (bsdtar->mode) {
@@ -684,7 +681,7 @@
 		break;
 	}
=20
-	lafe_cleanup_exclusions(&bsdtar->matching);
+	archive_match_free(bsdtar->matching);
 #if HAVE_REGEX_H
 	cleanup_substitution(bsdtar);
 #endif
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/bsdtar.h
--- a/head/contrib/libarchive/tar/bsdtar.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/tar/bsdtar.h	Fri Aug 10 14:19:25 2012 +0300
@@ -22,14 +22,12 @@
  * (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/contrib/libarchive/tar/bsdtar.h 232153 2012-02-25 10:58:=
02Z mm $
+ * $FreeBSD: head/contrib/libarchive/tar/bsdtar.h 238856 2012-07-28 06:38:=
44Z mm $
  */
=20
 #include "bsdtar_platform.h"
 #include <stdio.h>
=20
-#include "matching.h"
-
 #define	DEFAULT_BYTES_PER_BLOCK	(20*512)
=20
 /*
@@ -46,16 +44,11 @@
 	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		  readdisk_flags; /* Flags for read disk operation */
 	int		  strip_components; /* Remove this many leading dirs */
 	int		  gid;  /* --gid */
 	const char	 *gname; /* --gname */
@@ -67,10 +60,8 @@
 	const char	 *compress_program;
 	char		  option_absolute_paths; /* -P */
 	char		  option_chroot; /* --chroot */
-	char		  option_dont_traverse_mounts; /* --one-file-system */
 	char		  option_fast_read; /* --fast-read */
 	const char	 *option_options; /* --options */
-	char		  option_honor_nodump; /* --nodump */
 	char		  option_interactive; /* -w */
 	char		  option_no_owner; /* -o */
 	char		  option_no_subdirs; /* -n */
@@ -81,7 +72,6 @@
 	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 */
=20
 	/* Option parser state */
 	int		  getopt_state;
@@ -111,7 +101,8 @@
 	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 */
+	int			 first_fs;	/* for write.c */
+	struct archive		*matching;	/* for matching.c */
 	struct security		*security;	/* for read.c */
 	struct name_cache	*uname_cache;	/* for write.c */
 	struct siginfo_data	*siginfo;	/* for siginfo.c */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/getdate.c
--- a/head/contrib/libarchive/tar/getdate.c	Mon Jul 30 11:44:18 2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1037 +0,0 @@
-/*
- * This code is in the public domain and has no copyright.
- *
- * This is a plain C recursive-descent translation of an old
- * public-domain YACC grammar that has been used for parsing dates in
- * very many open-source projects.
- *
- * Since the original authors were generous enough to donate their
- * work to the public domain, I feel compelled to match their
- * generosity.
- *
- * Tim Kientzle, February 2009.
- */
-
-/*
- * Header comment from original getdate.y:
- */
-
-/*
-**  Originally written by Steven M. Bellovin <smb at research.att.com> while
-**  at the University of North Carolina at Chapel Hill.  Later tweaked by
-**  a couple of people on Usenet.  Completely overhauled by Rich $alz
-**  <rsalz at bbn.com> and Jim Berets <jberets at bbn.com> in August, 1990;
-**
-**  This grammar has 10 shift/reduce conflicts.
-**
-**  This code is in the public domain and has no copyright.
-*/
-
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/contrib/libarchive/tar/getdate.c 232153 2012-02-2=
5 10:58:02Z mm $");
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* This file defines a single public function. */
-time_t get_date(time_t now, char *);
-
-/* Basic time units. */
-#define	EPOCH		1970
-#define	MINUTE		(60L)
-#define	HOUR		(60L * MINUTE)
-#define	DAY		(24L * HOUR)
-
-/* Daylight-savings mode:  on, off, or not yet known. */
-enum DSTMODE { DSTon, DSToff, DSTmaybe };
-/* Meridian:  am or pm. */
-enum { tAM, tPM };
-/* Token types returned by nexttoken() */
-enum { tAGO =3D 260, tDAY, tDAYZONE, tAMPM, tMONTH, tMONTH_UNIT, tSEC_UNIT,
-       tUNUMBER, tZONE, tDST };
-struct token { int token; time_t value; };
-
-/*
- * Parser state.
- */
-struct gdstate {
-	struct token *tokenp; /* Pointer to next token. */
-	/* HaveXxxx counts how many of this kind of phrase we've seen;
-	 * it's a fatal error to have more than one time, zone, day,
-	 * or date phrase. */
-	int	HaveYear;
-	int	HaveMonth;
-	int	HaveDay;
-	int	HaveWeekDay; /* Day of week */
-	int	HaveTime; /* Hour/minute/second */
-	int	HaveZone; /* timezone and/or DST info */
-	int	HaveRel; /* time offset; we can have more than one */
-	/* Absolute time values. */
-	time_t	Timezone;  /* Seconds offset from GMT */
-	time_t	Day;
-	time_t	Hour;
-	time_t	Minutes;
-	time_t	Month;
-	time_t	Seconds;
-	time_t	Year;
-	/* DST selection */
-	enum DSTMODE	DSTmode;
-	/* Day of week accounting, e.g., "3rd Tuesday" */
-	time_t	DayOrdinal; /* "3" in "3rd Tuesday" */
-	time_t	DayNumber; /* "Tuesday" in "3rd Tuesday" */
-	/* Relative time values: hour/day/week offsets are measured in
-	 * seconds, month/year are counted in months. */
-	time_t	RelMonth;
-	time_t	RelSeconds;
-};
-
-/*
- * A series of functions that recognize certain common time phrases.
- * Each function returns 1 if it managed to make sense of some of the
- * tokens, zero otherwise.
- */
-
-/*
- *  hour:minute or hour:minute:second with optional AM, PM, or numeric
- *  timezone offset
- */
-static int
-timephrase(struct gdstate *gds)
-{
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D ':'
-	    && gds->tokenp[2].token =3D=3D tUNUMBER
-	    && gds->tokenp[3].token =3D=3D ':'
-	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
-		/* "12:14:18" or "22:08:07" */
-		++gds->HaveTime;
-		gds->Hour =3D gds->tokenp[0].value;
-		gds->Minutes =3D gds->tokenp[2].value;
-		gds->Seconds =3D gds->tokenp[4].value;
-		gds->tokenp +=3D 5;
-	}
-	else if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D ':'
-	    && gds->tokenp[2].token =3D=3D tUNUMBER) {
-		/* "12:14" or "22:08" */
-		++gds->HaveTime;
-		gds->Hour =3D gds->tokenp[0].value;
-		gds->Minutes =3D gds->tokenp[2].value;
-		gds->Seconds =3D 0;
-		gds->tokenp +=3D 3;
-	}
-	else if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D tAMPM) {
-		/* "7" is a time if it's followed by "am" or "pm" */
-		++gds->HaveTime;
-		gds->Hour =3D gds->tokenp[0].value;
-		gds->Minutes =3D gds->Seconds =3D 0;
-		/* We'll handle the AM/PM below. */
-		gds->tokenp +=3D 1;
-	} else {
-		/* We can't handle this. */
-		return 0;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tAMPM) {
-		/* "7:12pm", "12:20:13am" */
-		if (gds->Hour =3D=3D 12)
-			gds->Hour =3D 0;
-		if (gds->tokenp[0].value =3D=3D tPM)
-			gds->Hour +=3D 12;
-		gds->tokenp +=3D 1;
-	}
-	if (gds->tokenp[0].token =3D=3D '+'
-	    && gds->tokenp[1].token =3D=3D tUNUMBER) {
-		/* "7:14+0700" */
-		gds->HaveZone++;
-		gds->DSTmode =3D DSToff;
-		gds->Timezone =3D - ((gds->tokenp[1].value / 100) * HOUR
-		    + (gds->tokenp[1].value % 100) * MINUTE);
-		gds->tokenp +=3D 2;
-	}
-	if (gds->tokenp[0].token =3D=3D '-'
-	    && gds->tokenp[1].token =3D=3D tUNUMBER) {
-		/* "19:14:12-0530" */
-		gds->HaveZone++;
-		gds->DSTmode =3D DSToff;
-		gds->Timezone =3D + ((gds->tokenp[1].value / 100) * HOUR
-		    + (gds->tokenp[1].value % 100) * MINUTE);
-		gds->tokenp +=3D 2;
-	}
-	return 1;
-}
-
-/*
- * Timezone name, possibly including DST.
- */
-static int
-zonephrase(struct gdstate *gds)
-{
-	if (gds->tokenp[0].token =3D=3D tZONE
-	    && gds->tokenp[1].token =3D=3D tDST) {
-		gds->HaveZone++;
-		gds->Timezone =3D gds->tokenp[0].value;
-		gds->DSTmode =3D DSTon;
-		gds->tokenp +=3D 1;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tZONE) {
-		gds->HaveZone++;
-		gds->Timezone =3D gds->tokenp[0].value;
-		gds->DSTmode =3D DSToff;
-		gds->tokenp +=3D 1;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tDAYZONE) {
-		gds->HaveZone++;
-		gds->Timezone =3D gds->tokenp[0].value;
-		gds->DSTmode =3D DSTon;
-		gds->tokenp +=3D 1;
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * Year/month/day in various combinations.
- */
-static int
-datephrase(struct gdstate *gds)
-{
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D '/'
-	    && gds->tokenp[2].token =3D=3D tUNUMBER
-	    && gds->tokenp[3].token =3D=3D '/'
-	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
-		gds->HaveYear++;
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		if (gds->tokenp[0].value >=3D 13) {
-			/* First number is big:  2004/01/29, 99/02/17 */
-			gds->Year =3D gds->tokenp[0].value;
-			gds->Month =3D gds->tokenp[2].value;
-			gds->Day =3D gds->tokenp[4].value;
-		} else if ((gds->tokenp[4].value >=3D 13)
-		    || (gds->tokenp[2].value >=3D 13)) {
-			/* Last number is big:  01/07/98 */
-			/* Middle number is big:  01/29/04 */
-			gds->Month =3D gds->tokenp[0].value;
-			gds->Day =3D gds->tokenp[2].value;
-			gds->Year =3D gds->tokenp[4].value;
-		} else {
-			/* No significant clues: 02/03/04 */
-			gds->Month =3D gds->tokenp[0].value;
-			gds->Day =3D gds->tokenp[2].value;
-			gds->Year =3D gds->tokenp[4].value;
-		}
-		gds->tokenp +=3D 5;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D '/'
-	    && gds->tokenp[2].token =3D=3D tUNUMBER) {
-		/* "1/15" */
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		gds->Month =3D gds->tokenp[0].value;
-		gds->Day =3D gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D '-'
-	    && gds->tokenp[2].token =3D=3D tUNUMBER
-	    && gds->tokenp[3].token =3D=3D '-'
-	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
-		/* ISO 8601 format.  yyyy-mm-dd.  */
-		gds->HaveYear++;
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		gds->Year =3D gds->tokenp[0].value;
-		gds->Month =3D gds->tokenp[2].value;
-		gds->Day =3D gds->tokenp[4].value;
-		gds->tokenp +=3D 5;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D '-'
-	    && gds->tokenp[2].token =3D=3D tMONTH
-	    && gds->tokenp[3].token =3D=3D '-'
-	    && gds->tokenp[4].token =3D=3D tUNUMBER) {
-		gds->HaveYear++;
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		if (gds->tokenp[0].value > 31) {
-			/* e.g. 1992-Jun-17 */
-			gds->Year =3D gds->tokenp[0].value;
-			gds->Month =3D gds->tokenp[2].value;
-			gds->Day =3D gds->tokenp[4].value;
-		} else {
-			/* e.g. 17-JUN-1992.  */
-			gds->Day =3D gds->tokenp[0].value;
-			gds->Month =3D gds->tokenp[2].value;
-			gds->Year =3D gds->tokenp[4].value;
-		}
-		gds->tokenp +=3D 5;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tMONTH
-	    && gds->tokenp[1].token =3D=3D tUNUMBER
-	    && gds->tokenp[2].token =3D=3D ','
-	    && gds->tokenp[3].token =3D=3D tUNUMBER) {
-		/* "June 17, 2001" */
-		gds->HaveYear++;
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		gds->Month =3D gds->tokenp[0].value;
-		gds->Day =3D gds->tokenp[1].value;
-		gds->Year =3D gds->tokenp[3].value;
-		gds->tokenp +=3D 4;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tMONTH
-	    && gds->tokenp[1].token =3D=3D tUNUMBER) {
-		/* "May 3" */
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		gds->Month =3D gds->tokenp[0].value;
-		gds->Day =3D gds->tokenp[1].value;
-		gds->tokenp +=3D 2;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D tMONTH
-	    && gds->tokenp[2].token =3D=3D tUNUMBER) {
-		/* "12 Sept 1997" */
-		gds->HaveYear++;
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		gds->Day =3D gds->tokenp[0].value;
-		gds->Month =3D gds->tokenp[1].value;
-		gds->Year =3D gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D tMONTH) {
-		/* "12 Sept" */
-		gds->HaveMonth++;
-		gds->HaveDay++;
-		gds->Day =3D gds->tokenp[0].value;
-		gds->Month =3D gds->tokenp[1].value;
-		gds->tokenp +=3D 2;
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * Relative time phrase: "tomorrow", "yesterday", "+1 hour", etc.
- */
-static int
-relunitphrase(struct gdstate *gds)
-{
-	if (gds->tokenp[0].token =3D=3D '-'
-	    && gds->tokenp[1].token =3D=3D tUNUMBER
-	    && gds->tokenp[2].token =3D=3D tSEC_UNIT) {
-		/* "-3 hours" */
-		gds->HaveRel++;
-		gds->RelSeconds -=3D gds->tokenp[1].value * gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D '+'
-	    && gds->tokenp[1].token =3D=3D tUNUMBER
-	    && gds->tokenp[2].token =3D=3D tSEC_UNIT) {
-		/* "+1 minute" */
-		gds->HaveRel++;
-		gds->RelSeconds +=3D gds->tokenp[1].value * gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D tSEC_UNIT) {
-		/* "1 day" */
-		gds->HaveRel++;
-		gds->RelSeconds +=3D gds->tokenp[1].value * gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D '-'
-	    && gds->tokenp[1].token =3D=3D tUNUMBER
-	    && gds->tokenp[2].token =3D=3D tMONTH_UNIT) {
-		/* "-3 months" */
-		gds->HaveRel++;
-		gds->RelMonth -=3D gds->tokenp[1].value * gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D '+'
-	    && gds->tokenp[1].token =3D=3D tUNUMBER
-	    && gds->tokenp[2].token =3D=3D tMONTH_UNIT) {
-		/* "+5 years" */
-		gds->HaveRel++;
-		gds->RelMonth +=3D gds->tokenp[1].value * gds->tokenp[2].value;
-		gds->tokenp +=3D 3;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-	    && gds->tokenp[1].token =3D=3D tMONTH_UNIT) {
-		/* "2 years" */
-		gds->HaveRel++;
-		gds->RelMonth +=3D gds->tokenp[0].value * gds->tokenp[1].value;
-		gds->tokenp +=3D 2;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D tSEC_UNIT) {
-		/* "now", "tomorrow" */
-		gds->HaveRel++;
-		gds->RelSeconds +=3D gds->tokenp[0].value;
-		++gds->tokenp;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D tMONTH_UNIT) {
-		/* "month" */
-		gds->HaveRel++;
-		gds->RelMonth +=3D gds->tokenp[0].value;
-		gds->tokenp +=3D 1;
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * Day of the week specification.
- */
-static int
-dayphrase(struct gdstate *gds)
-{
-	if (gds->tokenp[0].token =3D=3D tDAY) {
-		/* "tues", "wednesday," */
-		gds->HaveWeekDay++;
-		gds->DayOrdinal =3D 1;
-		gds->DayNumber =3D gds->tokenp[0].value;
-		gds->tokenp +=3D 1;
-		if (gds->tokenp[0].token =3D=3D ',')
-			gds->tokenp +=3D 1;
-		return 1;
-	}
-	if (gds->tokenp[0].token =3D=3D tUNUMBER
-		&& gds->tokenp[1].token =3D=3D tDAY) {
-		/* "second tues" "3 wed" */
-		gds->HaveWeekDay++;
-		gds->DayOrdinal =3D gds->tokenp[0].value;
-		gds->DayNumber =3D gds->tokenp[1].value;
-		gds->tokenp +=3D 2;
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * Try to match a phrase using one of the above functions.
- * This layer also deals with a couple of generic issues.
- */
-static int
-phrase(struct gdstate *gds)
-{
-	if (timephrase(gds))
-		return 1;
-	if (zonephrase(gds))
-		return 1;
-	if (datephrase(gds))
-		return 1;
-	if (dayphrase(gds))
-		return 1;
-	if (relunitphrase(gds)) {
-		if (gds->tokenp[0].token =3D=3D tAGO) {
-			gds->RelSeconds =3D -gds->RelSeconds;
-			gds->RelMonth =3D -gds->RelMonth;
-			gds->tokenp +=3D 1;
-		}
-		return 1;
-	}
-
-	/* Bare numbers sometimes have meaning. */
-	if (gds->tokenp[0].token =3D=3D tUNUMBER) {
-		if (gds->HaveTime && !gds->HaveYear && !gds->HaveRel) {
-			gds->HaveYear++;
-			gds->Year =3D gds->tokenp[0].value;
-			gds->tokenp +=3D 1;
-			return 1;
-		}
-
-		if(gds->tokenp[0].value > 10000) {
-			/* "20040301" */
-			gds->HaveYear++;
-			gds->HaveMonth++;
-			gds->HaveDay++;
-			gds->Day=3D (gds->tokenp[0].value)%100;
-			gds->Month=3D (gds->tokenp[0].value/100)%100;
-			gds->Year =3D gds->tokenp[0].value/10000;
-			gds->tokenp +=3D 1;
-			return 1;
-		}
-
-		if (gds->tokenp[0].value < 24) {
-			gds->HaveTime++;
-			gds->Hour =3D gds->tokenp[0].value;
-			gds->Minutes =3D 0;
-			gds->Seconds =3D 0;
-			gds->tokenp +=3D 1;
-			return 1;
-		}
-
-		if ((gds->tokenp[0].value / 100 < 24)
-		    && (gds->tokenp[0].value % 100 < 60)) {
-			/* "513" is same as "5:13" */
-			gds->Hour =3D gds->tokenp[0].value / 100;
-			gds->Minutes =3D gds->tokenp[0].value % 100;
-			gds->Seconds =3D 0;
-			gds->tokenp +=3D 1;
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * A dictionary of time words.
- */
-static struct LEXICON {
-	size_t		abbrev;
-	const char	*name;
-	int		type;
-	time_t		value;
-} const TimeWords[] =3D {
-	/* am/pm */
-	{ 0, "am",		tAMPM,	tAM },
-	{ 0, "pm",		tAMPM,	tPM },
-
-	/* Month names. */
-	{ 3, "january",		tMONTH,  1 },
-	{ 3, "february",	tMONTH,  2 },
-	{ 3, "march",		tMONTH,  3 },
-	{ 3, "april",		tMONTH,  4 },
-	{ 3, "may",		tMONTH,  5 },
-	{ 3, "june",		tMONTH,  6 },
-	{ 3, "july",		tMONTH,  7 },
-	{ 3, "august",		tMONTH,  8 },
-	{ 3, "september",	tMONTH,  9 },
-	{ 3, "october",		tMONTH, 10 },
-	{ 3, "november",	tMONTH, 11 },
-	{ 3, "december",	tMONTH, 12 },
-
-	/* Days of the week. */
-	{ 2, "sunday",		tDAY, 0 },
-	{ 3, "monday",		tDAY, 1 },
-	{ 2, "tuesday",		tDAY, 2 },
-	{ 3, "wednesday",	tDAY, 3 },
-	{ 2, "thursday",	tDAY, 4 },
-	{ 2, "friday",		tDAY, 5 },
-	{ 2, "saturday",	tDAY, 6 },
-
-	/* Timezones: Offsets are in seconds. */
-	{ 0, "gmt",  tZONE,     0*HOUR }, /* Greenwich Mean */
-	{ 0, "ut",   tZONE,     0*HOUR }, /* Universal (Coordinated) */
-	{ 0, "utc",  tZONE,     0*HOUR },
-	{ 0, "wet",  tZONE,     0*HOUR }, /* Western European */
-	{ 0, "bst",  tDAYZONE,  0*HOUR }, /* British Summer */
-	{ 0, "wat",  tZONE,     1*HOUR }, /* West Africa */
-	{ 0, "at",   tZONE,     2*HOUR }, /* Azores */
-	/* { 0, "bst", tZONE, 3*HOUR }, */ /* Brazil Standard: Conflict */
-	/* { 0, "gst", tZONE, 3*HOUR }, */ /* Greenland Standard: Conflict*/
-	{ 0, "nft",  tZONE,     3*HOUR+30*MINUTE }, /* Newfoundland */
-	{ 0, "nst",  tZONE,     3*HOUR+30*MINUTE }, /* Newfoundland Standard */
-	{ 0, "ndt",  tDAYZONE,  3*HOUR+30*MINUTE }, /* Newfoundland Daylight */
-	{ 0, "ast",  tZONE,     4*HOUR }, /* Atlantic Standard */
-	{ 0, "adt",  tDAYZONE,  4*HOUR }, /* Atlantic Daylight */
-	{ 0, "est",  tZONE,     5*HOUR }, /* Eastern Standard */
-	{ 0, "edt",  tDAYZONE,  5*HOUR }, /* Eastern Daylight */
-	{ 0, "cst",  tZONE,     6*HOUR }, /* Central Standard */
-	{ 0, "cdt",  tDAYZONE,  6*HOUR }, /* Central Daylight */
-	{ 0, "mst",  tZONE,     7*HOUR }, /* Mountain Standard */
-	{ 0, "mdt",  tDAYZONE,  7*HOUR }, /* Mountain Daylight */
-	{ 0, "pst",  tZONE,     8*HOUR }, /* Pacific Standard */
-	{ 0, "pdt",  tDAYZONE,  8*HOUR }, /* Pacific Daylight */
-	{ 0, "yst",  tZONE,     9*HOUR }, /* Yukon Standard */
-	{ 0, "ydt",  tDAYZONE,  9*HOUR }, /* Yukon Daylight */
-	{ 0, "hst",  tZONE,     10*HOUR }, /* Hawaii Standard */
-	{ 0, "hdt",  tDAYZONE,  10*HOUR }, /* Hawaii Daylight */
-	{ 0, "cat",  tZONE,     10*HOUR }, /* Central Alaska */
-	{ 0, "ahst", tZONE,     10*HOUR }, /* Alaska-Hawaii Standard */
-	{ 0, "nt",   tZONE,     11*HOUR }, /* Nome */
-	{ 0, "idlw", tZONE,     12*HOUR }, /* Intl Date Line West */
-	{ 0, "cet",  tZONE,     -1*HOUR }, /* Central European */
-	{ 0, "met",  tZONE,     -1*HOUR }, /* Middle European */
-	{ 0, "mewt", tZONE,     -1*HOUR }, /* Middle European Winter */
-	{ 0, "mest", tDAYZONE,  -1*HOUR }, /* Middle European Summer */
-	{ 0, "swt",  tZONE,     -1*HOUR }, /* Swedish Winter */
-	{ 0, "sst",  tDAYZONE,  -1*HOUR }, /* Swedish Summer */
-	{ 0, "fwt",  tZONE,     -1*HOUR }, /* French Winter */
-	{ 0, "fst",  tDAYZONE,  -1*HOUR }, /* French Summer */
-	{ 0, "eet",  tZONE,     -2*HOUR }, /* Eastern Eur, USSR Zone 1 */
-	{ 0, "bt",   tZONE,     -3*HOUR }, /* Baghdad, USSR Zone 2 */
-	{ 0, "it",   tZONE,     -3*HOUR-30*MINUTE },/* Iran */
-	{ 0, "zp4",  tZONE,     -4*HOUR }, /* USSR Zone 3 */
-	{ 0, "zp5",  tZONE,     -5*HOUR }, /* USSR Zone 4 */
-	{ 0, "ist",  tZONE,     -5*HOUR-30*MINUTE },/* Indian Standard */
-	{ 0, "zp6",  tZONE,     -6*HOUR }, /* USSR Zone 5 */
-	/* { 0, "nst",  tZONE, -6.5*HOUR }, */ /* North Sumatra: Conflict */
-	/* { 0, "sst", tZONE, -7*HOUR }, */ /* So Sumatra, USSR 6: Conflict */
-	{ 0, "wast", tZONE,     -7*HOUR }, /* West Australian Standard */
-	{ 0, "wadt", tDAYZONE,  -7*HOUR }, /* West Australian Daylight */
-	{ 0, "jt",   tZONE,     -7*HOUR-30*MINUTE },/* Java (3pm in Cronusland!)*/
-	{ 0, "cct",  tZONE,     -8*HOUR }, /* China Coast, USSR Zone 7 */
-	{ 0, "jst",  tZONE,     -9*HOUR }, /* Japan Std, USSR Zone 8 */
-	{ 0, "cast", tZONE,     -9*HOUR-30*MINUTE },/* Ctrl Australian Std */
-	{ 0, "cadt", tDAYZONE,  -9*HOUR-30*MINUTE },/* Ctrl Australian Daylt */
-	{ 0, "east", tZONE,     -10*HOUR }, /* Eastern Australian Std */
-	{ 0, "eadt", tDAYZONE,  -10*HOUR }, /* Eastern Australian Daylt */
-	{ 0, "gst",  tZONE,     -10*HOUR }, /* Guam Std, USSR Zone 9 */
-	{ 0, "nzt",  tZONE,     -12*HOUR }, /* New Zealand */
-	{ 0, "nzst", tZONE,     -12*HOUR }, /* New Zealand Standard */
-	{ 0, "nzdt", tDAYZONE,  -12*HOUR }, /* New Zealand Daylight */
-	{ 0, "idle", tZONE,     -12*HOUR }, /* Intl Date Line East */
-
-	{ 0, "dst",  tDST,		0 },
-
-	/* Time units. */
-	{ 4, "years",		tMONTH_UNIT,	12 },
-	{ 5, "months",		tMONTH_UNIT,	1 },
-	{ 9, "fortnights",	tSEC_UNIT,	14 * DAY },
-	{ 4, "weeks",		tSEC_UNIT,	7 * DAY },
-	{ 3, "days",		tSEC_UNIT,	DAY },
-	{ 4, "hours",		tSEC_UNIT,	HOUR },
-	{ 3, "minutes",		tSEC_UNIT,	MINUTE },
-	{ 3, "seconds",		tSEC_UNIT,	1 },
-
-	/* Relative-time words. */
-	{ 0, "tomorrow",	tSEC_UNIT,	DAY },
-	{ 0, "yesterday",	tSEC_UNIT,	-DAY },
-	{ 0, "today",		tSEC_UNIT,	0 },
-	{ 0, "now",		tSEC_UNIT,	0 },
-	{ 0, "last",		tUNUMBER,	-1 },
-	{ 0, "this",		tSEC_UNIT,	0 },
-	{ 0, "next",		tUNUMBER,	2 },
-	{ 0, "first",		tUNUMBER,	1 },
-	{ 0, "1st",		tUNUMBER,	1 },
-/*	{ 0, "second",		tUNUMBER,	2 }, */
-	{ 0, "2nd",		tUNUMBER,	2 },
-	{ 0, "third",		tUNUMBER,	3 },
-	{ 0, "3rd",		tUNUMBER,	3 },
-	{ 0, "fourth",		tUNUMBER,	4 },
-	{ 0, "4th",		tUNUMBER,	4 },
-	{ 0, "fifth",		tUNUMBER,	5 },
-	{ 0, "5th",		tUNUMBER,	5 },
-	{ 0, "sixth",		tUNUMBER,	6 },
-	{ 0, "seventh",		tUNUMBER,	7 },
-	{ 0, "eighth",		tUNUMBER,	8 },
-	{ 0, "ninth",		tUNUMBER,	9 },
-	{ 0, "tenth",		tUNUMBER,	10 },
-	{ 0, "eleventh",	tUNUMBER,	11 },
-	{ 0, "twelfth",		tUNUMBER,	12 },
-	{ 0, "ago",		tAGO,		1 },
-
-	/* Military timezones. */
-	{ 0, "a",	tZONE,	1*HOUR },
-	{ 0, "b",	tZONE,	2*HOUR },
-	{ 0, "c",	tZONE,	3*HOUR },
-	{ 0, "d",	tZONE,	4*HOUR },
-	{ 0, "e",	tZONE,	5*HOUR },
-	{ 0, "f",	tZONE,	6*HOUR },
-	{ 0, "g",	tZONE,	7*HOUR },
-	{ 0, "h",	tZONE,	8*HOUR },
-	{ 0, "i",	tZONE,	9*HOUR },
-	{ 0, "k",	tZONE,	10*HOUR },
-	{ 0, "l",	tZONE,	11*HOUR },
-	{ 0, "m",	tZONE,	12*HOUR },
-	{ 0, "n",	tZONE,	-1*HOUR },
-	{ 0, "o",	tZONE,	-2*HOUR },
-	{ 0, "p",	tZONE,	-3*HOUR },
-	{ 0, "q",	tZONE,	-4*HOUR },
-	{ 0, "r",	tZONE,	-5*HOUR },
-	{ 0, "s",	tZONE,	-6*HOUR },
-	{ 0, "t",	tZONE,	-7*HOUR },
-	{ 0, "u",	tZONE,	-8*HOUR },
-	{ 0, "v",	tZONE,	-9*HOUR },
-	{ 0, "w",	tZONE,	-10*HOUR },
-	{ 0, "x",	tZONE,	-11*HOUR },
-	{ 0, "y",	tZONE,	-12*HOUR },
-	{ 0, "z",	tZONE,	0*HOUR },
-
-	/* End of table. */
-	{ 0, NULL,	0,	0 }
-};
-
-/*
- * Year is either:
- *  =3D A number from 0 to 99, which means a year from 1970 to 2069, or
- *  =3D The actual year (>=3D100).
- */
-static time_t
-Convert(time_t Month, time_t Day, time_t Year,
-	time_t Hours, time_t Minutes, time_t Seconds,
-	time_t Timezone, enum DSTMODE DSTmode)
-{
-	static int DaysInMonth[12] =3D {
-		31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-	};
-	time_t	Julian;
-	int	i;
-
-	if (Year < 69)
-		Year +=3D 2000;
-	else if (Year < 100)
-		Year +=3D 1900;
-	DaysInMonth[1] =3D Year % 4 =3D=3D 0 && (Year % 100 !=3D 0 || Year % 400 =
=3D=3D 0)
-	    ? 29 : 28;
-	/* Checking for 2038 bogusly assumes that time_t is 32 bits.  But
-	   I'm too lazy to try to check for time_t overflow in another way.  */
-	if (Year < EPOCH || Year > 2038
-	    || Month < 1 || Month > 12
-	    /* Lint fluff:  "conversion from long may lose accuracy" */
-	    || Day < 1 || Day > DaysInMonth[(int)--Month]
-	    || Hours < 0 || Hours > 23
-	    || Minutes < 0 || Minutes > 59
-	    || Seconds < 0 || Seconds > 59)
-		return -1;
-
-	Julian =3D Day - 1;
-	for (i =3D 0; i < Month; i++)
-		Julian +=3D DaysInMonth[i];
-	for (i =3D EPOCH; i < Year; i++)
-		Julian +=3D 365 + (i % 4 =3D=3D 0);
-	Julian *=3D DAY;
-	Julian +=3D Timezone;
-	Julian +=3D Hours * HOUR + Minutes * MINUTE + Seconds;
-	if (DSTmode =3D=3D DSTon
-	    || (DSTmode =3D=3D DSTmaybe && localtime(&Julian)->tm_isdst))
-		Julian -=3D HOUR;
-	return Julian;
-}
-
-
-static time_t
-DSTcorrect(time_t Start, time_t Future)
-{
-	time_t	StartDay;
-	time_t	FutureDay;
-
-	StartDay =3D (localtime(&Start)->tm_hour + 1) % 24;
-	FutureDay =3D (localtime(&Future)->tm_hour + 1) % 24;
-	return (Future - Start) + (StartDay - FutureDay) * HOUR;
-}
-
-
-static time_t
-RelativeDate(time_t Start, time_t zone, int dstmode,
-    time_t DayOrdinal, time_t DayNumber)
-{
-	struct tm	*tm;
-	time_t	t, now;
-
-	t =3D Start - zone;
-	tm =3D gmtime(&t);
-	now =3D Start;
-	now +=3D DAY * ((DayNumber - tm->tm_wday + 7) % 7);
-	now +=3D 7 * DAY * (DayOrdinal <=3D 0 ? DayOrdinal : DayOrdinal - 1);
-	if (dstmode =3D=3D DSTmaybe)
-		return DSTcorrect(Start, now);
-	return now - Start;
-}
-
-
-static time_t
-RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
-{
-	struct tm	*tm;
-	time_t	Month;
-	time_t	Year;
-
-	if (RelMonth =3D=3D 0)
-		return 0;
-	tm =3D localtime(&Start);
-	Month =3D 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
-	Year =3D Month / 12;
-	Month =3D Month % 12 + 1;
-	return DSTcorrect(Start,
-	    Convert(Month, (time_t)tm->tm_mday, Year,
-		(time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
-		Timezone, DSTmaybe));
-}
-
-/*
- * Tokenizer.
- */
-static int
-nexttoken(char **in, time_t *value)
-{
-	char	c;
-	char	buff[64];
-
-	for ( ; ; ) {
-		while (isspace((unsigned char)**in))
-			++*in;
-
-		/* Skip parenthesized comments. */
-		if (**in =3D=3D '(') {
-			int Count =3D 0;
-			do {
-				c =3D *(*in)++;
-				if (c =3D=3D '\0')
-					return c;
-				if (c =3D=3D '(')
-					Count++;
-				else if (c =3D=3D ')')
-					Count--;
-			} while (Count > 0);
-			continue;
-		}
-
-		/* Try the next token in the word table first. */
-		/* This allows us to match "2nd", for example. */
-		{
-			char *src =3D *in;
-			const struct LEXICON *tp;
-			unsigned i =3D 0;
-
-			/* Force to lowercase and strip '.' characters. */
-			while (*src !=3D '\0'
-			    && (isalnum((unsigned char)*src) || *src =3D=3D '.')
-			    && i < sizeof(buff)-1) {
-				if (*src !=3D '.') {
-					if (isupper((unsigned char)*src))
-						buff[i++] =3D tolower((unsigned char)*src);
-					else
-						buff[i++] =3D *src;
-				}
-				src++;
-			}
-			buff[i] =3D '\0';
-
-			/*
-			 * Find the first match.  If the word can be
-			 * abbreviated, make sure we match at least
-			 * the minimum abbreviation.
-			 */
-			for (tp =3D TimeWords; tp->name; tp++) {
-				size_t abbrev =3D tp->abbrev;
-				if (abbrev =3D=3D 0)
-					abbrev =3D strlen(tp->name);
-				if (strlen(buff) >=3D abbrev
-				    && strncmp(tp->name, buff, strlen(buff))
-				    	=3D=3D 0) {
-					/* Skip over token. */
-					*in =3D src;
-					/* Return the match. */
-					*value =3D tp->value;
-					return tp->type;
-				}
-			}
-		}
-
-		/*
-		 * Not in the word table, maybe it's a number.  Note:
-		 * Because '-' and '+' have other special meanings, I
-		 * don't deal with signed numbers here.
-		 */
-		if (isdigit((unsigned char)(c =3D **in))) {
-			for (*value =3D 0; isdigit((unsigned char)(c =3D *(*in)++)); )
-				*value =3D 10 * *value + c - '0';
-			(*in)--;
-			return (tUNUMBER);
-		}
-
-		return *(*in)++;
-	}
-}
-
-#define	TM_YEAR_ORIGIN 1900
-
-/* Yield A - B, measured in seconds.  */
-static long
-difftm (struct tm *a, struct tm *b)
-{
-	int ay =3D a->tm_year + (TM_YEAR_ORIGIN - 1);
-	int by =3D b->tm_year + (TM_YEAR_ORIGIN - 1);
-	int days =3D (
-		/* difference in day of year */
-		a->tm_yday - b->tm_yday
-		/* + intervening leap days */
-		+  ((ay >> 2) - (by >> 2))
-		-  (ay/100 - by/100)
-		+  ((ay/100 >> 2) - (by/100 >> 2))
-		/* + difference in years * 365 */
-		+  (long)(ay-by) * 365
-		);
-	return (days * DAY + (a->tm_hour - b->tm_hour) * HOUR
-	    + (a->tm_min - b->tm_min) * MINUTE
-	    + (a->tm_sec - b->tm_sec));
-}
-
-/*
- *
- * The public function.
- *
- * TODO: tokens[] array should be dynamically sized.
- */
-time_t
-get_date(time_t now, char *p)
-{
-	struct token	tokens[256];
-	struct gdstate	_gds;
-	struct token	*lasttoken;
-	struct gdstate	*gds;
-	struct tm	local, *tm;
-	struct tm	gmt, *gmt_ptr;
-	time_t		Start;
-	time_t		tod;
-	long		tzone;
-
-	/* Clear out the parsed token array. */
-	memset(tokens, 0, sizeof(tokens));
-	/* Initialize the parser state. */
-	memset(&_gds, 0, sizeof(_gds));
-	gds =3D &_gds;
-
-	/* Look up the current time. */
-	memset(&local, 0, sizeof(local));
-	tm =3D localtime (&now);
-	if (tm =3D=3D NULL)
-		return -1;
-	local =3D *tm;
-
-	/* Look up UTC if we can and use that to determine the current
-	 * timezone offset. */
-	memset(&gmt, 0, sizeof(gmt));
-	gmt_ptr =3D gmtime (&now);
-	if (gmt_ptr !=3D NULL) {
-		/* Copy, in case localtime and gmtime use the same buffer. */
-		gmt =3D *gmt_ptr;
-	}
-	if (gmt_ptr !=3D NULL)
-		tzone =3D difftm (&gmt, &local);
-	else
-		/* This system doesn't understand timezones; fake it. */
-		tzone =3D 0;
-	if(local.tm_isdst)
-		tzone +=3D HOUR;
-
-	/* Tokenize the input string. */
-	lasttoken =3D tokens;
-	while ((lasttoken->token =3D nexttoken(&p, &lasttoken->value)) !=3D 0) {
-		++lasttoken;
-		if (lasttoken > tokens + 255)
-			return -1;
-	}
-	gds->tokenp =3D tokens;
-
-	/* Match phrases until we run out of input tokens. */
-	while (gds->tokenp < lasttoken) {
-		if (!phrase(gds))
-			return -1;
-	}
-
-	/* Use current local timezone if none was specified. */
-	if (!gds->HaveZone) {
-		gds->Timezone =3D tzone;
-		gds->DSTmode =3D DSTmaybe;
-	}
-
-	/* If a timezone was specified, use that for generating the default
-	 * time components instead of the local timezone. */
-	if (gds->HaveZone && gmt_ptr !=3D NULL) {
-		now -=3D gds->Timezone;
-		gmt_ptr =3D gmtime (&now);
-		if (gmt_ptr !=3D NULL)
-			local =3D *gmt_ptr;
-		now +=3D gds->Timezone;
-	}
-
-	if (!gds->HaveYear)
-		gds->Year =3D local.tm_year + 1900;
-	if (!gds->HaveMonth)
-		gds->Month =3D local.tm_mon + 1;
-	if (!gds->HaveDay)
-		gds->Day =3D local.tm_mday;
-	/* Note: No default for hour/min/sec; a specifier that just
-	 * gives date always refers to 00:00 on that date. */
-
-	/* If we saw more than one time, timezone, weekday, year, month,
-	 * or day, then give up. */
-	if (gds->HaveTime > 1 || gds->HaveZone > 1 || gds->HaveWeekDay > 1
-	    || gds->HaveYear > 1 || gds->HaveMonth > 1 || gds->HaveDay > 1)
-		return -1;
-
-	/* Compute an absolute time based on whatever absolute information
-	 * we collected. */
-	if (gds->HaveYear || gds->HaveMonth || gds->HaveDay
-	    || gds->HaveTime || gds->HaveWeekDay) {
-		Start =3D Convert(gds->Month, gds->Day, gds->Year,
-		    gds->Hour, gds->Minutes, gds->Seconds,
-		    gds->Timezone, gds->DSTmode);
-		if (Start < 0)
-			return -1;
-	} else {
-		Start =3D now;
-		if (!gds->HaveRel)
-			Start -=3D local.tm_hour * HOUR + local.tm_min * MINUTE
-			    + local.tm_sec;
-	}
-
-	/* Add the relative offset. */
-	Start +=3D gds->RelSeconds;
-	Start +=3D RelativeMonth(Start, gds->Timezone, gds->RelMonth);
-
-	/* Adjust for day-of-week offsets. */
-	if (gds->HaveWeekDay
-	    && !(gds->HaveYear || gds->HaveMonth || gds->HaveDay)) {
-		tod =3D RelativeDate(Start, gds->Timezone,
-		    gds->DSTmode, gds->DayOrdinal, gds->DayNumber);
-		Start +=3D tod;
-	}
-
-	/* -1 is an error indicator, so return 0 instead of -1 if
-	 * that's the actual time. */
-	return Start =3D=3D -1 ? 0 : Start;
-}
-
-
-#if	defined(TEST)
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
-    time_t	d;
-
-    while (*++argv !=3D NULL) {
-	    (void)printf("Input: %s\n", *argv);
-	    d =3D get_date(*argv);
-	    if (d =3D=3D -1)
-		    (void)printf("Bad format - couldn't convert.\n");
-	    else
-		    (void)printf("Output: %s\n", ctime(&d));
-    }
-    exit(0);
-    /* NOTREACHED */
-}
-#endif	/* defined(TEST) */
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/read.c
--- a/head/contrib/libarchive/tar/read.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/tar/read.c	Fri Aug 10 14:19:25 2012 +0300
@@ -24,7 +24,7 @@
  */
=20
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/tar/read.c 232153 2012-02-25 1=
0:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/tar/read.c 238856 2012-07-28 0=
6:38:44Z mm $");
=20
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -77,12 +77,15 @@
 static void	list_item_verbose(struct bsdtar *, FILE *,
 		    struct archive_entry *);
 static void	read_archive(struct bsdtar *bsdtar, char mode, struct archive =
*);
+static int unmatched_inclusions_warn(struct archive *matching, const char =
*);
+
=20
 void
 tar_mode_t(struct bsdtar *bsdtar)
 {
 	read_archive(bsdtar, 't', NULL);
-	if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archiv=
e") !=3D 0)
+	if (unmatched_inclusions_warn(bsdtar->matching,
+	    "Not found in archive") !=3D 0)
 		bsdtar->return_value =3D 1;
 }
=20
@@ -100,7 +103,8 @@
=20
 	read_archive(bsdtar, 'x', writer);
=20
-	if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archiv=
e") !=3D 0)
+	if (unmatched_inclusions_warn(bsdtar->matching,
+	    "Not found in archive") !=3D 0)
 		bsdtar->return_value =3D 1;
 	archive_write_free(writer);
 }
@@ -152,17 +156,21 @@
 	struct archive		 *a;
 	struct archive_entry	 *entry;
 	int			  r;
-	time_t			  sec;
-	long			  nsec;
=20
 	while (*bsdtar->argv) {
-		lafe_include(&bsdtar->matching, *bsdtar->argv);
+		if (archive_match_include_pattern(bsdtar->matching,
+		    *bsdtar->argv) !=3D ARCHIVE_OK)
+			lafe_errc(1, 0, "Error inclusion pattern: %s",
+			    archive_error_string(bsdtar->matching));
 		bsdtar->argv++;
 	}
=20
 	if (bsdtar->names_from_file !=3D NULL)
-		lafe_include_from_file(&bsdtar->matching,
-		    bsdtar->names_from_file, bsdtar->option_null);
+		if (archive_match_include_pattern_from_file(
+		    bsdtar->matching, bsdtar->names_from_file,
+		    bsdtar->option_null) !=3D ARCHIVE_OK)
+			lafe_errc(1, 0, "Error inclusion pattern: %s",
+			    archive_error_string(bsdtar->matching));
=20
 	a =3D archive_read_new();
 	if (bsdtar->compress_program !=3D NULL)
@@ -199,7 +207,7 @@
 	for (;;) {
 		/* Support --fast-read option */
 		if (bsdtar->option_fast_read &&
-		    lafe_unmatched_inclusions(bsdtar->matching) =3D=3D 0)
+		    archive_match_path_unmatched_inclusions(bsdtar->matching) =3D=3D 0)
 			break;
=20
 		r =3D archive_read_next_header(a, &entry);
@@ -232,42 +240,6 @@
 			archive_entry_set_gname(entry, bsdtar->gname);
=20
 		/*
-		 * Exclude entries that are too old.
-		 */
-		if (bsdtar->newer_ctime_filter) {
-			/* Use ctime if format provides, else mtime. */
-			if (archive_entry_ctime_is_set(entry)) {
-				sec =3D archive_entry_ctime(entry);
-				nsec =3D archive_entry_ctime_nsec(entry);
-			} else if (archive_entry_mtime_is_set(entry)) {
-				sec =3D archive_entry_mtime(entry);
-				nsec =3D archive_entry_mtime_nsec(entry);
-			} else {
-				sec =3D 0;
-				nsec =3D 0;
-			}
-			if (sec < bsdtar->newer_ctime_sec)
-				continue; /* Too old, skip it. */
-			if (sec =3D=3D bsdtar->newer_ctime_sec
-			    && nsec <=3D bsdtar->newer_ctime_nsec)
-				continue; /* Too old, skip it. */
-		}
-		if (bsdtar->newer_mtime_filter) {
-			if (archive_entry_mtime_is_set(entry)) {
-				sec =3D archive_entry_mtime(entry);
-				nsec =3D archive_entry_mtime_nsec(entry);
-			} else {
-				sec =3D 0;
-				nsec =3D 0;
-			}
-			if (sec < bsdtar->newer_mtime_sec)
-				continue; /* Too old, skip it. */
-			if (sec =3D=3D bsdtar->newer_mtime_sec
-			    && nsec <=3D bsdtar->newer_mtime_nsec)
-				continue; /* Too old, skip it. */
-		}
-
-		/*
 		 * Note that pattern exclusions are checked before
 		 * pathname rewrites are handled.  This gives more
 		 * control over exclusions, since rewrites always lose
@@ -276,7 +248,7 @@
 		 * rewrite, there would be no way to exclude foo1/bar
 		 * while allowing foo2/bar.)
 		 */
-		if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry)))
+		if (archive_match_excluded(bsdtar->matching, entry))
 			continue; /* Excluded by a pattern test. */
=20
 		if (mode =3D=3D 't') {
@@ -471,3 +443,21 @@
 	else if (archive_entry_symlink(entry)) /* Symbolic link */
 		safe_fprintf(out, " -> %s", archive_entry_symlink(entry));
 }
+
+static int
+unmatched_inclusions_warn(struct archive *matching, const char *msg)
+{
+	const char *p;
+	int r;
+
+	if (matching =3D=3D NULL)
+		return (0);
+
+	while ((r =3D archive_match_path_unmatched_inclusions_next(
+	    matching, &p)) =3D=3D ARCHIVE_OK)
+		lafe_warnc(0, "%s: %s", p, msg);
+	if (r =3D=3D ARCHIVE_FATAL)
+		lafe_errc(1, errno, "Out of memory");
+
+	return (archive_match_path_unmatched_inclusions(matching));
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/test/main.c
--- a/head/contrib/libarchive/tar/test/main.c	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/tar/test/main.c	Fri Aug 10 14:19:25 2012 +0300
@@ -24,6 +24,9 @@
  */
=20
 #include "test.h"
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
@@ -31,6 +34,16 @@
 #ifdef HAVE_ICONV_H
 #include <iconv.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
 #include <limits.h>
 #include <locale.h>
 #ifdef HAVE_SIGNAL_H
@@ -46,7 +59,7 @@
  * TODO: Move this into a separate configuration header, have all test
  * suites share one copy of this file.
  */
-__FBSDID("$FreeBSD: head/contrib/libarchive/tar/test/main.c 232153 2012-02=
-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/tar/test/main.c 238856 2012-07=
-28 06:38:44Z mm $");
 #define KNOWNREF	"test_patterns_2.tar.uu"
 #define ENVBASE "BSDTAR"  /* Prefix for environment variables. */
 #define	PROGRAM "bsdtar"  /* Name of program being tested. */
@@ -116,7 +129,14 @@
 #endif
=20
 #if defined(_WIN32) && !defined(__CYGWIN__)
-void *GetFunctionKernel32(const char *name)
+static void	*GetFunctionKernel32(const char *);
+static int	 my_CreateSymbolicLinkA(const char *, const char *, int);
+static int	 my_CreateHardLinkA(const char *, const char *);
+static int	 my_GetFileInformationByName(const char *,
+		     BY_HANDLE_FILE_INFORMATION *);
+
+static void *
+GetFunctionKernel32(const char *name)
 {
 	static HINSTANCE lib;
 	static int set;
@@ -155,7 +175,7 @@
 	return f =3D=3D NULL ? 0 : (*f)(linkname, target, NULL);
 }
=20
-int
+static int
 my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *=
bhfi)
 {
 	HANDLE h;
@@ -1507,7 +1527,7 @@
 /* Create a file with the specified contents and report any failures. */
 int
 assertion_make_file(const char *file, int line,
-    const char *path, int mode, const char *contents)
+    const char *path, int mode, int csize, const void *contents)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
 	/* TODO: Rework this to set file mode as well. */
@@ -1521,8 +1541,13 @@
 		return (0);
 	}
 	if (contents !=3D NULL) {
-		if (strlen(contents)
-		    !=3D fwrite(contents, 1, strlen(contents), f)) {
+		size_t wsize;
+
+		if (csize < 0)
+			wsize =3D strlen(contents);
+		else
+			wsize =3D (size_t)csize;
+		if (wsize !=3D fwrite(contents, 1, wsize, f)) {
 			fclose(f);
 			failure_start(file, line,
 			    "Could not write file %s", path);
@@ -1542,10 +1567,16 @@
 		return (0);
 	}
 	if (contents !=3D NULL) {
-		if ((ssize_t)strlen(contents)
-		    !=3D write(fd, contents, strlen(contents))) {
+		ssize_t wsize;
+
+		if (csize < 0)
+			wsize =3D (ssize_t)strlen(contents);
+		else
+			wsize =3D (ssize_t)csize;
+		if (wsize !=3D write(fd, contents, wsize)) {
 			close(fd);
-			failure_start(file, line, "Could not write to %s", path);
+			failure_start(file, line,
+			    "Could not write to %s", path);
 			failure_finish(NULL);
 			return (0);
 		}
@@ -1716,6 +1747,52 @@
 #endif /* defined(_WIN32) && !defined(__CYGWIN__) */
 }
=20
+/* Set nodump, report failures. */
+int
+assertion_nodump(const char *file, int line, const char *pathname)
+{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+	int r;
+
+	assertion_count(file, line);
+	r =3D chflags(pathname, UF_NODUMP);
+	if (r < 0) {
+		failure_start(file, line, "Can't set nodump %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS=
)\
+	 && defined(EXT2_NODUMP_FL)
+	int fd, r, flags;
+
+	assertion_count(file, line);
+	fd =3D open(pathname, O_RDONLY | O_NONBLOCK);
+	if (fd < 0) {
+		failure_start(file, line, "Can't open %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0) {
+		failure_start(file, line, "Can't get flags %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	flags |=3D EXT2_NODUMP_FL;
+	r =3D ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+	if (r < 0) {
+		failure_start(file, line, "Can't set nodump %s\n", pathname);
+		failure_finish(NULL);
+		return (0);
+	}
+	close(fd);
+#else
+	(void)pathname; /* UNUSED */
+	assertion_count(file, line);
+#endif
+	return (1);
+}
+
 /*
  *
  *  UTILITIES for use by tests.
@@ -1744,7 +1821,7 @@
 		return (value);
=20
 	++tested;
-	assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+	assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
 	/* Note: Cygwin has its own symlink() emulation that does not
 	 * use the Win32 CreateSymbolicLink() function. */
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1794,6 +1871,70 @@
 }
=20
 /*
+ * Can this filesystem handle nodump flags.
+ */
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+
+int
+canNodump(void)
+{
+	const char *path =3D "cannodumptest";
+	struct stat sb;
+
+	assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
+	if (chflags(path, UF_NODUMP) < 0)
+		return (0);
+	if (stat(path, &sb) < 0)
+		return (0);
+	if (sb.st_flags & UF_NODUMP)
+		return (1);
+	return (0);
+}
+
+#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS=
)\
+	 && defined(EXT2_NODUMP_FL)
+
+int
+canNodump(void)
+{
+	const char *path =3D "cannodumptest";
+	int fd, r, flags;
+
+	assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
+	fd =3D open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return (0);
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	flags |=3D EXT2_NODUMP_FL;
+	r =3D ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	close(fd);
+	fd =3D open(path, O_RDONLY | O_NONBLOCK);
+	if (fd < 0)
+		return (0);
+	r =3D ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+	if (r < 0)
+		return (0);
+	close(fd);
+	if (flags & EXT2_NODUMP_FL)
+		return (1);
+	return (0);
+}
+
+#else
+
+int
+canNodump()
+{
+	return (0);
+}
+
+#endif
+
+/*
  * Sleep as needed; useful for verifying disk timestamp changes by
  * ensuring that the wall-clock time has actually changed before we
  * go back to re-read something from disk.
@@ -2236,17 +2377,77 @@
 	return strdup(buff);
 }
=20
+static int
+get_test_set(int *test_set, int limit, const char *test)
+{
+	int start, end;
+	int idx =3D 0;
+
+	if (test =3D=3D NULL) {
+		/* Default: Run all tests. */
+		for (;idx < limit; idx++)
+			test_set[idx] =3D idx;
+		return (limit);
+	}
+	if (*test >=3D '0' && *test <=3D '9') {
+		const char *vp =3D test;
+		start =3D 0;
+		while (*vp >=3D '0' && *vp <=3D '9') {
+			start *=3D 10;
+			start +=3D *vp - '0';
+			++vp;
+		}
+		if (*vp =3D=3D '\0') {
+			end =3D start;
+		} else if (*vp =3D=3D '-') {
+			++vp;
+			if (*vp =3D=3D '\0') {
+				end =3D limit - 1;
+			} else {
+				end =3D 0;
+				while (*vp >=3D '0' && *vp <=3D '9') {
+					end *=3D 10;
+					end +=3D *vp - '0';
+					++vp;
+				}
+			}
+		} else
+			return (-1);
+		if (start < 0 || end >=3D limit || start > end)
+			return (-1);
+		while (start <=3D end)
+			test_set[idx++] =3D start++;
+	} else {
+		size_t len =3D strlen(test);
+		for (start =3D 0; start < limit; ++start) {
+			const char *name =3D tests[start].name;
+			const char *p;
+
+			while ((p =3D strchr(name, test[0])) !=3D NULL) {
+				if (strncmp(p, test, len) =3D=3D 0) {
+					test_set[idx++] =3D start;
+					break;
+				} else
+					name =3D p + 1;
+			}
+
+		}
+	}
+	return ((idx =3D=3D 0)?-1:idx);
+}
+
 int
 main(int argc, char **argv)
 {
 	static const int limit =3D sizeof(tests) / sizeof(tests[0]);
-	int i =3D 0, j =3D 0, start, end, tests_run =3D 0, tests_failed =3D 0, op=
tion;
+	int test_set[sizeof(tests) / sizeof(tests[0])];
+	int i =3D 0, j =3D 0, tests_run =3D 0, tests_failed =3D 0, option;
 	time_t now;
 	char *refdir_alloc =3D NULL;
 	const char *progname;
 	char **saved_argv;
 	const char *tmp, *option_arg, *p;
-	char tmpdir[256], *pwd, *testprogdir, *tmp2 =3D NULL;
+	char tmpdir[256], *pwd, *testprogdir, *tmp2 =3D NULL, *vlevel =3D NULL;
 	char tmpdir_timestamp[256];
=20
 	(void)argc; /* UNUSED */
@@ -2332,6 +2533,19 @@
 	if (getenv(ENVBASE "_DEBUG") !=3D NULL)
 		dump_on_failure =3D 1;
=20
+	/* Allow -v to be controlled through the environment. */
+	if (getenv("_VERBOSITY_LEVEL") !=3D NULL)
+	{
+		vlevel =3D getenv("_VERBOSITY_LEVEL");
+		verbosity =3D atoi(vlevel);
+		if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL)
+		{
+			/* Unsupported verbosity levels are silently ignored */
+			vlevel =3D NULL;
+			verbosity =3D VERBOSITY_PASSFAIL;
+		}
+	}
+
 	/* Get the directory holding test files from environment. */
 	refdir =3D getenv(ENVBASE "_TEST_FILES");
=20
@@ -2379,7 +2593,8 @@
 #endif
 				break;
 			case 'q':
-				verbosity--;
+				if (!vlevel)
+					verbosity--;
 				break;
 			case 'r':
 				refdir =3D option_arg;
@@ -2388,7 +2603,8 @@
 				until_failure++;
 				break;
 			case 'v':
-				verbosity++;
+				if (!vlevel)
+					verbosity++;
 				break;
 			default:
 				fprintf(stderr, "Unrecognized option '%c'\n",
@@ -2501,78 +2717,27 @@
 	saved_argv =3D argv;
 	do {
 		argv =3D saved_argv;
-		if (*argv =3D=3D NULL) {
-			/* Default: Run all tests. */
-			for (i =3D 0; i < limit; i++) {
+		do {
+			int test_num;
+
+			test_num =3D get_test_set(test_set, limit, *argv);
+			if (test_num < 0) {
+				printf("*** INVALID Test %s\n", *argv);
+				free(refdir_alloc);
+				usage(progname);
+				return (1);
+			}
+			for (i =3D 0; i < test_num; i++) {
 				tests_run++;
-				if (test_run(i, tmpdir)) {
+				if (test_run(test_set[i], tmpdir)) {
 					tests_failed++;
 					if (until_failure)
 						goto finish;
 				}
 			}
-		} else {
-			while (*(argv) !=3D NULL) {
-				if (**argv >=3D '0' && **argv <=3D '9') {
-					char *vp =3D *argv;
-					start =3D 0;
-					while (*vp >=3D '0' && *vp <=3D '9') {
-						start *=3D 10;
-						start +=3D *vp - '0';
-						++vp;
-					}
-					if (*vp =3D=3D '\0') {
-						end =3D start;
-					} else if (*vp =3D=3D '-') {
-						++vp;
-						if (*vp =3D=3D '\0') {
-							end =3D limit - 1;
-						} else {
-							end =3D 0;
-							while (*vp >=3D '0' && *vp <=3D '9') {
-								end *=3D 10;
-								end +=3D *vp - '0';
-								++vp;
-							}
-						}
-					} else {
-						printf("*** INVALID Test %s\n", *argv);
-						free(refdir_alloc);
-						usage(progname);
-						return (1);
-					}
-					if (start < 0 || end >=3D limit || start > end) {
-						printf("*** INVALID Test %s\n", *argv);
-						free(refdir_alloc);
-						usage(progname);
-						return (1);
-					}
-				} else {
-					for (start =3D 0; start < limit; ++start) {
-						if (strcmp(*argv, tests[start].name) =3D=3D 0)
-							break;
-					}
-					end =3D start;
-					if (start >=3D limit) {
-						printf("*** INVALID Test ``%s''\n",
-						    *argv);
-						free(refdir_alloc);
-						usage(progname);
-						/* usage() never returns */
-					}
-				}
-				while (start <=3D end) {
-					tests_run++;
-					if (test_run(start, tmpdir)) {
-						tests_failed++;
-						if (until_failure)
-							goto finish;
-					}
-					++start;
-				}
+			if (*argv !=3D NULL)
 				argv++;
-			}
-		}
+		} while (*argv !=3D NULL);
 	} while (until_failure);
=20
 finish:
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/test/test.h
--- a/head/contrib/libarchive/tar/test/test.h	Mon Jul 30 11:44:18 2012 +0300
+++ b/head/contrib/libarchive/tar/test/test.h	Fri Aug 10 14:19:25 2012 +0300
@@ -22,7 +22,7 @@
  * (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/contrib/libarchive/tar/test/test.h 232153 2012-02-25 10:=
58:02Z mm $
+ * $FreeBSD: head/contrib/libarchive/tar/test/test.h 238856 2012-07-28 06:=
38:44Z mm $
  */
=20
 /* Every test program should #include "test.h" as the first thing. */
@@ -196,11 +196,15 @@
 #define assertMakeDir(dirname, mode)	\
   assertion_make_dir(__FILE__, __LINE__, dirname, mode)
 #define assertMakeFile(path, mode, contents) \
-  assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+  assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+  assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
 #define assertMakeHardlink(newfile, oldfile)	\
   assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
 #define assertMakeSymlink(newfile, linkto)	\
   assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertNodump(path)      \
+  assertion_nodump(__FILE__, __LINE__, path)
 #define assertUmask(mask)	\
   assertion_umask(__FILE__, __LINE__, mask)
 #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec)	\
@@ -243,9 +247,10 @@
 int assertion_is_reg(const char *, int, const char *, int);
 int assertion_is_symlink(const char *, int, const char *, const char *);
 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_file(const char *, int, const char *, int, int, const v=
oid *);
 int assertion_make_hardlink(const char *, int, const char *newpath, const =
char *);
 int assertion_make_symlink(const char *, int, const char *newpath, const c=
har *);
+int assertion_nodump(const char *, int, const char *);
 int assertion_non_empty_file(const char *, int, const char *);
 int assertion_text_file_contents(const char *, int, const char *buff, cons=
t char *f);
 int assertion_umask(const char *, int, int);
@@ -269,6 +274,9 @@
 /* Return true if this platform can run the "gunzip" program. */
 int canGunzip(void);
=20
+/* Return true if this filesystem can handle nodump flags. */
+int canNodump(void);
+
 /* Return true if the file has large i-node number(>0xffffffff). */
 int is_LargeInode(const char *);
=20
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/test/test_=
basic.c
--- a/head/contrib/libarchive/tar/test/test_basic.c	Mon Jul 30 11:44:18 201=
2 +0300
+++ b/head/contrib/libarchive/tar/test/test_basic.c	Fri Aug 10 14:19:25 201=
2 +0300
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/tar/test/test_basic.c 232153 2=
012-02-25 10:58:02Z mm $");
+__FBSDID("$FreeBSD: head/contrib/libarchive/tar/test/test_basic.c 238909 2=
012-07-30 14:47:35Z mm $");
=20
 static const char *
 make_files(void)
@@ -58,14 +58,19 @@
 	assertChdir(target);
=20
 	/* Regular file with 2 links. */
+	failure("%s", target);
 	assertIsReg("file", -1);
+	failure("%s", target);
 	assertFileSize("file", 10);
+	failure("%s", target);
 	assertFileContents("123456789", 10, "file");
 	failure("%s", target);
 	assertFileNLinks("file", 2);
=20
 	/* Another name for the same file. */
+	failure("%s", target);
 	assertIsReg("linkfile", -1);
+	failure("%s", target);
 	assertFileSize("linkfile", 10);
 	assertFileContents("123456789", 10, "linkfile");
 	assertFileNLinks("linkfile", 2);
@@ -76,6 +81,7 @@
 		assertIsSymlink("symlink", "file");
=20
 	/* dir */
+	failure("%s", target);
 	assertIsDir("dir", 0775);
 	assertChdir("..");
 }
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/test/test_=
format_newc.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/tar/test/test_format_newc.c	Fri Aug 10 14:19:=
25 2012 +0300
@@ -0,0 +1,64 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_format_newc)
+{
+
+	assertMakeFile("file1", 0644, "file1");
+	assertMakeFile("file2", 0644, "file2");
+	assertMakeHardlink("file3", "file1");
+
+	/* Test 1: Create an archive file with a newc format. */
+	assertEqualInt(0,
+	    systemf("%s -cf test1.cpio --format newc file1 file2 file3",
+	    testprog));
+	assertMakeDir("test1", 0755);
+	assertChdir("test1");
+	assertEqualInt(0,
+	    systemf("%s -xf ../test1.cpio >test.out 2>test.err", testprog));
+	assertFileContents("file1", 5, "file1");
+	assertFileContents("file2", 5, "file2");
+	assertFileContents("file1", 5, "file3");
+	assertEmptyFile("test.out");
+	assertEmptyFile("test.err");
+	assertChdir("..");
+
+	/* Test 2: Exclude one of hardlinked files. */
+	assertEqualInt(0,
+	    systemf("%s -cf test2.cpio --format newc file1 file2",
+	    testprog));
+	assertMakeDir("test2", 0755);
+	assertChdir("test2");
+	assertEqualInt(0,
+	    systemf("%s -xf ../test2.cpio >test.out 2>test.err", testprog));
+	assertFileContents("file1", 5, "file1");
+	assertFileContents("file2", 5, "file2");
+	assertFileNotExists("file3");
+	assertEmptyFile("test.out");
+	assertEmptyFile("test.err");
+	assertChdir("..");
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/test/test_=
getdate.c
--- a/head/contrib/libarchive/tar/test/test_getdate.c	Mon Jul 30 11:44:18 2=
012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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 WARRANTI=
ES
- * 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 US=
E,
- * 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/contrib/libarchive/tar/test/test_getdate.c 228763=
 2011-12-21 11:13:29Z mm $");
-
-#include <time.h>
-
-/*
- * Verify that the getdate() function works.
- */
-
-time_t get_date(time_t, const char *);
-
-DEFINE_TEST(test_getdate)
-{
-	time_t now =3D time(NULL);
-
-	assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0);
-	assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138);
-	assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980);
-	assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000);
-	assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460);
-	/* It's important that we handle ctime() format. */
-	assertEqualInt(get_date(now, "Sun Feb 22 17:38:26 PST 2009"),
-	    1235353106);
-	/* Basic relative offsets. */
-	/* If we use the actual current time as the reference, then
-	 * these tests break around DST changes, so it's actually
-	 * important to use a specific reference time here. */
-	assertEqualInt(get_date(0, "tomorrow"), 24 * 60 * 60);
-	assertEqualInt(get_date(0, "yesterday"), - 24 * 60 * 60);
-	assertEqualInt(get_date(0, "now + 1 hour"), 60 * 60);
-	assertEqualInt(get_date(0, "now + 1 hour + 1 minute"), 60 * 60 + 60);
-	/* Repeat the above for a different start time. */
-	now =3D 1231113600; /* Jan 5, 2009 00:00 UTC */
-	assertEqualInt(get_date(0, "Jan 5, 2009 00:00 UTC"), now);
-	assertEqualInt(get_date(now, "tomorrow"), now + 24 * 60 * 60);
-	assertEqualInt(get_date(now, "yesterday"), now - 24 * 60 * 60);
-	assertEqualInt(get_date(now, "now + 1 hour"), now + 60 * 60);
-	assertEqualInt(get_date(now, "now + 1 hour + 1 minute"),
-	    now + 60 * 60 + 60);
-	assertEqualInt(get_date(now, "tomorrow 5:16am UTC"),
-	    now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60);
-	assertEqualInt(get_date(now, "UTC 5:16am tomorrow"),
-	    now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60);
-
-	/* Jan 5, 2009 was a Monday. */
-	assertEqualInt(get_date(now, "monday UTC"), now);
-	assertEqualInt(get_date(now, "sunday UTC"), now + 6 * 24 * 60 * 60);
-	assertEqualInt(get_date(now, "tuesday UTC"), now + 24 * 60 * 60);
-	/* "next tuesday" is one week after "tuesday" */
-	assertEqualInt(get_date(now, "UTC next tuesday"),
-	    now + 8 * 24 * 60 * 60);
-	/* "last tuesday" is one week before "tuesday" */
-	assertEqualInt(get_date(now, "last tuesday UTC"),
-	    now - 6 * 24 * 60 * 60);
-	/* TODO: Lots more tests here. */
-}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/test/test_=
option_nodump.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/libarchive/tar/test/test_option_nodump.c	Fri Aug 10 14:1=
9:25 2012 +0300
@@ -0,0 +1,68 @@
+/*-
+ * 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 WARRANTI=
ES
+ * 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 US=
E,
+ * 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_nodump)
+{
+
+	if (!canNodump()) {
+		skipping("Can't test nodump on this filesystem");
+		return;
+	}
+
+	assertMakeFile("file1", 0644, "file1");
+	assertMakeFile("file2", 0644, "file2");
+	assertMakeFile("file3", 0644, "file3");
+	assertNodump("file2");
+
+	/* Test 1: Without --nodump */
+	assertEqualInt(0, systemf("%s -cf test1.tar file1 file2 file3",
+	    testprog));
+	assertMakeDir("test1", 0755);
+	assertChdir("test1");
+	assertEqualInt(0,
+	    systemf("%s -xf ../test1.tar >test.out 2>test.err", testprog));
+	assertFileContents("file1", 5, "file1");
+	assertFileContents("file2", 5, "file2");
+	assertFileContents("file3", 5, "file3");
+	assertEmptyFile("test.out");
+	assertEmptyFile("test.err");
+	assertChdir("..");
+
+	/* Test 2: With --nodump */
+	assertEqualInt(0, systemf("%s -cf test2.tar --nodump file1 file2 file3",
+	    testprog));
+	assertMakeDir("test2", 0755);
+	assertChdir("test2");
+	assertEqualInt(0,
+	    systemf("%s -xf ../test2.tar >test.out 2>test.err", testprog));
+	assertFileContents("file1", 5, "file1");
+	assertFileNotExists("file2");
+	assertFileContents("file3", 5, "file3");
+	assertEmptyFile("test.out");
+	assertEmptyFile("test.err");
+	assertChdir("..");
+}
diff -r 6b68d37bb4dc -r 2d798fd21d78 head/contrib/libarchive/tar/tree.c
--- a/head/contrib/libarchive/tar/tree.c	Mon Jul 30 11:44:18 2012 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,848 +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 WARRANTI=
ES
- * 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 US=
E,
- * 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 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).
- */
-#include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: head/contrib/libarchive/tar/tree.c 232153 2012-02-25 1=
0:58:02Z mm $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.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_WINDOWS_H) && !defined(__CYGWIN__)
-#include <windows.h>
-#endif
-
-#include "tree.h"
-
-/*
- * TODO:
- *    1) Loop checking.
- *    3) Arbitrary logical traversals by closing/reopening intermediate fd=
s.
- */
-
-struct tree_entry {
-	int depth;
-	struct tree_entry *next;
-	struct tree_entry *parent;
-	char *name;
-	size_t dirname_length;
-	dev_t dev;
-	ino_t ino;
-	int flags;
-	/* How to return back to the parent of a symlink. */
-#ifdef HAVE_FCHDIR
-	int symlink_parent_fd;
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-	char *symlink_parent_path;
-#else
-#error fchdir function required.
-#endif
-};
-
-/* 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;
-#if defined(_WIN32) && !defined(__CYGWIN__)
-	HANDLE d;
-	BY_HANDLE_FILE_INFORMATION fileInfo;
-#define	INVALID_DIR_HANDLE INVALID_HANDLE_VALUE
-	WIN32_FIND_DATA _findData;
-	WIN32_FIND_DATA *findData;
-#else
-	DIR	*d;
-#define	INVALID_DIR_HANDLE NULL
-	struct dirent *de;
-#endif
-	int	 flags;
-	int	 visit_type;
-	int	 tree_errno; /* Error code from last failed operation. */
-
-	/* Dynamically-sized buffer for holding path */
-	char	*buff;
-	size_t	 buff_length;
-
-	const char *basename; /* Last path element */
-	size_t	 dirname_length; /* Leading dir length */
-	size_t	 path_length; /* Total path length */
-
-	int	 depth;
-	int	 openCount;
-	int	 maxOpenCount;
-
-	struct stat	lst;
-	struct stat	st;
-};
-
-/* Definitions for tree.flags bitmap. */
-#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__)
-static int
-tree_dir_next_windows(struct tree *t, const char *pattern);
-#else
-static int
-tree_dir_next_posix(struct tree *t);
-#endif
-
-#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
-
-#include <stdio.h>
-void
-tree_dump(struct tree *t, FILE *out)
-{
-	char buff[300];
-	struct tree_entry *te;
-
-	fprintf(out, "\tdepth: %d\n", t->depth);
-	fprintf(out, "\tbuff: %s\n", t->buff);
-	fprintf(out, "\tpwd: %s\n", getcwd(buff, sizeof(buff)));
-	fprintf(out, "\tbasename: %s\n", t->basename);
-	fprintf(out, "\tstack:\n");
-	for (te =3D t->stack; te !=3D NULL; te =3D te->next) {
-		fprintf(out, "\t\t%s%d:\"%s\" %s%s%s%s%s%s\n",
-		    t->current =3D=3D te ? "*" : " ",
-		    te->depth,
-		    te->name,
-		    te->flags & needsFirstVisit ? "V" : "",
-		    te->flags & needsDescent ? "D" : "",
-		    te->flags & needsOpen ? "O" : "",
-		    te->flags & needsAscent ? "A" : "",
-		    te->flags & isDirLink ? "L" : "",
-		    (t->current =3D=3D te && t->d) ? "+" : ""
-		);
-	}
-}
-
-/*
- * Add a directory path to the current stack.
- */
-static void
-tree_push(struct tree *t, const char *path)
-{
-	struct tree_entry *te;
-
-	te =3D malloc(sizeof(*te));
-	memset(te, 0, sizeof(*te));
-	te->next =3D t->stack;
-	te->parent =3D t->current;
-	if (te->parent)
-		te->depth =3D te->parent->depth + 1;
-	t->stack =3D te;
-#ifdef HAVE_FCHDIR
-	te->symlink_parent_fd =3D -1;
-	te->name =3D strdup(path);
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-	te->symlink_parent_path =3D NULL;
-	te->name =3D strdup(path);
-#endif
-	te->flags =3D needsDescent | needsOpen | needsAscent;
-	te->dirname_length =3D t->dirname_length;
-}
-
-/*
- * Append a name to the current dir path.
- */
-static void
-tree_append(struct tree *t, const char *name, size_t name_length)
-{
-	char *p;
-	size_t size_needed;
-
-	if (t->buff !=3D NULL)
-		t->buff[t->dirname_length] =3D '\0';
-	/* Strip trailing '/' from name, unless entire name is "/". */
-	while (name_length > 1 && name[name_length - 1] =3D=3D '/')
-		name_length--;
-
-	/* Resize pathname buffer as needed. */
-	size_needed =3D name_length + 1 + t->dirname_length;
-	if (t->buff_length < size_needed) {
-		if (t->buff_length < 1024)
-			t->buff_length =3D 1024;
-		while (t->buff_length < size_needed)
-			t->buff_length *=3D 2;
-		t->buff =3D realloc(t->buff, t->buff_length);
-	}
-	if (t->buff =3D=3D NULL)
-		abort();
-	p =3D t->buff + t->dirname_length;
-	t->path_length =3D t->dirname_length + name_length;
-	/* Add a separating '/' if it's needed. */
-	if (t->dirname_length > 0 && p[-1] !=3D '/') {
-		*p++ =3D '/';
-		t->path_length ++;
-	}
-#if HAVE_STRNCPY_S
-	strncpy_s(p, t->buff_length - (p - t->buff), name, name_length);
-#else
-	strncpy(p, name, name_length);
-#endif
-	p[name_length] =3D '\0';
-	t->basename =3D p;
-}
-
-/*
- * Open a directory tree for traversal.
- */
-struct tree *
-tree_open(const char *path)
-{
-#ifdef HAVE_FCHDIR
-	struct tree *t;
-
-	t =3D malloc(sizeof(*t));
-	memset(t, 0, sizeof(*t));
-	/* First item is set up a lot like a symlink traversal. */
-	tree_push(t, path);
-	t->stack->flags =3D needsFirstVisit | isDirLink | needsAscent;
-	t->stack->symlink_parent_fd =3D open(".", O_RDONLY);
-	t->openCount++;
-	t->d =3D INVALID_DIR_HANDLE;
-	return (t);
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-	struct tree *t;
-	char *cwd =3D _getcwd(NULL, 0);
-	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 =3D MultiByteToWideChar(CP_OEMCP, 0, path, strlen(path), NULL, 0);
-	if (l =3D=3D 0)
-		abort();
-	wcs =3D malloc(sizeof(*wcs) * (l+1));
-	if (wcs =3D=3D NULL)
-		abort();
-	l =3D MultiByteToWideChar(CP_OEMCP, 0, path, strlen(path), wcs, l);
-	wcs[l] =3D L'\0';
-	wlen =3D l;
-	for (wp =3D wcs; *wp !=3D L'\0'; ++wp) {
-		if (*wp =3D=3D L'\\')
-			*wp =3D L'/';
-	}
-	l =3D WideCharToMultiByte(CP_OEMCP, 0, wcs, wlen, NULL, 0, NULL, NULL);
-	if (l =3D=3D 0)
-		abort();
-	pathname =3D malloc(l+1);
-	if (pathname =3D=3D NULL)
-		abort();
-	l =3D WideCharToMultiByte(CP_OEMCP, 0, wcs, wlen, pathname, l, NULL, NULL=
);
-	pathname[l] =3D '\0';
-	free(wcs);
-	base =3D pathname;
-#if defined(_WIN32) && !defined(__CYGWIN__)
-	/* ASCII version APIs do not accept the path which begin with
-	 * "//?/" prefix. */
-	if (strncmp(base, "//?/", 4) =3D=3D 0)
-		base +=3D 4;
-#endif
-
-	t =3D malloc(sizeof(*t));
-	memset(t, 0, sizeof(*t));
-	/* 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 (strchr(base, '*') || strchr(base, '?')) {
-		/* It has a wildcard in it... */
-		/* Separate the last element. */
-		p =3D strrchr(base, '/');
-		if (p !=3D NULL) {
-			*p =3D '\0';
-			chdir(base);
-			tree_append(t, base, p - base);
-			t->dirname_length =3D t->path_length;
-			base =3D p + 1;
-		}
-	}
-	tree_push(t, base);
-	free(pathname);
-	t->stack->flags =3D needsFirstVisit | isDirLink | needsAscent;
-	t->stack->symlink_parent_path =3D cwd;
-	t->d =3D INVALID_DIR_HANDLE;
-	return (t);
-#endif
-}
-
-/*
- * We've finished a directory; ascend back to the parent.
- */
-static int
-tree_ascend(struct tree *t)
-{
-	struct tree_entry *te;
-	int r =3D 0;
-
-	te =3D t->stack;
-	t->depth--;
-	if (te->flags & isDirLink) {
-#ifdef HAVE_FCHDIR
-		if (fchdir(te->symlink_parent_fd) !=3D 0) {
-			t->tree_errno =3D errno;
-			r =3D TREE_ERROR_FATAL;
-		}
-		close(te->symlink_parent_fd);
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-		if (SetCurrentDirectory(te->symlink_parent_path) =3D=3D 0) {
-			t->tree_errno =3D errno;
-			r =3D TREE_ERROR_FATAL;
-		}
-		free(te->symlink_parent_path);
-		te->symlink_parent_path =3D NULL;
-#endif
-		t->openCount--;
-	} else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
-		if (SetCurrentDirectory("..") =3D=3D 0) {
-#else
-		if (chdir("..") !=3D 0) {
-#endif
-			t->tree_errno =3D errno;
-			r =3D TREE_ERROR_FATAL;
-		}
-	}
-	return (r);
-}
-
-/*
- * Pop the working stack.
- */
-static void
-tree_pop(struct tree *t)
-{
-	struct tree_entry *te;
-
-	if (t->buff)
-		t->buff[t->dirname_length] =3D '\0';
-	if (t->stack =3D=3D t->current && t->current !=3D NULL)
-		t->current =3D t->current->parent;
-	te =3D t->stack;
-	t->stack =3D te->next;
-	t->dirname_length =3D te->dirname_length;
-	if (t->buff) {
-		t->basename =3D t->buff + t->dirname_length;
-		while (t->basename[0] =3D=3D '/')
-			t->basename++;
-	}
-	free(te->name);
-	free(te);
-}
-
-/*
- * Get the next item in the tree traversal.
- */
-int
-tree_next(struct tree *t)
-{
-	int r;
-
-	/* If we're called again after a fatal error, that's an API
-	 * violation.  Just crash now. */
-	if (t->visit_type =3D=3D TREE_ERROR_FATAL) {
-		fprintf(stderr, "Unable to continue traversing"
-		    " directory hierarchy after a fatal error.");
-		abort();
-	}
-
-	while (t->stack !=3D NULL) {
-		/* If there's an open dir, get the next entry from there. */
-		if (t->d !=3D INVALID_DIR_HANDLE) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
-			r =3D tree_dir_next_windows(t, NULL);
-#else
-			r =3D tree_dir_next_posix(t);
-#endif
-			if (r =3D=3D 0)
-				continue;
-			return (r);
-		}
-
-		if (t->stack->flags & needsFirstVisit) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
-			char *d =3D t->stack->name;
-			t->stack->flags &=3D ~needsFirstVisit;
-			if (strchr(d, '*') || strchr(d, '?')) {
-				r =3D tree_dir_next_windows(t, d);
-				if (r =3D=3D 0)
-					continue;
-				return (r);
-			}
-			/* Not a pattern, handle it as-is... */
-#endif
-			/* Top stack item needs a regular visit. */
-			t->current =3D t->stack;
-			tree_append(t, t->stack->name, strlen(t->stack->name));
-			/* t->dirname_length =3D t->path_length; */
-			/* tree_pop(t); */
-			t->stack->flags &=3D ~needsFirstVisit;
-			return (t->visit_type =3D TREE_REGULAR);
-		} else if (t->stack->flags & needsDescent) {
-			/* Top stack item is dir to descend into. */
-			t->current =3D t->stack;
-			tree_append(t, t->stack->name, strlen(t->stack->name));
-			t->stack->flags &=3D ~needsDescent;
-			/* If it is a link, set up fd for the ascent. */
-			if (t->stack->flags & isDirLink) {
-#ifdef HAVE_FCHDIR
-				t->stack->symlink_parent_fd =3D open(".", O_RDONLY);
-				t->openCount++;
-				if (t->openCount > t->maxOpenCount)
-					t->maxOpenCount =3D t->openCount;
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-				t->stack->symlink_parent_path =3D _getcwd(NULL, 0);
-#endif
-			}
-			t->dirname_length =3D t->path_length;
-#if defined(_WIN32) && !defined(__CYGWIN__)
-			if (t->path_length =3D=3D 259 || !SetCurrentDirectory(t->stack->name) !=
=3D 0)
-#else
-			if (chdir(t->stack->name) !=3D 0)
-#endif
-			{
-				/* c