From 8c8f03ca5b7f1f0d07c23e7c354a45b7c95335f0 Mon Sep 17 00:00:00 2001
From: Martin Matuska <mm@FreeBSD.org>
Date: Wed, 11 May 2016 10:10:11 +0000
Subject: [PATCH] Keep full libarchive distribution in vendor branch (prep for
 3.2.0 update)

---
 .gitattributes                                |    4 +
 .gitignore                                    |   84 +
 CMakeLists.txt                                | 1525 ++++++++++
 CTestConfig.cmake                             |   11 +
 INSTALL                                       |   35 +
 Makefile.am                                   | 1012 +++++++
 build/README.txt                              |   35 +
 build/autoconf/check_stdcall_func.m4          |   51 +
 build/autoconf/config.rpath                   |  696 +++++
 build/autoconf/iconv.m4                       |  268 ++
 build/autoconf/la_uid_t.m4                    |   20 +
 build/autoconf/lib-ld.m4                      |  109 +
 build/autoconf/lib-link.m4                    |  777 +++++
 build/autoconf/lib-prefix.m4                  |  224 ++
 build/autogen.sh                              |   67 +
 build/bump-version.sh                         |   36 +
 build/clean.sh                                |   97 +
 build/cmake/CheckFileOffsetBits.c             |   14 +
 build/cmake/CheckFileOffsetBits.cmake         |   44 +
 build/cmake/CheckFuncs.cmake                  |   49 +
 build/cmake/CheckFuncs_stub.c.in              |   16 +
 build/cmake/CheckHeaderDirent.cmake           |   32 +
 build/cmake/CheckStructMember.cmake           |   43 +
 build/cmake/CheckTypeExists.cmake             |   42 +
 build/cmake/FindLZMA.cmake                    |   48 +
 build/cmake/FindLibGCC.cmake                  |   22 +
 build/cmake/FindNettle.cmake                  |   23 +
 build/cmake/FindPCREPOSIX.cmake               |   34 +
 .../LibarchiveCheckCSourceCompiles.cmake      |  106 +
 build/cmake/LibarchiveCheckCSourceRuns.cmake  |  102 +
 build/cmake/config.h.in                       | 1143 ++++++++
 build/makerelease.sh                          |   58 +
 build/pkgconfig/libarchive.pc.in              |   11 +
 .../utils/gen_archive_string_composition_h.sh |  455 +++
 build/version                                 |    1 +
 configure.ac                                  |  788 ++++++
 contrib/README                                |   59 +
 contrib/libarchive.1aix53.spec                |  160 ++
 contrib/libarchive.spec                       |  147 +
 .../libarchive_autodetect-st_lib_archive.m4   |  154 +
 contrib/psota-benchmark/results.txt           |  136 +
 contrib/psota-benchmark/tcp.sh                |  110 +
 contrib/shar/Makefile                         |   14 +
 contrib/shar/shar.1                           |  128 +
 contrib/shar/shar.c                           |  314 +++
 contrib/shar/tree.c                           |  542 ++++
 contrib/shar/tree.h                           |  115 +
 contrib/shar/tree_config.h                    |   78 +
 contrib/untar.c                               |  225 ++
 cpio/CMakeLists.txt                           |   47 +
 cpio/config_freebsd.h                         |   56 +
 cpio/cpio_windows.c                           |  338 +++
 cpio/cpio_windows.h                           |   72 +
 cpio/test/CMakeLists.txt                      |   93 +
 doc/html/.ignore_me                           |    2 +
 doc/man/.ignore_me                            |    2 +
 doc/mdoc2man.awk                              |  391 +++
 doc/mdoc2wiki.awk                             |  451 +++
 doc/pdf/.ignore_me                            |    2 +
 doc/text/.ignore_me                           |    2 +
 doc/update.sh                                 |  119 +
 doc/wiki/.ignore_me                           |    2 +
 examples/minitar/Makefile                     |   26 +
 examples/minitar/README                       |   12 +
 examples/minitar/minitar.c                    |  458 +++
 examples/tarfilter.c                          |  113 +
 examples/untar.c                              |  266 ++
 libarchive/CMakeLists.txt                     |  193 ++
 libarchive/archive_entry_copy_bhfi.c          |   75 +
 libarchive/archive_read_disk_windows.c        | 2296 +++++++++++++++
 libarchive/archive_windows.c                  |  908 ++++++
 libarchive/archive_windows.h                  |  306 ++
 libarchive/archive_write_disk_windows.c       | 2502 +++++++++++++++++
 libarchive/config_freebsd.h                   |  160 ++
 libarchive/filter_fork_windows.c              |  190 ++
 libarchive/mtree.5                            |  269 ++
 libarchive/test/.cvsignore                    |   10 +
 libarchive/test/CMakeLists.txt                |  256 ++
 tar/CMakeLists.txt                            |   49 +
 tar/bsdtar_windows.c                          |  298 ++
 tar/bsdtar_windows.h                          |   60 +
 tar/config_freebsd.h                          |   84 +
 tar/test/CMakeLists.txt                       |  101 +
 tar/test/test_windows.c                       |  324 +++
 84 files changed, 20797 insertions(+)
 create mode 100644 .gitattributes
 create mode 100644 .gitignore
 create mode 100644 CMakeLists.txt
 create mode 100644 CTestConfig.cmake
 create mode 100644 INSTALL
 create mode 100644 Makefile.am
 create mode 100644 build/README.txt
 create mode 100644 build/autoconf/check_stdcall_func.m4
 create mode 100755 build/autoconf/config.rpath
 create mode 100644 build/autoconf/iconv.m4
 create mode 100644 build/autoconf/la_uid_t.m4
 create mode 100644 build/autoconf/lib-ld.m4
 create mode 100644 build/autoconf/lib-link.m4
 create mode 100644 build/autoconf/lib-prefix.m4
 create mode 100755 build/autogen.sh
 create mode 100755 build/bump-version.sh
 create mode 100755 build/clean.sh
 create mode 100644 build/cmake/CheckFileOffsetBits.c
 create mode 100644 build/cmake/CheckFileOffsetBits.cmake
 create mode 100644 build/cmake/CheckFuncs.cmake
 create mode 100644 build/cmake/CheckFuncs_stub.c.in
 create mode 100644 build/cmake/CheckHeaderDirent.cmake
 create mode 100644 build/cmake/CheckStructMember.cmake
 create mode 100644 build/cmake/CheckTypeExists.cmake
 create mode 100644 build/cmake/FindLZMA.cmake
 create mode 100644 build/cmake/FindLibGCC.cmake
 create mode 100644 build/cmake/FindNettle.cmake
 create mode 100644 build/cmake/FindPCREPOSIX.cmake
 create mode 100644 build/cmake/LibarchiveCheckCSourceCompiles.cmake
 create mode 100644 build/cmake/LibarchiveCheckCSourceRuns.cmake
 create mode 100644 build/cmake/config.h.in
 create mode 100755 build/makerelease.sh
 create mode 100644 build/pkgconfig/libarchive.pc.in
 create mode 100755 build/utils/gen_archive_string_composition_h.sh
 create mode 100644 build/version
 create mode 100644 configure.ac
 create mode 100644 contrib/README
 create mode 100644 contrib/libarchive.1aix53.spec
 create mode 100644 contrib/libarchive.spec
 create mode 100644 contrib/libarchive_autodetect-st_lib_archive.m4
 create mode 100644 contrib/psota-benchmark/results.txt
 create mode 100755 contrib/psota-benchmark/tcp.sh
 create mode 100644 contrib/shar/Makefile
 create mode 100644 contrib/shar/shar.1
 create mode 100644 contrib/shar/shar.c
 create mode 100644 contrib/shar/tree.c
 create mode 100644 contrib/shar/tree.h
 create mode 100644 contrib/shar/tree_config.h
 create mode 100644 contrib/untar.c
 create mode 100644 cpio/CMakeLists.txt
 create mode 100644 cpio/config_freebsd.h
 create mode 100644 cpio/cpio_windows.c
 create mode 100644 cpio/cpio_windows.h
 create mode 100644 cpio/test/CMakeLists.txt
 create mode 100644 doc/html/.ignore_me
 create mode 100644 doc/man/.ignore_me
 create mode 100755 doc/mdoc2man.awk
 create mode 100755 doc/mdoc2wiki.awk
 create mode 100644 doc/pdf/.ignore_me
 create mode 100644 doc/text/.ignore_me
 create mode 100755 doc/update.sh
 create mode 100644 doc/wiki/.ignore_me
 create mode 100644 examples/minitar/Makefile
 create mode 100644 examples/minitar/README
 create mode 100644 examples/minitar/minitar.c
 create mode 100644 examples/tarfilter.c
 create mode 100644 examples/untar.c
 create mode 100644 libarchive/CMakeLists.txt
 create mode 100644 libarchive/archive_entry_copy_bhfi.c
 create mode 100644 libarchive/archive_read_disk_windows.c
 create mode 100644 libarchive/archive_windows.c
 create mode 100644 libarchive/archive_windows.h
 create mode 100644 libarchive/archive_write_disk_windows.c
 create mode 100644 libarchive/config_freebsd.h
 create mode 100644 libarchive/filter_fork_windows.c
 create mode 100644 libarchive/mtree.5
 create mode 100644 libarchive/test/.cvsignore
 create mode 100644 libarchive/test/CMakeLists.txt
 create mode 100644 tar/CMakeLists.txt
 create mode 100644 tar/bsdtar_windows.c
 create mode 100644 tar/bsdtar_windows.h
 create mode 100644 tar/config_freebsd.h
 create mode 100644 tar/test/CMakeLists.txt
 create mode 100644 tar/test/test_windows.c

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000000..496519561edf
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,4 @@
+.git*            export-ignore
+
+*.sh             crlf=input
+config.rpath     crlf=input
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..3609145920ca
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,84 @@
+*.o
+*.exe
+*.lo
+*.cmake
+.libs/
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache/
+bsdcpio
+bsdcpio_test
+bsdtar
+bsdtar_test
+build/autoconf/compile
+build/autoconf/config.guess
+build/autoconf/config.sub
+build/autoconf/depcomp
+build/autoconf/install-sh
+build/autoconf/libtool.m4
+build/autoconf/ltmain.sh
+build/autoconf/ltoptions.m4
+build/autoconf/ltsugar.m4
+build/autoconf/ltversion.m4
+build/autoconf/lt~obsolete.m4
+build/autoconf/missing
+build/pkgconfig/libarchive.pc
+config.h
+config.h.in
+config.h.in~
+config.log
+config.status
+configure
+cpio/.deps/
+cpio/.dirstamp
+cpio/test/.deps/
+cpio/test/.dirstamp
+cpio/test/list.h
+libarchive.la
+libarchive/.deps/
+libarchive/.dirstamp
+libarchive/test/.deps/
+libarchive/test/.dirstamp
+libarchive/test/list.h
+libarchive_fe.la
+libarchive_fe/.deps/
+libarchive_fe/.dirstamp
+libarchive_test
+libtool
+stamp-h1
+tar/.deps/
+tar/.dirstamp
+tar/test/.deps/
+tar/test/.dirstamp
+tar/test/list.h
+CMakeCache.txt
+CMakeFiles/
+DartConfiguration.tcl
+cmake.tmp/
+cpio/CMakeFiles/
+cpio/test/CMakeFiles/
+libarchive/CMakeFiles/
+libarchive/test/CMakeFiles/
+tar/CMakeFiles/
+tar/test/CMakeFiles/
+test_utils/.deps/
+test_utils/.dirstamp
+
+doc/html/*.html
+doc/man/*.1
+doc/man/*.3
+doc/man/*.5
+doc/pdf/*.pdf
+doc/text/*.txt
+doc/wiki/*.wiki
+
+libarchive-*.tar.gz
+libarchive-*.zip
+
+Testing/
+libarchive/libarchive.a
+libarchive/libarchive.so
+libarchive/libarchive.so.*
+
+.DS_Store
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000000..2cdb9fb48585
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,1525 @@
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.6 FATAL_ERROR)
+#
+PROJECT(libarchive C)
+#
+SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
+if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
+endif()
+#
+# Set the Build type for make based generators.
+# You can choose following types:
+#   Debug          : Debug build
+#   Release        : Release build
+#   RelWithDebInfo : Release build with Debug Info
+#   MinSizeRel     : Release Min Size build
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
+# value type is "UNINITIALIZED".
+GET_PROPERTY(cached_type CACHE CMAKE_BUILD_TYPE PROPERTY TYPE)
+IF("${cached_type}" STREQUAL "UNINITIALIZED")
+  SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE)
+ENDIF("${cached_type}" STREQUAL "UNINITIALIZED")
+# Check the Build Type.
+IF(NOT "${CMAKE_BUILD_TYPE}"
+       MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+  MESSAGE(FATAL_ERROR
+          "Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
+          "Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel")
+ENDIF(NOT "${CMAKE_BUILD_TYPE}"
+          MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+
+# On MacOS, prefer MacPorts libraries to system libraries.
+# I haven't come up with a compelling argument for this to be conditional.
+list(APPEND CMAKE_PREFIX_PATH /opt/local)
+
+#
+# Version - read from 'version' file.
+#
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/build/version _version)
+STRING(REGEX REPLACE
+ "^([0-9])[0-9][0-9][0-9][0-9][0-9][0-9][a-z]?$" "\\1" _major ${_version})
+STRING(REGEX REPLACE
+ "^[0-9]([0-9][0-9][0-9])[0-9][0-9][0-9][a-z]?$" "\\1" _minor ${_version})
+STRING(REGEX REPLACE
+ "^[0-9][0-9][0-9][0-9]([0-9][0-9][0-9])[a-z]?$" "\\1" _revision ${_version})
+STRING(REGEX REPLACE
+ "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]([a-z]?)$" "\\1" _quality ${_version})
+SET(_version_number ${_major}${_minor}${_revision})
+STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_minor ${_minor})
+STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_revision ${_revision})
+#
+SET(VERSION                    "${_major}.${_trimmed_minor}.${_trimmed_revision}${_quality}")
+SET(BSDCPIO_VERSION_STRING     "${VERSION}")
+SET(BSDTAR_VERSION_STRING      "${VERSION}")
+SET(LIBARCHIVE_VERSION_NUMBER  "${_version_number}")
+SET(LIBARCHIVE_VERSION_STRING  "${VERSION}")
+
+# INTERFACE_VERSION increments with every release
+# libarchive 2.7 == interface version 9 = 2 + 7 
+# libarchive 2.8 == interface version 10 = 2 + 8
+# libarchive 2.9 == interface version 11 = 2 + 9
+# libarchive 3.0 == interface version 12
+# libarchive 3.1 == interface version 13
+math(EXPR INTERFACE_VERSION  "13 + ${_minor}")
+
+# Set SOVERSION == Interface version
+# ?? Should there be more here ??
+SET(SOVERSION "${INTERFACE_VERSION}")
+
+# Enalbe CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros
+# saving and restoring the state of the variables.
+INCLUDE(CMakePushCheckState)
+
+# Initialize the state of the variables. This initialization is not
+# necessary but this shows you what value the variables initially have.
+SET(CMAKE_REQUIRED_DEFINITIONS)
+SET(CMAKE_REQUIRED_INCLUDES)
+SET(CMAKE_REQUIRED_LIBRARIES)
+SET(CMAKE_REQUIRED_FLAGS)
+
+# Especially for early development, we want to be a little
+# aggressive about diagnosing build problems; this can get
+# relaxed somewhat in final shipping versions.
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+  SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
+  #################################################################
+  # Set compile flags for all build types.
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
+  #################################################################
+  # Set compile flags for debug build.
+  # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror -Wextra -Wunused")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+IF (MSVC)
+  #################################################################
+  # Set compile flags for debug build.
+  # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
+  # Enable level 4 C4061: The enumerate has no associated handler in a switch
+  #                       statement.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4061")
+  # Enable level 4 C4254: A larger bit field was assigned to a smaller bit
+  #                       field.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4254")
+  # Enable level 4 C4295: An array was initialized but the last character in
+  #                       the array is not a null; accessing the array may
+  #                       produce unexpected results.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4295")
+  # Enable level 4 C4296: An unsigned variable was used in a comparison
+  #                       operation with zero.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4296")
+  # Enable level 4 C4389: An operation involved signed and unsigned variables.
+  #                       This could result in a loss of data.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4389")
+  # Enable level 4 C4505: The given function is local and not referenced in
+  #                       the body of the module; therefore, the function is
+  #                       dead code.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4505")
+  # Enable level 4 C4514: The optimizer removed an inline function that is not
+  #                       called.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4514")
+  # Enable level 4 C4702: Unreachable code.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4702")
+  # Enable level 4 C4706: The test value in a conditional expression was the
+  #                       result of an assignment.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706")
+  # /WX option is the same as gcc's -Werror option.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /WX")
+  # /Oi option enables built-in functions.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
+  #################################################################
+  # Set compile flags for release build.
+  SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi")
+ENDIF (MSVC)
+
+# Enable CTest/CDash support
+include(CTest)
+
+OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
+OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
+OPTION(ENABLE_TAR "Enable tar building" ON)
+OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE)
+OPTION(ENABLE_CPIO "Enable cpio building" ON)
+OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
+OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
+OPTION(ENABLE_ACL "Enable ACL support" ON)
+OPTION(ENABLE_ICONV "Enable iconv support" ON)
+OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
+SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
+SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
+SET(WINDOWS_VERSION "" CACHE STRING "Set Windows version to use (Windows only)")
+
+IF(ENABLE_TEST)
+	ENABLE_TESTING()
+ENDIF(ENABLE_TEST)
+
+IF(WIN32)
+  IF(WINDOWS_VERSION STREQUAL "WIN8")
+    SET(WINVER 0x0602)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WIN7")
+    SET(WINVER 0x0601)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WS08")
+    SET(WINVER 0x0600)
+  ELSEIF(WINDOWS_VERSION STREQUAL "VISTA")
+    SET(WINVER 0x0600)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WS03")
+    SET(WINVER 0x0502)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
+    SET(WINVER 0x0501)
+  ELSE(WINDOWS_VERSION STREQUAL "WIN8")
+    # The default is to use Windows 2000 API.
+    SET(WINVER 0x0500)
+  ENDIF(WINDOWS_VERSION STREQUAL "WIN8")
+  SET(_WIN32_WINNT ${WINVER})
+ENDIF(WIN32)
+
+IF(MSVC)
+  IF(ENABLE_SAFESEH STREQUAL "YES")
+    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH")
+    SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH")
+    SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH")
+	SET(CMAKE_REQUIRED_LINKER_FLAGS "/SAFESEH")
+  ELSEIF(ENABLE_SAFESEH STREQUAL "NO")
+    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
+    SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
+    SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
+	SET(CMAKE_REQUIRED_LINKER_FLAGS "/SAFESEH:NO")
+  ENDIF(ENABLE_SAFESEH STREQUAL "YES")
+ENDIF(MSVC)
+
+IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
+  ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
+ENDIF()
+
+#
+INCLUDE(LibarchiveCheckCSourceCompiles)
+INCLUDE(LibarchiveCheckCSourceRuns)
+INCLUDE(CheckFileOffsetBits)
+INCLUDE(CheckFuncs)
+INCLUDE(CheckHeaderDirent)
+INCLUDE(CheckIncludeFile)
+INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckLibraryExists)
+INCLUDE(CheckStructMember)
+INCLUDE(CheckSymbolExists)
+INCLUDE(CheckTypeExists)
+INCLUDE(CheckTypeSize)
+
+#
+# Generate list.h
+#
+MACRO (GENERATE_LIST_H _listfile _cmlist __list_sources)
+  SET(_argv ${ARGV})
+  # Remove _listfile and _cmlist from _argv
+  LIST(REMOVE_AT _argv 0 1)
+  IF (NOT EXISTS "${_listfile}" OR
+     ${_cmlist} IS_NEWER_THAN "${_listfile}")
+
+    MESSAGE(STATUS "Generating ${_listfile}")
+    FILE(WRITE ${_listfile} "")
+    FOREACH (testfile ${_argv})
+      IF (testfile MATCHES "^test_[^/]+[.]c$")
+        FILE(STRINGS ${testfile} testvar REGEX "^DEFINE_TEST")
+        FOREACH (deftest ${testvar})
+          FILE(APPEND ${_listfile} "${deftest}\n")
+        ENDFOREACH (deftest)
+      ENDIF (testfile MATCHES "^test_[^/]+[.]c$")
+    ENDFOREACH (testfile)
+
+  ENDIF (NOT EXISTS "${_listfile}" OR
+     ${_cmlist} IS_NEWER_THAN "${_listfile}")
+ENDMACRO (GENERATE_LIST_H)
+#
+# Generate installation rules for man pages.
+#
+MACRO (INSTALL_MAN __mans)
+  FOREACH (_man ${ARGV})
+    STRING(REGEX REPLACE "^.+[.]([1-9])" "\\1" _mansect ${_man})
+    INSTALL(FILES ${_man} DESTINATION "share/man/man${_mansect}")
+  ENDFOREACH (_man)
+ENDMACRO (INSTALL_MAN __mans)
+#
+# Find out what macro is needed to use libraries on Windows.
+#
+MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
+       TRY_TYPE SAMPLE_SOURCE MACRO_LIST)
+  IF(WIN32 AND NOT CYGWIN)
+    CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+    SET(CMAKE_REQUIRED_INCLUDES ${INCLUDES})
+    SET(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES})
+    FOREACH(VAR ${MACRO_LIST})
+      # Clear ${VAR} from CACHE If the libraries which ${VAR} was
+      # checked with are changed.
+      SET(VAR_WITH_LIB "${VAR}_WITH_LIB")
+      GET_PROPERTY(PREV_VAR_WITH_LIB VARIABLE PROPERTY ${VAR_WITH_LIB})
+      IF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
+        UNSET(${VAR} CACHE)
+      ENDIF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
+      # Check if the library can be used with the macro.
+      IF("${TRY_TYPE}" MATCHES "COMPILES")
+        LIBARCHIVE_CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
+      ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
+        LIBARCHIVE_CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
+      ELSE("${TRY_TYPE}" MATCHES "COMPILES")
+        MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
+      ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
+      # Save the libraries which ${VAR} is checked with.
+      SET(${VAR_WITH_LIB} "${LIBRARIES}" CACHE INTERNAL
+          "Macro ${VAR} is checked with")
+    ENDFOREACH(VAR)
+    CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+  ENDIF(WIN32 AND NOT CYGWIN)
+ENDMACRO (TRY_MACRO_FOR_LIBRARY)
+#
+# Check compress/decompress libraries
+#
+IF(WIN32 AND NOT CMAKE_CL_64 AND NOT CYGWIN)
+  # GnuWin32 is only for Win32, not Win64.
+  SET(__GNUWIN32PATH "C:/Program Files/GnuWin32")
+ENDIF(WIN32 AND NOT CMAKE_CL_64 AND NOT CYGWIN)
+IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
+  # You have to add a path availabel DLL file into PATH environment variable.
+  # Maybe DLL path is "C:/Program Files/GnuWin32/bin".
+  # The zlib and the bzip2 Setup program have installed programs and DLLs into
+  # "C:/Program Files/GnuWin32" by default.
+  # This is convenience setting for Windows.
+  SET(CMAKE_PREFIX_PATH ${__GNUWIN32PATH} $(CMAKE_PREFIX_PATH))
+  #
+  # If you didn't use Setup program or installed into nonstandard path,
+  # cmake cannot find out your zlib or bzip2 libraries and include files,
+  # you should execute cmake with  -DCMAKE_PREFIX_PATH option.
+  #   e.g.
+  #     cmake -DCMAKE_PREFIX_PATH=<your-GnuWin32-path> <path-to-source>
+  #
+  # If compiling error occured in zconf.h, You may need patch to zconf.h.
+  #--- zconf.h.orig	2005-07-21 00:40:26.000000000
+  #+++ zconf.h	2009-01-19 11:39:10.093750000
+  #@@ -286,7 +286,7 @@
+  # 
+  # #if 1           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+  # #  include <sys/types.h> /* for off_t */
+  #-#  include <unistd.h>    /* for SEEK_* and off_t */
+  #+#  include <stdio.h>    /* for SEEK_* and off_t */
+  # #  ifdef VMS
+  # #    include <unixio.h>   /* for off_t */
+  # #  endif
+ENDIF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
+
+SET(ADDITIONAL_LIBS "")
+#
+# Find ZLIB
+#
+FIND_PACKAGE(ZLIB)
+IF(ZLIB_FOUND)
+  SET(HAVE_LIBZ 1)
+  SET(HAVE_ZLIB_H 1)
+  INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${ZLIB_LIBRARIES})
+  IF(WIN32 AND NOT CYGWIN)
+    #
+    # Test if ZLIB_WINAPI macro is needed to use.
+    #
+    TRY_MACRO_FOR_LIBRARY(
+      "${ZLIB_INCLUDE_DIR}" "${ZLIB_LIBRARIES}"
+      RUNS
+      "#include <zlib.h>\nint main() {uLong f = zlibCompileFlags(); return (f&(1U<<10))?0:-1; }"
+      ZLIB_WINAPI)
+    IF(ZLIB_WINAPI)
+      ADD_DEFINITIONS(-DZLIB_WINAPI)
+    ELSE(ZLIB_WINAPI)
+      # Test if a macro is needed for the library.
+      TRY_MACRO_FOR_LIBRARY(
+        "${ZLIB_INCLUDE_DIR}" "${ZLIB_LIBRARIES}"
+        COMPILES
+        "#include <zlib.h>\nint main() {return zlibVersion()?1:0; }"
+        "ZLIB_DLL;WITHOUT_ZLIB_DLL")
+      IF(ZLIB_DLL)
+        ADD_DEFINITIONS(-DZLIB_DLL)
+      ENDIF(ZLIB_DLL)
+    ENDIF(ZLIB_WINAPI)
+  ENDIF(WIN32 AND NOT CYGWIN)
+ENDIF(ZLIB_FOUND)
+MARK_AS_ADVANCED(CLEAR ZLIB_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR ZLIB_LIBRARY)
+#
+# Find BZip2
+#
+FIND_PACKAGE(BZip2)
+IF(BZIP2_FOUND)
+  SET(HAVE_LIBBZ2 1)
+  SET(HAVE_BZLIB_H 1)
+  INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${BZIP2_LIBRARIES})
+  # Test if a macro is needed for the library.
+  TRY_MACRO_FOR_LIBRARY(
+    "${BZIP2_INCLUDE_DIR}" "${BZIP2_LIBRARIES}"
+    COMPILES
+    "#include <bzlib.h>\nint main() {return BZ2_bzlibVersion()?1:0; }"
+    "USE_BZIP2_DLL;USE_BZIP2_STATIC")
+  IF(USE_BZIP2_DLL)
+    ADD_DEFINITIONS(-DUSE_BZIP2_DLL)
+  ELSEIF(USE_BZIP2_STATIC)
+    ADD_DEFINITIONS(-DUSE_BZIP2_STATIC)
+  ENDIF(USE_BZIP2_DLL)
+ENDIF(BZIP2_FOUND)
+MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
+#
+# Find LZMA
+#
+FIND_PACKAGE(LZMA)
+IF(LZMA_FOUND)
+  SET(HAVE_LIBLZMA 1)
+  SET(HAVE_LZMA_H 1)
+  INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES})
+  # Test if a macro is needed for the library.
+  TRY_MACRO_FOR_LIBRARY(
+    "${LZMA_INCLUDE_DIR}" "${LZMA_LIBRARIES}"
+    COMPILES
+    "#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
+    "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
+  IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+    ADD_DEFINITIONS(-DLZMA_API_STATIC)
+  ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+ELSEIF(LZMADEC_FOUND)
+  SET(HAVE_LIBLZMADEC 1)
+  SET(HAVE_LZMADEC_H 1)
+  INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
+ENDIF(LZMA_FOUND)
+#
+# Find LZO2
+#
+IF (LZO2_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(LZO2_FIND_QUIETLY TRUE)
+ENDIF (LZO2_INCLUDE_DIR)
+
+FIND_PATH(LZO2_INCLUDE_DIR lzo/lzoconf.h)
+FIND_LIBRARY(LZO2_LIBRARY NAMES lzo2 liblzo2)
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO2 DEFAULT_MSG LZO2_LIBRARY LZO2_INCLUDE_DIR)
+IF(LZO2_FOUND)
+  SET(HAVE_LIBLZO2 1)
+  SET(HAVE_LZO_LZOCONF_H 1)
+  SET(HAVE_LZO_LZO1X_H 1)
+  INCLUDE_DIRECTORIES(${LZO2_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${LZO2_LIBRARY})
+  #
+  # TODO: test for static library.
+  #
+ENDIF(LZO2_FOUND)
+MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY)
+
+#
+# Check headers
+#
+CHECK_HEADER_DIRENT()
+
+SET(INCLUDES "")
+MACRO (LA_CHECK_INCLUDE_FILE header var)
+      CHECK_INCLUDE_FILES("${INCLUDES};${header}" ${var})
+      IF (${var})
+      	 SET(INCLUDES ${INCLUDES} ${header})
+      ENDIF (${var})
+ENDMACRO (LA_CHECK_INCLUDE_FILE)
+
+# Some FreeBSD headers assume sys/types.h was already included.
+LA_CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H)
+
+# Alphabetize the rest unless there's a compelling reason
+LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H)
+LA_CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H)
+LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H)
+LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H)
+LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
+LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
+LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
+
+LIBARCHIVE_CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
+#include <ext2fs/ext2_fs.h>
+int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
+
+LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
+LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
+LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
+LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
+LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
+LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H)
+LA_CHECK_INCLUDE_FILE("linux/types.h" HAVE_LINUX_TYPES_H)
+LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H)
+LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H)
+LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
+LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
+LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
+LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
+LA_CHECK_INCLUDE_FILE("poll.h" HAVE_POLL_H)
+LA_CHECK_INCLUDE_FILE("process.h" HAVE_PROCESS_H)
+LA_CHECK_INCLUDE_FILE("pwd.h" HAVE_PWD_H)
+LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
+LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H)
+LA_CHECK_INCLUDE_FILE("spawn.h" HAVE_SPAWN_H)
+LA_CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H)
+LA_CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
+LA_CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H)
+LA_CHECK_INCLUDE_FILE("string.h" HAVE_STRING_H)
+LA_CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
+LA_CHECK_INCLUDE_FILE("sys/acl.h" HAVE_SYS_ACL_H)
+LA_CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H)
+LA_CHECK_INCLUDE_FILE("sys/ioctl.h" HAVE_SYS_IOCTL_H)
+LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
+LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
+LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
+LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
+LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
+LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
+LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
+LA_CHECK_INCLUDE_FILE("sys/statvfs.h" HAVE_SYS_STATVFS_H)
+LA_CHECK_INCLUDE_FILE("sys/time.h" HAVE_SYS_TIME_H)
+LA_CHECK_INCLUDE_FILE("sys/utime.h" HAVE_SYS_UTIME_H)
+LA_CHECK_INCLUDE_FILE("sys/utsname.h" HAVE_SYS_UTSNAME_H)
+LA_CHECK_INCLUDE_FILE("sys/vfs.h" HAVE_SYS_VFS_H)
+LA_CHECK_INCLUDE_FILE("sys/wait.h" HAVE_SYS_WAIT_H)
+LA_CHECK_INCLUDE_FILE("time.h" HAVE_TIME_H)
+LA_CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H)
+LA_CHECK_INCLUDE_FILE("utime.h" HAVE_UTIME_H)
+LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
+LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
+LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
+# Following files need windwos.h, so we should test it after windows.h test.
+LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
+LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
+
+#
+# Check whether use of __EXTENSIONS__ is safe.
+# We need some macro such as _GNU_SOURCE to use extension functions.
+#
+SET(_INCLUDE_FILES)
+FOREACH (it ${_HEADER})
+   SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+ENDFOREACH (it)
+
+LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
+  "#define __EXTENSIONS__ 1
+   ${_INCLUDE_FILES}
+   int main() { return 0;}"
+ SAFE_TO_DEFINE_EXTENSIONS)
+
+#
+# Find Nettle
+#
+IF(ENABLE_NETTLE)
+  FIND_PACKAGE(Nettle)
+  IF(NETTLE_FOUND)
+    SET(HAVE_LIBNETTLE 1)
+    SET(HAVE_NETTLE_MD5_H 1)
+    SET(HAVE_NETTLE_RIPEMD160_H 1)
+    SET(HAVE_NETTLE_SHA_H 1)
+    INCLUDE_DIRECTORIES(${NETTLE_INCLUDE_DIR})
+    LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARIES})
+  ENDIF(NETTLE_FOUND)
+  MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR)
+  MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES)
+ENDIF(ENABLE_NETTLE)
+
+#
+# Find OpenSSL
+# (Except on Mac, where OpenSSL is deprecated.)
+#
+IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
+  FIND_PACKAGE(OpenSSL)
+ELSE()
+  SET(OPENSSL_FOUND FALSE) # Override cached value
+ENDIF()
+
+# FreeBSD libmd
+IF(NOT OPENSSL_FOUND)
+  CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND)
+  IF(LIBMD_FOUND)
+    CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+    SET(CMAKE_REQUIRED_LIBRARIES "md")
+    FIND_LIBRARY(LIBMD_LIBRARY NAMES md)
+    LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY})
+    CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+  ENDIF(LIBMD_FOUND)
+ENDIF(NOT OPENSSL_FOUND)
+
+#
+# How to prove that CRYPTO functions, which have several names on various
+# platforms, just see if archive_crypto.c can compile and link against
+# required libraries.
+#
+MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
+    FOREACH(ALGORITHM ${ALGORITHMS})
+      IF(NOT ARCHIVE_CRYPTO_${ALGORITHM})
+      STRING(TOLOWER "${ALGORITHM}" lower_algorithm)
+      STRING(TOUPPER "${ALGORITHM}" algorithm)
+      IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
+        SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+      ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND)
+        SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+      ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
+
+      IF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+        # Probe the local implementation for whether this
+	# crypto implementation is available on this platform.
+	SET(TRY_CRYPTO_REQUIRED_INCLUDES
+	  "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
+	SET(TRY_CRYPTO_REQUIRED_LIBS)
+	IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+	    SET(TRY_CRYPTO_REQUIRED_INCLUDES
+	      "${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
+	    SET(TRY_CRYPTO_REQUIRED_LIBS
+	        "-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
+	ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
+	    SET(TRY_CRYPTO_REQUIRED_INCLUDES
+	      "${TRY_CRYPTO_REQUIRED_INCLUDES};${NETTLE_INCLUDE_DIR}")
+	    SET(TRY_CRYPTO_REQUIRED_LIBS
+	        "-DLINK_LIBRARIES:STRING=${NETTLE_LIBRARY}")
+	ELSEIF("${IMPLEMENTATION}" MATCHES "^LIBMD$" AND LIBMD_FOUND)
+	    SET(TRY_CRYPTO_REQUIRED_LIBS
+	        "-DLINK_LIBRARIES:STRING=${LIBMD_LIBRARY}")
+	ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+
+    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
+	FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
+	     CONFDEFS_H)
+	FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_crypto.c"
+	     ARCHIVE_CRYPTO_C)
+
+	SET(SOURCE "${CONFDEFS_H}
+
+#define ARCHIVE_${algorithm}_COMPILE_TEST
+#define ARCHIVE_CRYPTO_${algorithm}_${IMPLEMENTATION}
+#define PLATFORM_CONFIG_H \"check_crypto_md.h\"
+
+${ARCHIVE_CRYPTO_C}
+
+int
+main(int argc, char **argv)
+{
+  archive_${lower_algorithm}_ctx ctx;
+  archive_${lower_algorithm}_init(&ctx);
+  archive_${lower_algorithm}_update(&ctx, *argv, argc);
+  archive_${lower_algorithm}_final(&ctx, NULL);
+  return 0;
+}
+")
+
+  FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.h" "")
+	FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
+	MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
+
+    IF(CMAKE_REQUIRED_LINKER_FLAGS)
+      SET(CHECK_CRYPTO_ADD_LINKER_FLAGS
+        "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
+    ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
+      SET(CHECK_CRYPTO_ADD_LINKER_FLAGS)
+    ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
+	TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
+	  ${CMAKE_BINARY_DIR}
+	  ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
+	  CMAKE_FLAGS ${CHECK_CRYPTO_ADD_LINKER_FLAGS}
+	   "${TRY_CRYPTO_REQUIRED_LIBS}"
+	   "${TRY_CRYPTO_REQUIRED_INCLUDES}"
+	  OUTPUT_VARIABLE OUTPUT)
+
+	# Inform user whether or not we found it; if not, log why we didn't.
+        IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+          MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- found")
+		  SET(ARCHIVE_CRYPTO_${ALGORITHM} 1)
+        ELSE (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+          MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- not found")
+          FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    	    "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} failed with the following output:\n"
+    	    "${OUTPUT}\n"
+    	    "Source file was:\n${SOURCE}\n")
+        ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+      ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+
+      # Add appropriate libs/includes depending on whether the implementation
+      # was found on this platform.
+      IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+        IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+          INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+	  LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
+	   LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
+        ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+      ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+      ENDIF(NOT ARCHIVE_CRYPTO_${ALGORITHM})
+    ENDFOREACH(ALGORITHM ${ALGORITHMS})
+ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
+
+#
+# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not
+# need the test what the functions can be mapped to archive_{crypto name}_init,
+# archive_{crypto name}_update and archive_{crypto name}_final.
+# The functions on Windows use CALG_{crypto name} macro to create a crypt object
+# and then we need to know what CALG_{crypto name} macros is available to show
+# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version
+# of Windows XP do not support SHA256, SHA384 and SHA512.
+#
+MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
+  IF(WIN32 AND NOT CYGWIN)
+    FOREACH(CRYPTO ${CRYPTO_LIST})
+      IF(NOT ARCHIVE_CRYPTO_${CRYPTO})
+      IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+	STRING(TOUPPER "${CRYPTO}" crypto)
+	SET(ALGID "")
+	IF ("${CRYPTO}" MATCHES "^MD5$")
+	    SET(ALGID "CALG_MD5")
+	ENDIF ("${CRYPTO}" MATCHES "^MD5$")
+	IF ("${CRYPTO}" MATCHES "^SHA1$")
+	    SET(ALGID "CALG_SHA1")
+	ENDIF ("${CRYPTO}" MATCHES "^SHA1$")
+	IF ("${CRYPTO}" MATCHES "^SHA256$")
+	    SET(ALGID "CALG_SHA_256")
+	ENDIF ("${CRYPTO}" MATCHES "^SHA256$")
+	IF ("${CRYPTO}" MATCHES "^SHA384$")
+	    SET(ALGID "CALG_SHA_384")
+	ENDIF ("${CRYPTO}" MATCHES "^SHA384$")
+	IF ("${CRYPTO}" MATCHES "^SHA512$")
+	    SET(ALGID "CALG_SHA_512")
+	ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
+
+    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
+	FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
+	     CONFDEFS_H)
+
+	SET(SOURCE "${CONFDEFS_H}
+
+#define ${crypto}_COMPILE_TEST
+#include <windows.h>
+#include <wincrypt.h>
+
+int
+main(int argc, char **argv)
+{
+	return ${ALGID};
+}
+")
+	SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c")
+
+	FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
+	MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
+
+    IF(CMAKE_REQUIRED_LINKER_FLAGS)
+      SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS
+        "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
+    ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
+      SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS)
+    ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
+	TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
+	  ${CMAKE_BINARY_DIR}
+	  ${SOURCE_FILE}
+	  CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive" ${CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS}
+	  OUTPUT_VARIABLE OUTPUT)
+
+	IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+	    MESSAGE(STATUS
+	        "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
+		SET(ARCHIVE_CRYPTO_${CRYPTO} 1)
+	ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+	    MESSAGE(STATUS
+	         "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
+    	    FILE(APPEND
+	        ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+                "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n"
+        	"${OUTPUT}\n"
+        	"Source file was:\n${SOURCE}\n")
+	ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+
+      ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+      ENDIF(NOT ARCHIVE_CRYPTO_${CRYPTO})
+    ENDFOREACH(CRYPTO)
+  ENDIF(WIN32 AND NOT CYGWIN)
+ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
+
+#
+# Find iconv
+# POSIX defines the second arg as const char **
+# and requires it to be in libc.  But we can accept
+# a non-const argument here and can support iconv()
+# being in libiconv.
+#
+MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
+  IF(NOT HAVE_ICONV)
+    CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+    IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+      #
+      # During checking iconv proto type, we should use -Werror to avoid the
+      # success of iconv detection with a warnig which success is a miss
+      # detection. So this needs for all build mode(even it's a release mode).
+      #
+      SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
+    ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+    IF (MSVC)
+      # NOTE: /WX option is the same as gcc's -Werror option.
+      SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
+    ENDIF (MSVC)
+    #
+    LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
+      "#include <stdlib.h>
+       #include <iconv.h>
+       int main() {
+          ${TRY_ICONV_CONST} char *ccp;
+          iconv_t cd = iconv_open(\"\", \"\");
+          iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0);
+          iconv_close(cd);
+          return 0;
+       }"
+     HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+    IF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+      SET(HAVE_ICONV true)
+      SET(ICONV_CONST ${TRY_ICONV_CONST})
+    ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+    CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+  ENDIF(NOT HAVE_ICONV)
+ENDMACRO(CHECK_ICONV TRY_ICONV_CONST)
+
+IF(ENABLE_ICONV)
+  CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+  FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
+  IF(ICONV_INCLUDE_DIR)
+    #SET(INCLUDES ${INCLUDES} "iconv.h")
+    SET(HAVE_ICONV_H 1)
+    INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
+    SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+    CHECK_ICONV("libc" "const")
+    CHECK_ICONV("libc" "")
+
+    # If iconv isn't in libc and we have a libiconv, try that.
+    FIND_LIBRARY(LIBICONV_PATH NAMES iconv libiconv)
+    IF(NOT HAVE_ICONV AND LIBICONV_PATH)
+      LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
+      # Test if a macro is needed for the library.
+      TRY_MACRO_FOR_LIBRARY(
+        "${ICONV_INCLUDE_DIR}" "${LIBICONV_PATH}"
+        COMPILES
+        "#include <iconv.h>\nint main() {return iconv_close((iconv_t)0);}"
+        "WITHOUT_LIBICONV_STATIC;LIBICONV_STATIC")
+      IF(NOT WITHOUT_LIBICONV_STATIC AND LIBICONV_STATIC)
+        ADD_DEFINITIONS(-DLIBICONV_STATIC)
+      ENDIF(NOT WITHOUT_LIBICONV_STATIC AND LIBICONV_STATIC)
+      #
+      # Set up CMAKE_REQUIRED_* for CHECK_ICONV
+      #
+      SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+      SET(CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
+      IF(LIBICONV_STATIC)
+        # LIBICONV_STATIC is necessary for the success of CHECK_ICONV
+        # on Windows.
+        SET(CMAKE_REQUIRED_DEFINITIONS "-DLIBICONV_STATIC")
+      ELSE(LIBICONV_STATIC)
+        SET(CMAKE_REQUIRED_DEFINITIONS)
+      ENDIF(LIBICONV_STATIC)
+      CHECK_ICONV("libiconv" "const")
+      CHECK_ICONV("libiconv" "")
+      IF (HAVE_ICONV)
+        LIST(APPEND ADDITIONAL_LIBS ${LIBICONV_PATH})
+      ENDIF(HAVE_ICONV)
+    ENDIF(NOT HAVE_ICONV AND LIBICONV_PATH)
+  ENDIF(ICONV_INCLUDE_DIR)
+  #
+  # Find locale_charset() for libiconv.
+  #
+  IF(LIBICONV_PATH)
+    SET(CMAKE_REQUIRED_DEFINITIONS)
+    SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+    SET(CMAKE_REQUIRED_LIBRARIES)
+    CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H)
+    FIND_LIBRARY(LIBCHARSET_PATH NAMES charset libcharset)
+    IF(LIBCHARSET_PATH)
+      SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH})
+      IF(WIN32 AND NOT CYGWIN)
+        # Test if a macro is needed for the library.
+        TRY_MACRO_FOR_LIBRARY(
+          "${ICONV_INCLUDE_DIR}" "${LIBCHARSET_PATH}"
+          COMPILES
+          "#include <localcharset.h>\nint main() {return locale_charset()?1:0;}"
+          "WITHOUT_LIBCHARSET_STATIC;LIBCHARSET_STATIC")
+        IF(NOT WITHOUT_LIBCHARSET_STATIC AND LIBCHARSET_STATIC)
+          ADD_DEFINITIONS(-DLIBCHARSET_STATIC)
+        ENDIF(NOT WITHOUT_LIBCHARSET_STATIC AND LIBCHARSET_STATIC)
+        IF(WITHOUT_LIBCHARSET_STATIC OR LIBCHARSET_STATIC)
+          SET(HAVE_LOCALE_CHARSET ON CACHE INTERNAL
+              "Have function locale_charset")
+        ENDIF(WITHOUT_LIBCHARSET_STATIC OR LIBCHARSET_STATIC)
+      ELSE(WIN32 AND NOT CYGWIN)
+        CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
+      ENDIF(WIN32 AND NOT CYGWIN)
+      IF(HAVE_LOCALE_CHARSET)
+        LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH})
+      ENDIF(HAVE_LOCALE_CHARSET)
+    ENDIF(LIBCHARSET_PATH)
+  ENDIF(LIBICONV_PATH)
+  CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+ELSE(ENABLE_ICONV)
+  # Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled
+  # (once enabled).
+  UNSET(HAVE_LOCALE_CHARSET CACHE)
+  UNSET(HAVE_ICONV CACHE)
+  UNSET(HAVE_ICONV_libc_ CACHE)
+  UNSET(HAVE_ICONV_libc_const CACHE)
+  UNSET(HAVE_ICONV_libiconv_ CACHE)
+  UNSET(HAVE_ICONV_libiconv_const CACHE)
+  UNSET(ICONV_INCLUDE_DIR CACHE)
+  UNSET(LIBICONV_PATH CACHE)
+  UNSET(LIBICONV_DLL CACHE)
+  UNSET(LIBICONV_STATIC CACHE)
+  UNSET(LIBCHARSET_DLL CACHE)
+  UNSET(LIBCHARSET_STATIC CACHE)
+ENDIF(ENABLE_ICONV)
+
+#
+# Find Libxml2
+#
+FIND_PACKAGE(LibXml2)
+IF(LIBXML2_FOUND)
+  CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+  INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES})
+  SET(HAVE_LIBXML2 1)
+  # libxml2's include files use iconv.h
+  SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+  CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H)
+  CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H)
+  # Test if a macro is needed for the library.
+  TRY_MACRO_FOR_LIBRARY(
+    "${ICONV_INCLUDE_DIR};${LIBXML2_INCLUDE_DIR}"
+    "ws2_32.lib;${ZLIB_LIBRARIES};${LIBICONV_PATH};${LIBXML2_LIBRARIES}"
+    COMPILES
+    "#include <stddef.h>\n#include <libxml/xmlreader.h>\nint main() {return xmlTextReaderRead((xmlTextReaderPtr)(void *)0);}"
+    "WITHOUT_LIBXML_STATIC;LIBXML_STATIC")
+  IF(NOT WITHOUT_LIBXML_STATIC AND LIBXML_STATIC)
+    ADD_DEFINITIONS(-DLIBXML_STATIC)
+  ENDIF(NOT WITHOUT_LIBXML_STATIC AND LIBXML_STATIC)
+  CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+ELSE(LIBXML2_FOUND)
+  #
+  # Find Expat
+  #
+  FIND_PACKAGE(EXPAT)
+  IF(EXPAT_FOUND)
+    CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+    INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR})
+    LIST(APPEND ADDITIONAL_LIBS ${EXPAT_LIBRARIES})
+    SET(HAVE_LIBEXPAT 1)
+    LA_CHECK_INCLUDE_FILE("expat.h" HAVE_EXPAT_H)
+    CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+  ENDIF(EXPAT_FOUND)
+ENDIF(LIBXML2_FOUND)
+MARK_AS_ADVANCED(CLEAR LIBXML2_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR LIBXML2_LIBRARIES)
+
+#
+# POSIX Regular Expression support
+#
+IF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$")
+  #
+  # If PCREPOSIX is not found or not requested, try using regex
+  # from libc or libregex
+  #
+  FIND_PATH(REGEX_INCLUDE_DIR regex.h)
+  IF(REGEX_INCLUDE_DIR)
+    CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
+    #
+    # If libc does not provide regex, find libregex.
+    #
+    IF(NOT HAVE_REGCOMP_LIBC)
+      CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+      FIND_LIBRARY(REGEX_LIBRARY regex)
+      IF(REGEX_LIBRARY)
+        SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
+        CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
+        IF(HAVE_REGCOMP_LIBREGEX)
+          LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
+          #
+          # If regex.h is not found, retry looking for regex.h at
+          # REGEX_INCLUDE_DIR
+          #
+          IF(NOT HAVE_REGEX_H)
+            UNSET(HAVE_REGEX_H CACHE)
+            INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
+            SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
+            LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
+          ENDIF(NOT HAVE_REGEX_H)
+          # Test if a macro is needed for the library.
+          TRY_MACRO_FOR_LIBRARY(
+            "${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
+            COMPILES
+            "#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+            "USE_REGEX_DLL;USE_REGEX_STATIC")
+          IF(USE_REGEX_DLL)
+            ADD_DEFINITIONS(-DUSE_REGEX_DLL)
+          ELSEIF(USE_REGEX_STATIC)
+            ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
+          ENDIF(USE_REGEX_DLL)
+        ENDIF(HAVE_REGCOMP_LIBREGEX)
+      ENDIF(REGEX_LIBRARY)
+      CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+    ENDIF(NOT HAVE_REGCOMP_LIBC)
+  ENDIF(REGEX_INCLUDE_DIR)
+  IF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX)
+    SET(FOUND_POSIX_REGEX_LIB 1)
+  ENDIF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX)
+ENDIF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$")
+
+IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
+  #
+  # If requested, try finding library for PCREPOSIX
+  #
+  FIND_PACKAGE(LibGCC)
+  FIND_PACKAGE(PCREPOSIX)
+  IF(PCREPOSIX_FOUND)
+    INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR})
+    LIST(APPEND ADDITIONAL_LIBS ${PCREPOSIX_LIBRARIES})
+    # Test if a macro is needed for the library.
+    TRY_MACRO_FOR_LIBRARY(
+      "${PCRE_INCLUDE_DIR}" "${PCREPOSIX_LIBRARIES}"
+      COMPILES
+      "#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+      "WITHOUT_PCRE_STATIC;PCRE_STATIC")
+    IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+      ADD_DEFINITIONS(-DPCRE_STATIC)
+	ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND PCRE_FOUND)
+	  # Determine if pcre static libraries are to be used.
+      LIST(APPEND ADDITIONAL_LIBS ${PCRE_LIBRARIES})
+      SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES})
+      MESSAGE(STATUS "trying again with -lpcre included")
+      TRY_MACRO_FOR_LIBRARY(
+        "${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+        COMPILES
+        "#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+        "WITHOUT_PCRE_STATIC;PCRE_STATIC")
+      IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+        ADD_DEFINITIONS(-DPCRE_STATIC)
+      ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND MSVC AND LIBGCC_FOUND)
+        # When doing a Visual Studio build using pcre static libraries
+        # built using the mingw toolchain, -lgcc is needed to resolve
+        # ___chkstk_ms.
+        MESSAGE(STATUS "Visual Studio build detected, trying again with -lgcc included")
+        LIST(APPEND ADDITIONAL_LIBS ${LIBGCC_LIBRARIES})
+        SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES} ${LIBGCC_LIBRARIES})
+          TRY_MACRO_FOR_LIBRARY(
+            "${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+            COMPILES
+            "#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+            "WITHOUT_PCRE_STATIC;PCRE_STATIC")
+          IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+            ADD_DEFINITIONS(-DPCRE_STATIC)
+          ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+      ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+    ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+  ENDIF(PCREPOSIX_FOUND)
+  MARK_AS_ADVANCED(CLEAR PCRE_INCLUDE_DIR)
+  MARK_AS_ADVANCED(CLEAR PCREPOSIX_LIBRARIES)
+  MARK_AS_ADVANCED(CLEAR PCRE_LIBRARIES)
+  MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
+ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
+
+#
+# Check functions
+#
+CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+  #
+  # During checking functions, we should use -fno-builtin to avoid the
+  # failure of function detection which failure is an error "conflicting
+  # types for built-in function" caused by using -Werror option.
+  #
+  SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
+CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
+CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
+CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
+CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(dirfd HAVE_DIRFD)
+CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
+CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
+CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
+CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
+CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
+CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatfs HAVE_FSTATFS)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatvfs HAVE_FSTATVFS)
+CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE)
+CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
+CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
+CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
+CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
+CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
+CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
+CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
+CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
+CHECK_FUNCTION_EXISTS_GLIBC(link HAVE_LINK)
+CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT)
+CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC)
+CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE)
+CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO)
+CHECK_FUNCTION_EXISTS_GLIBC(mknod HAVE_MKNOD)
+CHECK_FUNCTION_EXISTS_GLIBC(mkstemp HAVE_MKSTEMP)
+CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
+CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
+CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
+CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
+CHECK_FUNCTION_EXISTS_GLIBC(posix_spawnp HAVE_POSIX_SPAWNP)
+CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT)
+CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV)
+CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE)
+CHECK_FUNCTION_EXISTS_GLIBC(sigaction HAVE_SIGACTION)
+CHECK_FUNCTION_EXISTS_GLIBC(statfs HAVE_STATFS)
+CHECK_FUNCTION_EXISTS_GLIBC(statvfs HAVE_STATVFS)
+CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR)
+CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP)
+CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR)
+CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
+CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
+CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
+CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
+CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV)
+CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME)
+CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(utimensat HAVE_UTIMENSAT)
+CHECK_FUNCTION_EXISTS_GLIBC(vfork HAVE_VFORK)
+CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB)
+CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
+CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
+CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
+CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
+CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
+CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
+CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
+CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
+CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
+
+SET(CMAKE_REQUIRED_LIBRARIES "")
+CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
+CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO)
+CHECK_FUNCTION_EXISTS(strerror_r HAVE_STRERROR_R)
+CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME)
+CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
+CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP)
+CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY)
+
+CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+
+# Make sure we have the POSIX version of readdir_r, not the
+# older 2-argument version.
+LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
+  "#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
+  HAVE_READDIR_R)
+
+
+# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
+# NOTE: linux requires fcntl.h for AT_FDCWD.
+LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
+  "#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
+  HAVE_READLINKAT)
+
+
+# To verify major(), we need to both include the header
+# of interest and verify that the result can be linked.
+# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
+# CHECK_SYMBOL_EXISTS doesn't test linkage.
+LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
+  "#include <sys/mkdev.h>\nint main() { return major(256); }"
+  MAJOR_IN_MKDEV)
+LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
+  "#include <sys/sysmacros.h>\nint main() { return major(256); }"
+  MAJOR_IN_SYSMACROS)
+
+IF(HAVE_STRERROR_R)
+  SET(HAVE_DECL_STRERROR_R 1)
+ENDIF(HAVE_STRERROR_R)
+
+#
+# Check defines
+#
+SET(headers "limits.h")
+IF(HAVE_STDINT_H)
+  LIST(APPEND headers "stdint.h")
+ENDIF(HAVE_STDINT_H)
+IF(HAVE_INTTYPES_H)
+  LIST(APPEND headers "inttypes.h")
+ENDIF(HAVE_INTTYPES_H)
+CHECK_SYMBOL_EXISTS(EFTYPE           "errno.h"    HAVE_EFTYPE)
+CHECK_SYMBOL_EXISTS(EILSEQ           "errno.h"    HAVE_EILSEQ)
+CHECK_SYMBOL_EXISTS(D_MD_ORDER       "langinfo.h" HAVE_D_MD_ORDER)
+CHECK_SYMBOL_EXISTS(INT64_MAX        "${headers}" HAVE_DECL_INT64_MAX)
+CHECK_SYMBOL_EXISTS(INT64_MIN        "${headers}" HAVE_DECL_INT64_MIN)
+CHECK_SYMBOL_EXISTS(UINT32_MAX       "${headers}" HAVE_DECL_UINT32_MAX)
+CHECK_SYMBOL_EXISTS(UINT64_MAX       "${headers}" HAVE_DECL_UINT64_MAX)
+CHECK_SYMBOL_EXISTS(SIZE_MAX         "${headers}" HAVE_DECL_SIZE_MAX)
+CHECK_SYMBOL_EXISTS(SSIZE_MAX        "limits.h"   HAVE_DECL_SSIZE_MAX)
+
+#
+# Check struct members
+#
+# Check for tm_gmtoff in struct tm
+CHECK_STRUCT_MEMBER("struct tm" tm_gmtoff
+    "time.h" HAVE_STRUCT_TM_TM_GMTOFF)
+CHECK_STRUCT_MEMBER("struct tm" __tm_gmtoff
+    "time.h" HAVE_STRUCT_TM___TM_GMTOFF)
+
+# Check for f_namemax in struct statfs
+CHECK_STRUCT_MEMBER("struct statfs" f_namemax
+    "sys/param.h;sys/mount.h" HAVE_STRUCT_STATFS_F_NAMEMAX)
+
+# Check for birthtime in struct stat
+CHECK_STRUCT_MEMBER("struct stat" st_birthtime
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIME)
+
+# Check for high-resolution timestamps in struct stat
+CHECK_STRUCT_MEMBER("struct stat" st_birthtimespec.tv_nsec
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
+CHECK_STRUCT_MEMBER("struct stat" st_mtimespec.tv_nsec
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+CHECK_STRUCT_MEMBER("struct stat" st_mtim.tv_nsec
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+CHECK_STRUCT_MEMBER("struct stat" st_mtime_n
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIME_N)
+CHECK_STRUCT_MEMBER("struct stat" st_umtime
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_UMTIME)
+CHECK_STRUCT_MEMBER("struct stat" st_mtime_usec
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIME_USEC)
+# Check for block size support in struct stat
+CHECK_STRUCT_MEMBER("struct stat" st_blksize
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BLKSIZE)
+# Check for st_flags in struct stat (BSD fflags)
+CHECK_STRUCT_MEMBER("struct stat" st_flags
+    "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_FLAGS)
+
+IF(HAVE_SYS_STATVFS_H)
+  CHECK_STRUCT_MEMBER("struct statvfs" f_iosize
+    "sys/types.h;sys/statvfs.h" HAVE_STRUCT_STATVFS_F_IOSIZE)
+ENDIF()
+
+#
+#
+CHECK_STRUCT_MEMBER("struct tm" tm_sec
+    "sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
+
+#
+# Check for integer types
+#
+#
+CHECK_TYPE_SIZE("short" SIZE_OF_SHORT)
+CHECK_TYPE_SIZE("int" SIZE_OF_INT)
+CHECK_TYPE_SIZE("long" SIZE_OF_LONG)
+CHECK_TYPE_SIZE("long long"     SIZE_OF_LONG_LONG)
+
+CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT)
+CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED)
+CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG)
+CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
+
+CHECK_TYPE_SIZE("__int64" __INT64)
+CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
+
+CHECK_TYPE_SIZE(int16_t INT16_T) 
+CHECK_TYPE_SIZE(int32_t INT32_T)
+CHECK_TYPE_SIZE(int64_t INT64_T)
+CHECK_TYPE_SIZE(intmax_t INTMAX_T)
+CHECK_TYPE_SIZE(uint8_t UINT8_T) 
+CHECK_TYPE_SIZE(uint16_t UINT16_T) 
+CHECK_TYPE_SIZE(uint32_t UINT32_T) 
+CHECK_TYPE_SIZE(uint64_t UINT64_T)
+CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
+
+CHECK_TYPE_SIZE(dev_t       DEV_T)
+IF(NOT HAVE_DEV_T)
+  IF(MSVC)
+    SET(dev_t "unsigned int")
+  ENDIF(MSVC)
+ENDIF(NOT HAVE_DEV_T)
+#
+CHECK_TYPE_SIZE(gid_t       GID_T)
+IF(NOT HAVE_GID_T)
+  IF(WIN32)
+    SET(gid_t "short")
+  ELSE(WIN32)
+    SET(gid_t "unsigned int")
+  ENDIF(WIN32)
+ENDIF(NOT HAVE_GID_T)
+#
+CHECK_TYPE_SIZE(id_t        ID_T)
+IF(NOT HAVE_ID_T)
+  IF(WIN32)
+    SET(id_t "short")
+  ELSE(WIN32)
+    SET(id_t "unsigned int")
+  ENDIF(WIN32)
+ENDIF(NOT HAVE_ID_T)
+#
+CHECK_TYPE_SIZE(mode_t      MODE_T)
+IF(NOT HAVE_MODE_T)
+  IF(WIN32)
+    SET(mode_t "unsigned short")
+  ELSE(WIN32)
+    SET(mode_t "int")
+  ENDIF(WIN32)
+ENDIF(NOT HAVE_MODE_T)
+#
+CHECK_TYPE_SIZE(off_t       OFF_T)
+IF(NOT HAVE_OFF_T)
+  SET(off_t "__int64")
+ENDIF(NOT HAVE_OFF_T)
+#
+CHECK_TYPE_SIZE(size_t      SIZE_T)
+IF(NOT HAVE_SIZE_T)
+  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+    SET(size_t "uint64_t")
+  ELSE("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+    SET(size_t   "uint32_t")
+  ENDIF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ENDIF(NOT HAVE_SIZE_T)
+#
+CHECK_TYPE_SIZE(ssize_t     SSIZE_T)
+IF(NOT HAVE_SSIZE_T)
+  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+    SET(ssize_t "int64_t")
+  ELSE("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+    SET(ssize_t "long")
+  ENDIF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ENDIF(NOT HAVE_SSIZE_T)
+#
+CHECK_TYPE_SIZE(uid_t       UID_T)
+IF(NOT HAVE_UID_T)
+  IF(WIN32)
+    SET(uid_t "short")
+  ELSE(WIN32)
+    SET(uid_t "unsigned int")
+  ENDIF(WIN32)
+ENDIF(NOT HAVE_UID_T)
+#
+CHECK_TYPE_SIZE(pid_t       PID_T)
+IF(NOT HAVE_PID_T)
+  IF(WIN32)
+    SET(pid_t "int")
+  ELSE(WIN32)
+    MESSAGE(FATAL_ERROR "pid_t doesn't exist on this platform?")
+  ENDIF(WIN32)
+ENDIF(NOT HAVE_PID_T)
+#
+CHECK_TYPE_SIZE(intptr_t   INTPTR_T)
+IF(NOT HAVE_INTPTR_T)
+  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+    SET(intptr_t "int64_t")
+  ELSE()
+    SET(intptr_t "int32_t")
+  ENDIF()
+ENDIF(NOT HAVE_INTPTR_T)
+#
+CHECK_TYPE_SIZE(uintptr_t   UINTPTR_T)
+IF(NOT HAVE_UINTPTR_T)
+  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+    SET(uintptr_t "uint64_t")
+  ELSE()
+    SET(uintptr_t "uint32_t")
+  ENDIF()
+ENDIF(NOT HAVE_UINTPTR_T)
+#
+CHECK_TYPE_SIZE(wchar_t     SIZEOF_WCHAR_T)
+IF(HAVE_SIZEOF_WCHAR_T)
+  SET(HAVE_WCHAR_T 1)
+ENDIF(HAVE_SIZEOF_WCHAR_T)
+#
+# Check if _FILE_OFFSET_BITS macro needed for large files
+#
+CHECK_FILE_OFFSET_BITS()
+
+#
+# Check for Extended Attribute libraries, headers, and functions
+#
+IF(ENABLE_XATTR)
+  LA_CHECK_INCLUDE_FILE(attr/xattr.h     HAVE_ATTR_XATTR_H)
+  LA_CHECK_INCLUDE_FILE(sys/xattr.h      HAVE_SYS_XATTR_H)
+  LA_CHECK_INCLUDE_FILE(sys/extattr.h      HAVE_SYS_EXTATTR_H)
+  CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
+  IF(HAVE_LIBATTR)
+    SET(CMAKE_REQUIRED_LIBRARIES "attr")
+  ENDIF(HAVE_LIBATTR)
+  CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
+  CHECK_FUNCTION_EXISTS_GLIBC(extattr_get_file HAVE_EXTATTR_GET_FILE)
+  CHECK_FUNCTION_EXISTS_GLIBC(extattr_list_file HAVE_EXTATTR_LIST_FILE)
+  CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_fd HAVE_EXTATTR_SET_FD)
+  CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_file HAVE_EXTATTR_SET_FILE)
+  CHECK_FUNCTION_EXISTS_GLIBC(fgetxattr HAVE_FGETXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(flistxattr HAVE_FLISTXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(fsetxattr HAVE_FSETXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(getxattr HAVE_GETXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(lgetxattr HAVE_LGETXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(listxattr HAVE_LISTXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(llistxattr HAVE_LLISTXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(lsetxattr HAVE_LSETXATTR)
+  CHECK_FUNCTION_EXISTS_GLIBC(fgetea HAVE_FGETEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(flistea HAVE_FLISTEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(fsetea HAVE_FSETEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(getea HAVE_GETEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(lgetea HAVE_LGETEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(listea HAVE_LISTEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(llistea HAVE_LLISTEA)
+  CHECK_FUNCTION_EXISTS_GLIBC(lsetea HAVE_LSETEA)
+ELSE(ENABLE_XATTR)
+  SET(HAVE_ATTR_LIB FALSE)
+  SET(HAVE_ATTR_XATTR_H FALSE)
+  SET(HAVE_DECL_EXTATTR_NAMESPACE_USER FALSE)
+  SET(HAVE_EXTATTR_GET_FILE FALSE)
+  SET(HAVE_EXTATTR_LIST_FILE FALSE)
+  SET(HAVE_EXTATTR_SET_FD FALSE)
+  SET(HAVE_EXTATTR_SET_FILE FALSE)
+  SET(HAVE_FGETEA FALSE)
+  SET(HAVE_FGETXATTR FALSE)
+  SET(HAVE_FLISTEA FALSE)
+  SET(HAVE_FLISTXATTR FALSE)
+  SET(HAVE_FSETEA FALSE)
+  SET(HAVE_FSETXATTR FALSE)
+  SET(HAVE_GETEA FALSE)
+  SET(HAVE_GETXATTR FALSE)
+  SET(HAVE_LGETEA FALSE)
+  SET(HAVE_LGETXATTR FALSE)
+  SET(HAVE_LISTEA FALSE)
+  SET(HAVE_LISTXATTR FALSE)
+  SET(HAVE_LLISTEA FALSE)
+  SET(HAVE_LLISTXATTR FALSE)
+  SET(HAVE_LSETEA FALSE)
+  SET(HAVE_LSETXATTR FALSE)
+  SET(HAVE_SYS_EXTATTR_H FALSE)
+  SET(HAVE_SYS_XATTR_H FALSE)
+ENDIF(ENABLE_XATTR)
+
+#
+# Check for ACL libraries, headers, and functions
+#
+# The ACL support in libarchive is written against the POSIX1e draft,
+# which was never officially approved and varies quite a bit across
+# platforms.  Worse, some systems have completely non-POSIX acl functions,
+# which makes the following checks rather more complex than I would like.
+#
+IF(ENABLE_ACL)
+  CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL)
+  IF(HAVE_LIBACL)
+    SET(CMAKE_REQUIRED_LIBRARIES "acl")
+    FIND_LIBRARY(ACL_LIBRARY NAMES acl)
+    LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY})
+  ENDIF(HAVE_LIBACL)
+  #
+  CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
+  CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
+  CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD)
+  CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd_np HAVE_ACL_SET_FD_NP)
+  CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE)
+  CHECK_TYPE_EXISTS(acl_permset_t "${INCLUDES}"    HAVE_ACL_PERMSET_T)
+
+  # The "acl_get_perm()" function was omitted from the POSIX draft.
+  # (It's a pretty obvious oversight; otherwise, there's no way to
+  # test for specific permissions in a permset.)  Linux uses the obvious
+  # name, FreeBSD adds _np to mark it as "non-Posix extension."
+  # Test for both as a double-check that we really have POSIX-style ACL support.
+  CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
+  CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
+  CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
+  CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
+  CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
+  CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
+
+  # MacOS has an acl.h that isn't POSIX.  It can be detected by
+  # checking for ACL_USER
+  CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_ACL_USER)
+ELSE(ENABLE_ACL)
+  # If someone runs cmake, then disables ACL support, we need
+  # to forcibly override the cached values for these.
+  SET(HAVE_ACL_CREATE_ENTRY FALSE)
+  SET(HAVE_ACL_GET_LINK FALSE)
+  SET(HAVE_ACL_GET_LINK_NP FALSE)
+  SET(HAVE_ACL_GET_PERM FALSE)
+  SET(HAVE_ACL_GET_PERM_NP FALSE)
+  SET(HAVE_ACL_INIT FALSE)
+  SET(HAVE_ACL_LIB FALSE)
+  SET(HAVE_ACL_PERMSET_T FALSE)
+  SET(HAVE_ACL_SET_FD FALSE)
+  SET(HAVE_ACL_SET_FD_NP FALSE)
+  SET(HAVE_ACL_SET_FILE FALSE)
+  SET(HAVE_ACL_USER FALSE)
+ENDIF(ENABLE_ACL)
+
+#
+# Check MD5/RMD160/SHA support
+# NOTE: Crypto checks must be run last before generating config.h
+#
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" LIBC)
+CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2)
+CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3)
+CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
+
+# Libmd has to be probed after OpenSSL.
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
+
+CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
+
+# Generate "config.h" from "build/cmake/config.h.in"
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
+	${CMAKE_CURRENT_BINARY_DIR}/config.h)
+INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
+ADD_DEFINITIONS(-DHAVE_CONFIG_H)
+
+#
+# Register installation of PDF documents.
+#
+IF(WIN32 AND NOT CYGWIN)
+  #
+  # On Windows platform, It's better that we install PDF documents
+  # on one's computer.
+  # These PDF documents are available in the release package.
+  #
+  IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf)
+    INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf
+            DESTINATION share/man
+            FILES_MATCHING PATTERN "*.pdf"
+    )
+  ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf)
+ENDIF(WIN32 AND NOT CYGWIN)
+#
+#
+#
+INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/libarchive)
+#
+IF(MSVC)
+  ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
+ENDIF(MSVC)
+
+IF(ENABLE_TEST)
+  ADD_CUSTOM_TARGET(run_all_tests)
+ENDIF(ENABLE_TEST)
+
+add_subdirectory(libarchive)
+add_subdirectory(tar)
+add_subdirectory(cpio)
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
new file mode 100644
index 000000000000..7a09742db098
--- /dev/null
+++ b/CTestConfig.cmake
@@ -0,0 +1,11 @@
+# TODO: This file should be moved into the build/cmake directory...
+
+# The libarchive CDash page appears at
+#   http://my.cdash.org/index.php?project=libarchive
+set(CTEST_PROJECT_NAME "libarchive")
+set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
+
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "my.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=libarchive")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 000000000000..33c58b7ed454
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,35 @@
+More complete build documentation is available on the libarchive
+Wiki:  http://libarchive.googlecode.com/
+
+On most Unix-like systems, you should be able to install libarchive,
+bsdtar, and bsdcpio using the following common steps:
+    ./configure
+    make
+    make install
+
+If you need to customize the target directories or otherwise adjust
+the build setting, use
+    ./configure --help
+to list the configure options.
+
+If you are developing libarchive and need to update the
+configure script and other build files:
+    /bin/sh build/autogen.sh
+
+To create a distribution, please use the 'distcheck' target:
+    /bin/sh build/autogen.sh && ./configure && make distcheck
+
+On Unix-like and non-Unix-like systems, use the "cmake" utility (available from
+http://cmake.org/) to generate suitable build files for your platform.
+Cmake requires the name of the directory containing CmakeLists.txt and
+the "generator" to use for your build environment.  For example, to
+build with Xcode on Mac OS, you can use the following command:
+    cmake -G "Xcode" ~/libarchive-download-dir/
+The result will be appropriate makefiles, solution files, or project
+files that can be used with the corresponding development tool.
+The default on Unix-like systems is to generate Makefiles, so you
+can also use cmake instead of the configure script:
+    cmake ~/libarchive-download-dir/
+    make
+    make install
+See the libarchive Wiki or the cmake site for further documentation.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 000000000000..3fa2d22b6de6
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,1012 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS= foreign subdir-objects
+ACLOCAL_AMFLAGS = -I build/autoconf
+
+#
+# What to build and install
+#
+lib_LTLIBRARIES=	libarchive.la
+noinst_LTLIBRARIES=	libarchive_fe.la
+bin_PROGRAMS=	$(bsdtar_programs) $(bsdcpio_programs)
+man_MANS= $(libarchive_man_MANS) $(bsdtar_man_MANS) $(bsdcpio_man_MANS)
+BUILT_SOURCES= libarchive/test/list.h tar/test/list.h cpio/test/list.h
+
+#
+# What to test: We always test libarchive, test bsdtar and bsdcpio only
+# if we built them.
+#
+check_PROGRAMS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs)
+TESTS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs)
+TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT)
+# Always build and test both bsdtar and bsdcpio as part of 'distcheck'
+DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio
+COMMON_CFLAGS=-Wall -Wformat -Wformat-security
+# The next line is commented out by default in shipping libarchive releases.
+# It is uncommented by default in trunk.
+# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual
+AM_CFLAGS=$(COMMON_CFLAGS) $(DEV_CFLAGS)
+PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@
+AM_CPPFLAGS=$(PLATFORMCPPFLAGS)
+
+#
+# What to include in the distribution
+#
+EXTRA_DIST= \
+	CMakeLists.txt			\
+	build/autogen.sh		\
+	build/bump-version.sh		\
+	build/clean.sh			\
+	build/cmake			\
+	build/version			\
+	contrib				\
+	doc				\
+	examples			\
+	$(libarchive_EXTRA_DIST)	\
+	$(libarchive_test_EXTRA_DIST)	\
+	$(bsdtar_EXTRA_DIST)		\
+	$(bsdtar_test_EXTRA_DIST)	\
+	$(bsdcpio_EXTRA_DIST)		\
+	$(bsdcpio_test_EXTRA_DIST)
+
+# a) Clean out some unneeded files and directories
+# b) Collect all documentation and format it for distribution.
+dist-hook:
+	rm -rf `find $(distdir) -name CVS -type d`
+	rm -rf `find $(distdir) -name .svn -type d`
+	rm -f `find $(distdir) -name '*~'`
+	rm -f `find $(distdir) -name '*.out'`
+	rm -f `find $(distdir) -name '*.core'`
+	-rm -f $(distdir)/*/Makefile $(distdir)/*/*/Makefile
+	cd $(distdir)/doc && /bin/sh update.sh
+
+#
+# Extra rules for cleanup
+#
+DISTCLEANFILES=					\
+	libarchive/test/list.h			\
+	tar/test/list.h				\
+	cpio/test/list.h
+
+distclean-local:
+	-rm -rf .ref
+	-rm -rf autom4te.cache/
+	-rm -f *~
+	-[ -f libarchive/Makefile ] && cd libarchive && make clean
+	-[ -f libarchive/test/Makefile ] && cd libarchive/test && make clean
+	-[ -f tar/Makefile ] && cd tar && make clean
+	-[ -f tar/test/Makefile ] && cd tar/test && make clean
+	-[ -f cpio/Makefile ] && cd cpio && make clean
+	-[ -f cpio/test/Makefile ] && cd cpio/test && make clean
+
+#
+# Libarchive headers, source, etc.
+#
+#
+
+include_HEADERS= libarchive/archive.h libarchive/archive_entry.h
+
+libarchive_la_SOURCES=						\
+	libarchive/archive_acl.c				\
+	libarchive/archive_acl_private.h			\
+	libarchive/archive_check_magic.c			\
+	libarchive/archive_cmdline.c				\
+	libarchive/archive_cmdline_private.h			\
+	libarchive/archive_crc32.h				\
+	libarchive/archive_crypto.c				\
+	libarchive/archive_crypto_private.h			\
+	libarchive/archive_endian.h				\
+	libarchive/archive_entry.c				\
+	libarchive/archive_entry.h				\
+	libarchive/archive_entry_copy_stat.c			\
+	libarchive/archive_entry_link_resolver.c		\
+	libarchive/archive_entry_locale.h			\
+	libarchive/archive_entry_private.h			\
+	libarchive/archive_entry_sparse.c			\
+	libarchive/archive_entry_stat.c				\
+	libarchive/archive_entry_strmode.c			\
+	libarchive/archive_entry_xattr.c			\
+	libarchive/archive_getdate.c				\
+	libarchive/archive_match.c				\
+	libarchive/archive_options.c				\
+	libarchive/archive_options_private.h			\
+	libarchive/archive_pathmatch.c				\
+	libarchive/archive_pathmatch.h				\
+	libarchive/archive_platform.h				\
+	libarchive/archive_ppmd_private.h			\
+	libarchive/archive_ppmd7.c				\
+	libarchive/archive_ppmd7_private.h			\
+	libarchive/archive_private.h				\
+	libarchive/archive_rb.c					\
+	libarchive/archive_rb.h					\
+	libarchive/archive_read.c				\
+	libarchive/archive_read_append_filter.c			\
+	libarchive/archive_read_data_into_fd.c			\
+	libarchive/archive_read_disk_entry_from_file.c		\
+	libarchive/archive_read_disk_posix.c			\
+	libarchive/archive_read_disk_private.h			\
+	libarchive/archive_read_disk_set_standard_lookup.c	\
+	libarchive/archive_read_extract.c			\
+	libarchive/archive_read_open_fd.c			\
+	libarchive/archive_read_open_file.c			\
+	libarchive/archive_read_open_filename.c			\
+	libarchive/archive_read_open_memory.c			\
+	libarchive/archive_read_private.h			\
+	libarchive/archive_read_set_format.c			\
+	libarchive/archive_read_set_options.c			\
+	libarchive/archive_read_support_filter_all.c		\
+	libarchive/archive_read_support_filter_bzip2.c		\
+	libarchive/archive_read_support_filter_compress.c	\
+	libarchive/archive_read_support_filter_grzip.c		\
+	libarchive/archive_read_support_filter_gzip.c		\
+	libarchive/archive_read_support_filter_lrzip.c		\
+	libarchive/archive_read_support_filter_lzop.c		\
+	libarchive/archive_read_support_filter_none.c		\
+	libarchive/archive_read_support_filter_program.c	\
+	libarchive/archive_read_support_filter_rpm.c		\
+	libarchive/archive_read_support_filter_uu.c		\
+	libarchive/archive_read_support_filter_xz.c		\
+	libarchive/archive_read_support_format_7zip.c		\
+	libarchive/archive_read_support_format_all.c		\
+	libarchive/archive_read_support_format_ar.c		\
+	libarchive/archive_read_support_format_by_code.c	\
+	libarchive/archive_read_support_format_cab.c		\
+	libarchive/archive_read_support_format_cpio.c		\
+	libarchive/archive_read_support_format_empty.c		\
+	libarchive/archive_read_support_format_iso9660.c	\
+	libarchive/archive_read_support_format_lha.c		\
+	libarchive/archive_read_support_format_mtree.c		\
+	libarchive/archive_read_support_format_rar.c		\
+	libarchive/archive_read_support_format_raw.c		\
+	libarchive/archive_read_support_format_tar.c		\
+	libarchive/archive_read_support_format_xar.c		\
+	libarchive/archive_read_support_format_zip.c		\
+	libarchive/archive_string.c				\
+	libarchive/archive_string.h				\
+	libarchive/archive_string_composition.h			\
+	libarchive/archive_string_sprintf.c			\
+	libarchive/archive_util.c				\
+	libarchive/archive_virtual.c				\
+	libarchive/archive_write.c				\
+	libarchive/archive_write_disk_acl.c			\
+	libarchive/archive_write_disk_posix.c			\
+	libarchive/archive_write_disk_private.h			\
+	libarchive/archive_write_disk_set_standard_lookup.c	\
+	libarchive/archive_write_open_fd.c			\
+	libarchive/archive_write_open_file.c			\
+	libarchive/archive_write_open_filename.c		\
+	libarchive/archive_write_open_memory.c			\
+	libarchive/archive_write_private.h			\
+	libarchive/archive_write_add_filter.c			\
+	libarchive/archive_write_add_filter_b64encode.c		\
+	libarchive/archive_write_add_filter_by_name.c		\
+	libarchive/archive_write_add_filter_bzip2.c		\
+	libarchive/archive_write_add_filter_compress.c		\
+	libarchive/archive_write_add_filter_grzip.c		\
+	libarchive/archive_write_add_filter_gzip.c		\
+	libarchive/archive_write_add_filter_lrzip.c		\
+	libarchive/archive_write_add_filter_lzop.c		\
+	libarchive/archive_write_add_filter_none.c		\
+	libarchive/archive_write_add_filter_program.c		\
+	libarchive/archive_write_add_filter_uuencode.c		\
+	libarchive/archive_write_add_filter_xz.c		\
+	libarchive/archive_write_set_format.c			\
+	libarchive/archive_write_set_format_7zip.c		\
+	libarchive/archive_write_set_format_ar.c		\
+	libarchive/archive_write_set_format_by_name.c		\
+	libarchive/archive_write_set_format_cpio.c		\
+	libarchive/archive_write_set_format_cpio_newc.c		\
+	libarchive/archive_write_set_format_iso9660.c		\
+	libarchive/archive_write_set_format_mtree.c		\
+	libarchive/archive_write_set_format_pax.c		\
+	libarchive/archive_write_set_format_shar.c		\
+	libarchive/archive_write_set_format_ustar.c		\
+	libarchive/archive_write_set_format_v7tar.c		\
+	libarchive/archive_write_set_format_gnutar.c		\
+	libarchive/archive_write_set_format_xar.c		\
+	libarchive/archive_write_set_format_zip.c		\
+	libarchive/archive_write_set_options.c			\
+	libarchive/config_freebsd.h				\
+	libarchive/filter_fork_posix.c				\
+	libarchive/filter_fork.h
+
+if INC_WINDOWS_FILES
+libarchive_la_SOURCES+=						\
+	libarchive/archive_entry_copy_bhfi.c			\
+	libarchive/archive_read_disk_windows.c			\
+	libarchive/archive_windows.h				\
+	libarchive/archive_windows.c				\
+	libarchive/archive_write_disk_windows.c			\
+	libarchive/filter_fork_windows.c
+endif
+
+# -no-undefined marks that libarchive doesn't rely on symbols
+# defined in the application.  This is mandatory for cygwin.
+libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION)
+libarchive_la_LIBADD= $(LTLIBICONV)
+
+# Manpages to install
+libarchive_man_MANS=						\
+	libarchive/archive_entry.3				\
+	libarchive/archive_entry_acl.3				\
+	libarchive/archive_entry_linkify.3			\
+	libarchive/archive_entry_paths.3			\
+	libarchive/archive_entry_perms.3			\
+	libarchive/archive_entry_stat.3				\
+	libarchive/archive_entry_time.3				\
+	libarchive/archive_read.3				\
+	libarchive/archive_read_data.3				\
+	libarchive/archive_read_disk.3				\
+	libarchive/archive_read_extract.3			\
+	libarchive/archive_read_filter.3			\
+	libarchive/archive_read_format.3			\
+	libarchive/archive_read_free.3				\
+	libarchive/archive_read_header.3			\
+	libarchive/archive_read_new.3				\
+	libarchive/archive_read_open.3				\
+	libarchive/archive_read_set_options.3			\
+	libarchive/archive_util.3				\
+	libarchive/archive_write.3				\
+	libarchive/archive_write_blocksize.3			\
+	libarchive/archive_write_data.3				\
+	libarchive/archive_write_disk.3				\
+	libarchive/archive_write_filter.3			\
+	libarchive/archive_write_finish_entry.3	 		\
+	libarchive/archive_write_format.3			\
+	libarchive/archive_write_free.3				\
+	libarchive/archive_write_header.3			\
+	libarchive/archive_write_new.3				\
+	libarchive/archive_write_open.3				\
+	libarchive/archive_write_set_options.3			\
+	libarchive/cpio.5					\
+	libarchive/libarchive.3					\
+	libarchive/libarchive_changes.3				\
+	libarchive/libarchive_internals.3			\
+	libarchive/libarchive-formats.5				\
+	libarchive/mtree.5					\
+	libarchive/tar.5
+
+# Additional libarchive files to include in the distribution
+libarchive_EXTRA_DIST=			\
+	libarchive/archive_windows.c	\
+	libarchive/archive_windows.h	\
+	libarchive/filter_fork_windows.c	\
+	libarchive/CMakeLists.txt	\
+	$(libarchive_man_MANS)
+
+# pkgconfig
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = build/pkgconfig/libarchive.pc
+
+# Sources needed by all test programs
+test_utils_SOURCES= \
+	test_utils/test_utils.c \
+	test_utils/test_utils.h
+
+#
+#
+# libarchive_test program
+#
+#
+libarchive_test_SOURCES=					\
+	$(libarchive_la_SOURCES)				\
+	$(test_utils_SOURCES)					\
+	libarchive/test/main.c					\
+	libarchive/test/read_open_memory.c			\
+	libarchive/test/test.h					\
+	libarchive/test/test_acl_freebsd_posix1e.c		\
+	libarchive/test/test_acl_freebsd_nfs4.c			\
+	libarchive/test/test_acl_nfs4.c				\
+	libarchive/test/test_acl_pax.c				\
+	libarchive/test/test_acl_posix1e.c			\
+	libarchive/test/test_archive_api_feature.c		\
+	libarchive/test/test_archive_clear_error.c		\
+	libarchive/test/test_archive_cmdline.c			\
+	libarchive/test/test_archive_crypto.c			\
+	libarchive/test/test_archive_getdate.c			\
+	libarchive/test/test_archive_match_owner.c		\
+	libarchive/test/test_archive_match_path.c		\
+	libarchive/test/test_archive_match_time.c		\
+	libarchive/test/test_archive_pathmatch.c		\
+	libarchive/test/test_archive_read_close_twice.c		\
+	libarchive/test/test_archive_read_close_twice_open_fd.c	\
+	libarchive/test/test_archive_read_close_twice_open_filename.c	\
+	libarchive/test/test_archive_read_multiple_data_objects.c	\
+	libarchive/test/test_archive_read_next_header_empty.c	\
+	libarchive/test/test_archive_read_next_header_raw.c	\
+	libarchive/test/test_archive_read_open2.c		\
+	libarchive/test/test_archive_read_set_filter_option.c	\
+	libarchive/test/test_archive_read_set_format_option.c	\
+	libarchive/test/test_archive_read_set_option.c		\
+	libarchive/test/test_archive_read_set_options.c		\
+	libarchive/test/test_archive_read_support.c		\
+	libarchive/test/test_archive_set_error.c		\
+	libarchive/test/test_archive_string.c			\
+	libarchive/test/test_archive_string_conversion.c	\
+	libarchive/test/test_archive_write_add_filter_by_name.c	\
+	libarchive/test/test_archive_write_set_filter_option.c	\
+	libarchive/test/test_archive_write_set_format_by_name.c	\
+	libarchive/test/test_archive_write_set_format_option.c	\
+	libarchive/test/test_archive_write_set_option.c		\
+	libarchive/test/test_archive_write_set_options.c	\
+	libarchive/test/test_bad_fd.c				\
+	libarchive/test/test_compat_bzip2.c			\
+	libarchive/test/test_compat_cpio.c			\
+	libarchive/test/test_compat_gtar.c			\
+	libarchive/test/test_compat_gzip.c			\
+	libarchive/test/test_compat_lzip.c			\
+	libarchive/test/test_compat_lzma.c			\
+	libarchive/test/test_compat_lzop.c			\
+	libarchive/test/test_compat_mac.c			\
+	libarchive/test/test_compat_pax_libarchive_2x.c		\
+	libarchive/test/test_compat_solaris_tar_acl.c		\
+	libarchive/test/test_compat_solaris_pax_sparse.c	\
+	libarchive/test/test_compat_tar_hardlink.c		\
+	libarchive/test/test_compat_uudecode.c			\
+	libarchive/test/test_compat_xz.c			\
+	libarchive/test/test_compat_zip.c			\
+	libarchive/test/test_empty_write.c			\
+	libarchive/test/test_entry.c				\
+	libarchive/test/test_entry_strmode.c			\
+	libarchive/test/test_extattr_freebsd.c			\
+	libarchive/test/test_filter_count.c			\
+	libarchive/test/test_fuzz.c				\
+	libarchive/test/test_gnutar_filename_encoding.c		\
+	libarchive/test/test_link_resolver.c			\
+	libarchive/test/test_open_failure.c			\
+	libarchive/test/test_open_fd.c				\
+	libarchive/test/test_open_file.c			\
+	libarchive/test/test_open_filename.c			\
+	libarchive/test/test_pax_filename_encoding.c		\
+	libarchive/test/test_read_data_large.c			\
+	libarchive/test/test_read_disk.c			\
+	libarchive/test/test_read_disk_directory_traversals.c	\
+	libarchive/test/test_read_disk_entry_from_file.c	\
+	libarchive/test/test_read_extract.c			\
+	libarchive/test/test_read_file_nonexistent.c		\
+	libarchive/test/test_read_filter_grzip.c		\
+	libarchive/test/test_read_filter_lrzip.c		\
+	libarchive/test/test_read_filter_lzop.c			\
+	libarchive/test/test_read_filter_lzop_multiple_parts.c	\
+	libarchive/test/test_read_filter_program.c		\
+	libarchive/test/test_read_filter_program_signature.c	\
+	libarchive/test/test_read_filter_uudecode.c		\
+	libarchive/test/test_read_format_7zip.c			\
+	libarchive/test/test_read_format_ar.c			\
+	libarchive/test/test_read_format_cab.c			\
+	libarchive/test/test_read_format_cab_filename.c		\
+	libarchive/test/test_read_format_cpio_afio.c		\
+	libarchive/test/test_read_format_cpio_bin.c		\
+	libarchive/test/test_read_format_cpio_bin_Z.c		\
+	libarchive/test/test_read_format_cpio_bin_be.c		\
+	libarchive/test/test_read_format_cpio_bin_bz2.c		\
+	libarchive/test/test_read_format_cpio_bin_gz.c		\
+	libarchive/test/test_read_format_cpio_bin_lzip.c	\
+	libarchive/test/test_read_format_cpio_bin_lzma.c	\
+	libarchive/test/test_read_format_cpio_bin_xz.c		\
+	libarchive/test/test_read_format_cpio_filename.c	\
+	libarchive/test/test_read_format_cpio_odc.c		\
+	libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c	\
+	libarchive/test/test_read_format_cpio_svr4_gzip.c	\
+	libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c	\
+	libarchive/test/test_read_format_cpio_svr4c_Z.c		\
+	libarchive/test/test_read_format_empty.c		\
+	libarchive/test/test_read_format_gtar_filename.c	\
+	libarchive/test/test_read_format_gtar_gz.c		\
+	libarchive/test/test_read_format_gtar_lzma.c		\
+	libarchive/test/test_read_format_gtar_sparse.c		\
+	libarchive/test/test_read_format_iso_Z.c		\
+	libarchive/test/test_read_format_iso_multi_extent.c	\
+	libarchive/test/test_read_format_iso_xorriso.c		\
+	libarchive/test/test_read_format_isojoliet_bz2.c	\
+	libarchive/test/test_read_format_isojoliet_long.c	\
+	libarchive/test/test_read_format_isojoliet_rr.c		\
+	libarchive/test/test_read_format_isojoliet_versioned.c	\
+	libarchive/test/test_read_format_isorr_bz2.c		\
+	libarchive/test/test_read_format_isorr_ce.c		\
+	libarchive/test/test_read_format_isorr_new_bz2.c	\
+	libarchive/test/test_read_format_isorr_rr_moved.c	\
+	libarchive/test/test_read_format_isozisofs_bz2.c	\
+	libarchive/test/test_read_format_lha.c			\
+	libarchive/test/test_read_format_lha_filename.c		\
+	libarchive/test/test_read_format_mtree.c		\
+	libarchive/test/test_read_format_pax_bz2.c		\
+	libarchive/test/test_read_format_rar.c			\
+	libarchive/test/test_read_format_raw.c			\
+	libarchive/test/test_read_format_tar.c			\
+	libarchive/test/test_read_format_tar_empty_filename.c	\
+	libarchive/test/test_read_format_tar_filename.c		\
+	libarchive/test/test_read_format_tbz.c			\
+	libarchive/test/test_read_format_tgz.c			\
+	libarchive/test/test_read_format_tlz.c			\
+	libarchive/test/test_read_format_txz.c			\
+	libarchive/test/test_read_format_tz.c			\
+	libarchive/test/test_read_format_ustar_filename.c	\
+	libarchive/test/test_read_format_xar.c			\
+	libarchive/test/test_read_format_zip.c			\
+	libarchive/test/test_read_format_zip_comment_stored.c	\
+	libarchive/test/test_read_format_zip_filename.c		\
+	libarchive/test/test_read_format_zip_mac_metadata.c	\
+	libarchive/test/test_read_format_zip_sfx.c		\
+	libarchive/test/test_read_large.c			\
+	libarchive/test/test_read_pax_truncated.c		\
+	libarchive/test/test_read_position.c			\
+	libarchive/test/test_read_set_format.c			\
+	libarchive/test/test_read_truncated.c			\
+	libarchive/test/test_read_truncated_filter.c		\
+	libarchive/test/test_sparse_basic.c			\
+	libarchive/test/test_tar_filenames.c			\
+	libarchive/test/test_tar_large.c			\
+	libarchive/test/test_ustar_filenames.c			\
+	libarchive/test/test_ustar_filename_encoding.c		\
+	libarchive/test/test_write_disk.c			\
+	libarchive/test/test_write_disk_appledouble.c		\
+	libarchive/test/test_write_disk_failures.c		\
+	libarchive/test/test_write_disk_hardlink.c		\
+	libarchive/test/test_write_disk_hfs_compression.c	\
+	libarchive/test/test_write_disk_lookup.c		\
+	libarchive/test/test_write_disk_mac_metadata.c		\
+	libarchive/test/test_write_disk_no_hfs_compression.c	\
+	libarchive/test/test_write_disk_perms.c			\
+	libarchive/test/test_write_disk_secure.c		\
+	libarchive/test/test_write_disk_sparse.c		\
+	libarchive/test/test_write_disk_symlink.c		\
+	libarchive/test/test_write_disk_times.c			\
+	libarchive/test/test_write_filter_b64encode.c		\
+	libarchive/test/test_write_filter_bzip2.c		\
+	libarchive/test/test_write_filter_compress.c		\
+	libarchive/test/test_write_filter_gzip.c		\
+	libarchive/test/test_write_filter_gzip_timestamp.c	\
+	libarchive/test/test_write_filter_lrzip.c		\
+	libarchive/test/test_write_filter_lzip.c		\
+	libarchive/test/test_write_filter_lzma.c		\
+	libarchive/test/test_write_filter_lzop.c		\
+	libarchive/test/test_write_filter_program.c		\
+	libarchive/test/test_write_filter_uuencode.c		\
+	libarchive/test/test_write_filter_xz.c			\
+	libarchive/test/test_write_format_7zip.c		\
+	libarchive/test/test_write_format_7zip_empty.c		\
+	libarchive/test/test_write_format_7zip_large.c		\
+	libarchive/test/test_write_format_ar.c			\
+	libarchive/test/test_write_format_cpio.c		\
+	libarchive/test/test_write_format_cpio_empty.c		\
+	libarchive/test/test_write_format_cpio_newc.c		\
+	libarchive/test/test_write_format_cpio_odc.c		\
+	libarchive/test/test_write_format_gnutar.c		\
+	libarchive/test/test_write_format_iso9660.c		\
+	libarchive/test/test_write_format_iso9660_boot.c	\
+	libarchive/test/test_write_format_iso9660_empty.c	\
+	libarchive/test/test_write_format_iso9660_filename.c	\
+	libarchive/test/test_write_format_iso9660_zisofs.c	\
+	libarchive/test/test_write_format_mtree.c		\
+	libarchive/test/test_write_format_mtree_absolute_path.c	\
+	libarchive/test/test_write_format_mtree_classic.c	\
+	libarchive/test/test_write_format_mtree_classic_indent.c\
+	libarchive/test/test_write_format_mtree_fflags.c	\
+	libarchive/test/test_write_format_mtree_no_separator.c	\
+	libarchive/test/test_write_format_mtree_quoted_filename.c\
+	libarchive/test/test_write_format_pax.c			\
+	libarchive/test/test_write_format_shar_empty.c		\
+	libarchive/test/test_write_format_tar.c			\
+	libarchive/test/test_write_format_tar_empty.c		\
+	libarchive/test/test_write_format_tar_sparse.c		\
+	libarchive/test/test_write_format_tar_ustar.c		\
+	libarchive/test/test_write_format_tar_v7tar.c		\
+	libarchive/test/test_write_format_xar.c			\
+	libarchive/test/test_write_format_xar_empty.c		\
+	libarchive/test/test_write_format_zip.c			\
+	libarchive/test/test_write_format_zip_empty.c		\
+	libarchive/test/test_write_format_zip_no_compression.c	\
+	libarchive/test/test_write_open_memory.c		\
+	libarchive/test/test_write_zip_set_compression_store.c	\
+	libarchive/test/test_zip_filename_encoding.c
+
+libarchive_test_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/test_utils -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS)
+libarchive_test_LDADD= $(LTLIBICONV)
+
+# The "list.h" file just lists all of the tests defined in all of the sources.
+# Building it automatically provides a sanity-check on libarchive_test_SOURCES
+# above.
+libarchive/test/list.h: Makefile
+	cat $(top_srcdir)/libarchive/test/test_*.c | grep DEFINE_TEST > libarchive/test/list.h
+
+libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG
+
+libarchive_test_EXTRA_DIST=\
+	libarchive/test/list.h		\
+	libarchive/test/test_acl_pax.tar.uu				\
+	libarchive/test/test_archive_string_conversion.txt.Z.uu		\
+	libarchive/test/test_compat_bzip2_1.tbz.uu			\
+	libarchive/test/test_compat_bzip2_2.tbz.uu			\
+	libarchive/test/test_compat_cpio_1.cpio.uu			\
+	libarchive/test/test_compat_gtar_1.tar.uu			\
+	libarchive/test/test_compat_gzip_1.tgz.uu			\
+	libarchive/test/test_compat_gzip_2.tgz.uu			\
+	libarchive/test/test_compat_lzip_1.tlz.uu			\
+	libarchive/test/test_compat_lzip_2.tlz.uu			\
+	libarchive/test/test_compat_lzma_1.tlz.uu			\
+	libarchive/test/test_compat_lzma_2.tlz.uu			\
+	libarchive/test/test_compat_lzma_3.tlz.uu			\
+	libarchive/test/test_compat_lzop_1.tar.lzo.uu			\
+	libarchive/test/test_compat_lzop_2.tar.lzo.uu			\
+	libarchive/test/test_compat_lzop_3.tar.lzo.uu			\
+	libarchive/test/test_compat_mac-1.tar.Z.uu			\
+	libarchive/test/test_compat_mac-2.tar.Z.uu			\
+	libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu		\
+	libarchive/test/test_compat_solaris_tar_acl.tar.uu		\
+	libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu	\
+	libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu	\
+	libarchive/test/test_compat_tar_hardlink_1.tar.uu		\
+	libarchive/test/test_compat_xz_1.txz.uu				\
+	libarchive/test/test_compat_zip_1.zip.uu			\
+	libarchive/test/test_compat_zip_2.zip.uu			\
+	libarchive/test/test_compat_zip_3.zip.uu			\
+	libarchive/test/test_compat_zip_4.zip.uu			\
+	libarchive/test/test_compat_zip_5.zip.uu			\
+	libarchive/test/test_compat_zip_6.zip.uu			\
+	libarchive/test/test_compat_zip_7.xps.uu			\
+	libarchive/test/test_fuzz_1.iso.Z.uu				\
+	libarchive/test/test_fuzz.cab.uu				\
+	libarchive/test/test_fuzz.lzh.uu				\
+	libarchive/test/test_pax_filename_encoding.tar.uu		\
+	libarchive/test/test_rar_multivolume_multiple_files.part1.rar.uu \
+	libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu \
+	libarchive/test/test_rar_multivolume_multiple_files.part3.rar.uu \
+	libarchive/test/test_rar_multivolume_multiple_files.part4.rar.uu \
+	libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu \
+	libarchive/test/test_rar_multivolume_multiple_files.part6.rar.uu \
+	libarchive/test/test_rar_multivolume_single_file.part1.rar.uu	\
+	libarchive/test/test_rar_multivolume_single_file.part2.rar.uu	\
+	libarchive/test/test_rar_multivolume_single_file.part3.rar.uu	\
+	libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part02.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part03.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part04.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part05.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part06.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part07.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part08.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu \
+	libarchive/test/test_rar_multivolume_uncompressed_files.part10.rar.uu \
+	libarchive/test/test_read_filter_grzip.tar.grz.uu		\
+	libarchive/test/test_read_filter_lrzip.tar.lrz.uu		\
+	libarchive/test/test_read_filter_lzop.tar.lzo.uu		\
+	libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu	\
+	libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj_copy.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu		\
+	libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu	\
+	libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu	\
+	libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu	\
+	libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu	\
+	libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu	\
+	libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu	\
+	libarchive/test/test_read_format_7zip_bzip2.7z.uu		\
+	libarchive/test/test_read_format_7zip_copy.7z.uu		\
+	libarchive/test/test_read_format_7zip_copy_2.7z.uu		\
+	libarchive/test/test_read_format_7zip_deflate.7z.uu		\
+	libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu		\
+	libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu		\
+	libarchive/test/test_read_format_7zip_empty_archive.7z.uu	\
+	libarchive/test/test_read_format_7zip_empty_file.7z.uu		\
+	libarchive/test/test_read_format_7zip_lzma1.7z.uu		\
+	libarchive/test/test_read_format_7zip_lzma1_2.7z.uu		\
+	libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu		\
+	libarchive/test/test_read_format_7zip_lzma2.7z.uu		\
+	libarchive/test/test_read_format_7zip_ppmd.7z.uu		\
+	libarchive/test/test_read_format_7zip_symbolic_name.7z.uu	\
+	libarchive/test/test_read_format_ar.ar.uu			\
+	libarchive/test/test_read_format_cab_1.cab.uu			\
+	libarchive/test/test_read_format_cab_2.cab.uu			\
+	libarchive/test/test_read_format_cab_3.cab.uu			\
+	libarchive/test/test_read_format_cab_filename_cp932.cab.uu	\
+	libarchive/test/test_read_format_cpio_bin_be.cpio.uu		\
+	libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu	\
+	libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu	\
+	libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu	\
+	libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu	\
+	libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu	\
+	libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu	\
+	libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu	\
+	libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu	\
+	libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu	\
+	libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu	\
+	libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu	\
+	libarchive/test/test_read_format_gtar_sparse_1_17.tar.uu	\
+	libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tar.uu \
+	libarchive/test/test_read_format_gtar_sparse_1_17_posix01.tar.uu \
+	libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tar.uu \
+	libarchive/test/test_read_format_gtar_sparse_1_17_posix10_modified.tar.uu \
+	libarchive/test/test_read_format_iso.iso.Z.uu			\
+	libarchive/test/test_read_format_iso_2.iso.Z.uu			\
+	libarchive/test/test_read_format_iso_joliet.iso.Z.uu		\
+	libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu	\
+	libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu	\
+	libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu	\
+	libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu	\
+	libarchive/test/test_read_format_iso_rockridge.iso.Z.uu		\
+	libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu	\
+	libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu	\
+	libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu\
+	libarchive/test/test_read_format_iso_xorriso.iso.Z.uu		\
+	libarchive/test/test_read_format_iso_zisofs.iso.Z.uu		\
+	libarchive/test/test_read_format_lha_filename_cp932.lzh.uu	\
+	libarchive/test/test_read_format_lha_header0.lzh.uu		\
+	libarchive/test/test_read_format_lha_header1.lzh.uu		\
+	libarchive/test/test_read_format_lha_header2.lzh.uu		\
+	libarchive/test/test_read_format_lha_header3.lzh.uu		\
+	libarchive/test/test_read_format_lha_lh0.lzh.uu			\
+	libarchive/test/test_read_format_lha_lh6.lzh.uu			\
+	libarchive/test/test_read_format_lha_lh7.lzh.uu			\
+	libarchive/test/test_read_format_lha_withjunk.lzh.uu		\
+	libarchive/test/test_read_format_mtree.mtree.uu			\
+	libarchive/test/test_read_format_mtree_nomagic.mtree.uu		\
+	libarchive/test/test_read_format_mtree_nomagic2.mtree.uu	\
+	libarchive/test/test_read_format_mtree_nomagic3.mtree.uu	\
+	libarchive/test/test_read_format_rar.rar.uu			\
+	libarchive/test/test_read_format_rar_binary_data.rar.uu		\
+	libarchive/test/test_read_format_rar_compress_best.rar.uu	\
+	libarchive/test/test_read_format_rar_compress_normal.rar.uu	\
+	libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu	\
+	libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu\
+	libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu\
+	libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu\
+	libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu\
+	libarchive/test/test_read_format_rar_noeof.rar.uu		\
+	libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu\
+	libarchive/test/test_read_format_rar_sfx.exe.uu			\
+	libarchive/test/test_read_format_rar_subblock.rar.uu		\
+	libarchive/test/test_read_format_rar_unicode.rar.uu		\
+	libarchive/test/test_read_format_rar_windows.rar.uu		\
+	libarchive/test/test_read_format_raw.data.Z.uu			\
+	libarchive/test/test_read_format_raw.data.uu			\
+	libarchive/test/test_read_format_tar_empty_filename.tar.uu	\
+	libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu	\
+	libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu	\
+	libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu	\
+	libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu	\
+	libarchive/test/test_read_format_zip.zip.uu			\
+	libarchive/test/test_read_format_zip_comment_stored_1.zip.uu	\
+	libarchive/test/test_read_format_zip_comment_stored_2.zip.uu	\
+	libarchive/test/test_read_format_zip_filename_cp866.zip.uu	\
+	libarchive/test/test_read_format_zip_filename_cp932.zip.uu	\
+	libarchive/test/test_read_format_zip_filename_koi8r.zip.uu	\
+	libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu	\
+	libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu	\
+	libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu	\
+	libarchive/test/test_read_format_zip_length_at_end.zip.uu	\
+	libarchive/test/test_read_format_zip_mac_metadata.zip.uu	\
+	libarchive/test/test_read_format_zip_sfx.uu			\
+	libarchive/test/test_read_format_zip_symlink.zip.uu		\
+	libarchive/test/test_read_format_zip_ux.zip.uu			\
+	libarchive/test/test_read_large_splitted_rar_aa.uu		\
+	libarchive/test/test_read_large_splitted_rar_ab.uu		\
+	libarchive/test/test_read_large_splitted_rar_ac.uu		\
+	libarchive/test/test_read_large_splitted_rar_ad.uu		\
+	libarchive/test/test_read_large_splitted_rar_ae.uu		\
+	libarchive/test/test_read_splitted_rar_aa.uu			\
+	libarchive/test/test_read_splitted_rar_ab.uu			\
+	libarchive/test/test_read_splitted_rar_ac.uu			\
+	libarchive/test/test_read_splitted_rar_ad.uu			\
+	libarchive/test/test_splitted_rar_seek_support_aa.uu		\
+	libarchive/test/test_splitted_rar_seek_support_ab.uu		\
+	libarchive/test/test_splitted_rar_seek_support_ac.uu		\
+	libarchive/test/test_write_disk_appledouble.cpio.gz.uu	\
+	libarchive/test/test_write_disk_hfs_compression.tgz.uu		\
+	libarchive/test/test_write_disk_mac_metadata.tar.gz.uu		\
+	libarchive/test/test_write_disk_no_hfs_compression.tgz.uu	\
+	libarchive/test/CMakeLists.txt					\
+	libarchive/test/README
+
+#
+# Common code for libarchive frontends (cpio, tar)
+#
+libarchive_fe_la_SOURCES=			\
+	libarchive_fe/err.c			\
+	libarchive_fe/err.h			\
+	libarchive_fe/lafe_platform.h		\
+	libarchive_fe/line_reader.c		\
+	libarchive_fe/line_reader.h
+
+libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
+#
+#
+# bsdtar source, docs, etc.
+#
+#
+
+bsdtar_SOURCES=				\
+		tar/bsdtar.c		\
+		tar/bsdtar.h		\
+		tar/bsdtar_platform.h	\
+		tar/cmdline.c		\
+		tar/creation_set.c	\
+		tar/read.c		\
+		tar/subst.c		\
+		tar/util.c		\
+		tar/write.c
+
+if INC_WINDOWS_FILES
+bsdtar_SOURCES+=			\
+		tar/bsdtar_windows.h	\
+		tar/bsdtar_windows.c
+endif
+
+bsdtar_DEPENDENCIES= libarchive.la libarchive_fe.la
+
+if STATIC_BSDTAR
+bsdtar_ldstatic= -static
+bsdtar_ccstatic= -DLIBARCHIVE_STATIC
+else
+bsdtar_ldstatic=
+bsdtar_ccstatic=
+endif
+
+bsdtar_LDADD= libarchive.la libarchive_fe.la $(LTLIBICONV)
+bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS)
+bsdtar_LDFLAGS= $(bsdtar_ldstatic)
+
+bsdtar_EXTRA_DIST=		\
+	tar/bsdtar.1		\
+	tar/bsdtar_windows.h	\
+	tar/bsdtar_windows.c	\
+	tar/CMakeLists.txt	\
+	tar/config_freebsd.h
+
+
+if BUILD_BSDTAR
+bsdtar_man_MANS= tar/bsdtar.1
+bsdtar_programs= bsdtar
+else
+bsdtar_man_MANS=
+bsdtar_programs=
+endif
+
+#
+# bsdtar_test
+#
+
+bsdtar_test_SOURCES=						\
+	$(test_utils_SOURCES)					\
+	tar/test/main.c						\
+	tar/test/test.h						\
+	tar/test/test_0.c					\
+	tar/test/test_basic.c					\
+	tar/test/test_copy.c					\
+	tar/test/test_empty_mtree.c				\
+	tar/test/test_extract_tar_Z.c				\
+	tar/test/test_extract_tar_bz2.c				\
+	tar/test/test_extract_tar_grz.c				\
+	tar/test/test_extract_tar_gz.c				\
+	tar/test/test_extract_tar_lrz.c				\
+	tar/test/test_extract_tar_lz.c				\
+	tar/test/test_extract_tar_lzma.c			\
+	tar/test/test_extract_tar_lzo.c				\
+	tar/test/test_extract_tar_xz.c				\
+	tar/test/test_format_newc.c				\
+	tar/test/test_help.c					\
+	tar/test/test_option_C_upper.c				\
+	tar/test/test_option_H_upper.c				\
+	tar/test/test_option_L_upper.c				\
+	tar/test/test_option_O_upper.c				\
+	tar/test/test_option_T_upper.c				\
+	tar/test/test_option_U_upper.c				\
+	tar/test/test_option_X_upper.c				\
+	tar/test/test_option_a.c				\
+	tar/test/test_option_b.c				\
+	tar/test/test_option_b64encode.c			\
+	tar/test/test_option_exclude.c				\
+	tar/test/test_option_gid_gname.c			\
+	tar/test/test_option_grzip.c				\
+	tar/test/test_option_j.c				\
+	tar/test/test_option_k.c				\
+	tar/test/test_option_keep_newer_files.c			\
+	tar/test/test_option_lrzip.c				\
+	tar/test/test_option_lzma.c				\
+	tar/test/test_option_lzop.c				\
+	tar/test/test_option_n.c				\
+	tar/test/test_option_newer_than.c			\
+	tar/test/test_option_nodump.c				\
+	tar/test/test_option_older_than.c			\
+	tar/test/test_option_q.c				\
+	tar/test/test_option_r.c				\
+	tar/test/test_option_s.c				\
+	tar/test/test_option_uid_uname.c			\
+	tar/test/test_option_uuencode.c				\
+	tar/test/test_option_xz.c				\
+	tar/test/test_option_z.c				\
+	tar/test/test_patterns.c				\
+	tar/test/test_print_longpath.c				\
+	tar/test/test_stdio.c					\
+	tar/test/test_strip_components.c			\
+	tar/test/test_symlink_dir.c				\
+	tar/test/test_version.c					\
+	tar/test/test_windows.c
+
+bsdtar_test_CPPFLAGS=\
+	-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \
+	-I$(top_srcdir)/test_utils \
+	-I$(top_srcdir)/tar -I$(top_builddir)/tar/test \
+	$(PLATFORMCPPFLAGS)
+
+tar/test/list.h: Makefile
+	cat $(top_srcdir)/tar/test/test_*.c | grep DEFINE_TEST > tar/test/list.h
+
+if BUILD_BSDTAR
+bsdtar_test_programs= bsdtar_test
+bsdtar_TESTS_ENVIRONMENT= BSDTAR=`cd $(top_builddir);/bin/pwd`/bsdtar$(EXEEXT) BSDTAR_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/tar/test
+else
+bsdtar_test_programs=
+bsdtar_TESTS_ENVIRONMENT=
+endif
+
+bsdtar_test_EXTRA_DIST=			\
+	tar/test/list.h \
+	tar/test/test_extract.tar.Z.uu	 \
+	tar/test/test_extract.tar.bz2.uu \
+	tar/test/test_extract.tar.grz.uu \
+	tar/test/test_extract.tar.gz.uu	 \
+	tar/test/test_extract.tar.lrz.uu \
+	tar/test/test_extract.tar.lz.uu  \
+	tar/test/test_extract.tar.lzma.uu \
+	tar/test/test_extract.tar.lzo.uu \
+	tar/test/test_extract.tar.xz.uu \
+	tar/test/test_option_keep_newer_files.tar.Z.uu \
+	tar/test/test_option_s.tar.Z.uu \
+	tar/test/test_patterns_2.tar.uu	\
+	tar/test/test_patterns_3.tar.uu	\
+	tar/test/test_patterns_4.tar.uu	\
+	tar/test/test_print_longpath.tar.Z.uu \
+	tar/test/CMakeLists.txt
+
+
+#
+#
+# bsdcpio source, docs, etc.
+#
+#
+
+bsdcpio_SOURCES=			\
+		cpio/cmdline.c		\
+		cpio/cpio.c		\
+		cpio/cpio.h		\
+		cpio/cpio_platform.h
+
+if INC_WINDOWS_FILES
+bsdcpio_SOURCES+=			\
+		cpio/cpio_windows.h	\
+		cpio/cpio_windows.c
+endif
+
+bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la
+
+
+if STATIC_BSDCPIO
+bsdcpio_ldstatic= -static
+bsdcpio_ccstatic= -DLIBARCHIVE_STATIC
+else
+bsdcpio_ldstatic=
+bsdcpio_ccstatic=
+endif
+
+bsdcpio_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV)
+bsdcpio_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcpio_ccstatic) $(PLATFORMCPPFLAGS)
+bsdcpio_LDFLAGS= $(bsdcpio_ldstatic)
+
+bsdcpio_EXTRA_DIST=		\
+	cpio/bsdcpio.1		\
+	cpio/cpio_windows.h	\
+	cpio/cpio_windows.c	\
+	cpio/CMakeLists.txt	\
+	cpio/config_freebsd.h
+
+
+if BUILD_BSDCPIO
+# Manpages to install
+bsdcpio_man_MANS= cpio/bsdcpio.1
+bsdcpio_programs= bsdcpio
+else
+bsdcpio_man_MANS=
+bsdcpio_programs=
+endif
+
+#
+# bsdcpio_test
+#
+
+bsdcpio_test_SOURCES=						\
+	$(test_utils_SOURCES)					\
+	cpio/cmdline.c						\
+	cpio/test/main.c					\
+	cpio/test/test.h					\
+	cpio/test/test_0.c					\
+	cpio/test/test_basic.c					\
+	cpio/test/test_cmdline.c				\
+	cpio/test/test_extract_cpio_Z.c				\
+	cpio/test/test_extract_cpio_bz2.c			\
+	cpio/test/test_extract_cpio_grz.c			\
+	cpio/test/test_extract_cpio_gz.c			\
+	cpio/test/test_extract_cpio_lrz.c			\
+	cpio/test/test_extract_cpio_lz.c			\
+	cpio/test/test_extract_cpio_lzma.c			\
+	cpio/test/test_extract_cpio_lzo.c			\
+	cpio/test/test_extract_cpio_xz.c			\
+	cpio/test/test_format_newc.c				\
+	cpio/test/test_gcpio_compat.c				\
+	cpio/test/test_option_0.c				\
+	cpio/test/test_option_B_upper.c				\
+	cpio/test/test_option_C_upper.c				\
+	cpio/test/test_option_J_upper.c				\
+	cpio/test/test_option_L_upper.c				\
+	cpio/test/test_option_Z_upper.c				\
+	cpio/test/test_option_a.c				\
+	cpio/test/test_option_b64encode.c			\
+	cpio/test/test_option_c.c				\
+	cpio/test/test_option_d.c				\
+	cpio/test/test_option_f.c				\
+	cpio/test/test_option_grzip.c				\
+	cpio/test/test_option_help.c				\
+	cpio/test/test_option_l.c				\
+	cpio/test/test_option_lrzip.c				\
+	cpio/test/test_option_lzma.c				\
+	cpio/test/test_option_lzop.c				\
+	cpio/test/test_option_m.c				\
+	cpio/test/test_option_t.c				\
+	cpio/test/test_option_u.c				\
+	cpio/test/test_option_uuencode.c			\
+	cpio/test/test_option_version.c				\
+	cpio/test/test_option_xz.c				\
+	cpio/test/test_option_y.c				\
+	cpio/test/test_option_z.c				\
+	cpio/test/test_owner_parse.c				\
+	cpio/test/test_passthrough_dotdot.c			\
+	cpio/test/test_passthrough_reverse.c
+
+bsdcpio_test_CPPFLAGS= \
+	-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \
+	-I$(top_srcdir)/test_utils \
+	-I$(top_srcdir)/cpio -I$(top_builddir)/cpio/test \
+	$(PLATFORMCPPFLAGS)
+bsdcpio_test_LDADD=libarchive_fe.la
+
+cpio/test/list.h: Makefile
+	cat $(top_srcdir)/cpio/test/test_*.c | grep DEFINE_TEST > cpio/test/list.h
+
+if BUILD_BSDCPIO
+bsdcpio_test_programs= bsdcpio_test
+bsdcpio_TESTS_ENVIRONMENT= BSDCPIO=`cd $(top_builddir);/bin/pwd`/bsdcpio$(EXEEXT) BSDCPIO_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/cpio/test
+else
+bsdcpio_test_programs=
+bsdcpio_TESTS_ENVIRONMENT=
+endif
+
+bsdcpio_test_EXTRA_DIST=			\
+	cpio/test/list.h	\
+	cpio/test/test_extract.cpio.Z.uu	\
+	cpio/test/test_extract.cpio.bz2.uu	\
+	cpio/test/test_extract.cpio.grz.uu	\
+	cpio/test/test_extract.cpio.gz.uu	\
+	cpio/test/test_extract.cpio.lrz.uu	\
+	cpio/test/test_extract.cpio.lz.uu	\
+	cpio/test/test_extract.cpio.lzma.uu	\
+	cpio/test/test_extract.cpio.lzo.uu	\
+	cpio/test/test_extract.cpio.xz.uu	\
+	cpio/test/test_gcpio_compat_ref.bin.uu	\
+	cpio/test/test_gcpio_compat_ref.crc.uu	\
+	cpio/test/test_gcpio_compat_ref.newc.uu	\
+	cpio/test/test_gcpio_compat_ref.ustar.uu \
+	cpio/test/test_gcpio_compat_ref_nosym.bin.uu \
+	cpio/test/test_gcpio_compat_ref_nosym.crc.uu \
+	cpio/test/test_gcpio_compat_ref_nosym.newc.uu \
+	cpio/test/test_gcpio_compat_ref_nosym.ustar.uu \
+	cpio/test/test_option_f.cpio.uu		\
+	cpio/test/test_option_m.cpio.uu		\
+	cpio/test/test_option_t.cpio.uu		\
+	cpio/test/test_option_t.stdout.uu	\
+	cpio/test/test_option_tv.stdout.uu	\
+	cpio/test/CMakeLists.txt
diff --git a/build/README.txt b/build/README.txt
new file mode 100644
index 000000000000..ce8e1a32a577
--- /dev/null
+++ b/build/README.txt
@@ -0,0 +1,35 @@
+Notes on making a new release of libarchive
+===========================================
+
+The following serves as a guide for libarchive developers on the general
+process to be followed when making a new release of libarchive.
+
+* Update build/version with the version number of the release to be made.
+* If the library's ABI has changed, the library's soname major version *MUST*
+  be updated. Update configure.ac and CMakeLists.txt appropriately.
+  - For configure.ac, the variable ARCHIVE_INTERFACE needs to be updated.
+  - For CMakeLists.txt, the variable INTERFACE_VERSION needs to be updated.
+* Update the entries in the NEWS file accordingly.
+* Run `build/makerelease.sh` from the top source directory. Running this script
+  will do the following.
+  - Removes all Makefile.am development build specific CFLAGS from
+    Makefile.am.
+  - Update configure scripts and header files with the appropriate version
+    number from build/version.
+  - Rebuild the documentation directory.
+  - Runs a full cmake build and test.
+  - Runs a full autotools build and test.
+  - Builds the .tar.gz and .zip distribution files.
+* Commit all changed files into git.
+  - This should be build/version, NEWS, and the files edited by running
+    build/makerelease.sh.
+* Tag the release appropriately. The tag should also have an appropriate
+  message.
+  - The git command is as follows:
+    $ git tag -m "Libarchive <version>" v<version>
+    Replace <version> with the version to be released.
+* Copy all the generated wiki files and commit them into the libarchive.wiki
+  repository. Overwrite any preexisting files with the same name (these files
+  are always autogenerated from the libarchive release after every release).
+* Update the libarchive.org website accordingly.
+* Make an announcement to the libarchive-announce mailing list.
diff --git a/build/autoconf/check_stdcall_func.m4 b/build/autoconf/check_stdcall_func.m4
new file mode 100644
index 000000000000..926b046c5330
--- /dev/null
+++ b/build/autoconf/check_stdcall_func.m4
@@ -0,0 +1,51 @@
+# AC_LANG_STDCALL_FUNC_LINK_TRY(FUNCTION, SIGNATURE)
+# -------------------------------
+# Produce a source which links correctly iff the FUNCTION exists.
+AC_DEFUN([AC_LANG_STDCALL_FUNC_LINK_TRY],
+[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
+
+# AC_CHECK_STDCALL_FUNC(FUNCTION, SIGNATURE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -----------------------------------------------------------------
+AC_DEFUN([AC_CHECK_STDCALL_FUNC],
+[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$1])dnl
+AC_CACHE_CHECK([for $1], ac_var,
+[AC_LINK_IFELSE([AC_LANG_STDCALL_FUNC_LINK_TRY([$1],[$2])],
+                [AS_VAR_SET(ac_var, yes)],
+                [AS_VAR_SET(ac_var, no)])])
+AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])# AC_CHECK_FUNC
+
+# AC_LANG_STDCALL_FUNC_LINK_TRY(C)(FUNCTION, SIGNATURE)
+# ----------------------------------
+# Don't include <ctype.h> because on OSF/1 3.0 it includes
+# <sys/types.h> which includes <sys/select.h> which contains a
+# prototype for select.  Similarly for bzero.
+m4_define([AC_LANG_STDCALL_FUNC_LINK_TRY(C)],
+[AC_LANG_PROGRAM(
+[/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char __stdcall $1 ( $2 ) below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char __stdcall $1 ( $2 );
+char (*f) ( $2 );
+],
+[/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$1) || defined (__stub___$1)
+choke me
+#else
+f = $1;
+#endif
+])])
+
+# AC_LANG_STDCALL_FUNC_LINK_TRY(C++)(FUNCTION)
+# ------------------------------------
+m4_copy([AC_LANG_STDCALL_FUNC_LINK_TRY(C)], [AC_LANG_STDCALL_FUNC_LINK_TRY(C++)])
+
diff --git a/build/autoconf/config.rpath b/build/autoconf/config.rpath
new file mode 100755
index 000000000000..8a8cf8edec5e
--- /dev/null
+++ b/build/autoconf/config.rpath
@@ -0,0 +1,696 @@
+#! /bin/sh
+#
+# NOTE: This file was brought from
+#       http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/config.rpath
+#       You should sometimes check if the file is updated and bring it to
+#       our trunk and copy this note to the top of that file.
+#
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+#   Copyright 1996-2011 Free Software Foundation, Inc.
+#   Taken from GNU libtool, 2001
+#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+#   This file is free software; the Free Software Foundation gives
+#   unlimited permission to copy and/or distribute it, with or without
+#   modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+#   than 256 bytes, otherwise the compiler driver will dump core. The only
+#   known workaround is to choose shorter directory names for the build
+#   directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+  wl='-Wl,'
+else
+  case "$host_os" in
+    aix*)
+      wl='-Wl,'
+      ;;
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      ;;
+    hpux9* | hpux10* | hpux11*)
+      wl='-Wl,'
+      ;;
+    irix5* | irix6* | nonstopux*)
+      wl='-Wl,'
+      ;;
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+        ecc*)
+          wl='-Wl,'
+          ;;
+        icc* | ifort*)
+          wl='-Wl,'
+          ;;
+        lf95*)
+          wl='-Wl,'
+          ;;
+        nagfor*)
+          wl='-Wl,-Wl,,'
+          ;;
+        pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+          wl='-Wl,'
+          ;;
+        ccc*)
+          wl='-Wl,'
+          ;;
+        xl* | bgxl* | bgf* | mpixl*)
+          wl='-Wl,'
+          ;;
+        como)
+          wl='-lopt='
+          ;;
+        *)
+          case `$CC -V 2>&1 | sed 5q` in
+            *Sun\ F* | *Sun*Fortran*)
+              wl=
+              ;;
+            *Sun\ C*)
+              wl='-Wl,'
+              ;;
+          esac
+          ;;
+      esac
+      ;;
+    newsos6)
+      ;;
+    *nto* | *qnx*)
+      ;;
+    osf3* | osf4* | osf5*)
+      wl='-Wl,'
+      ;;
+    rdos*)
+      ;;
+    solaris*)
+      case $cc_basename in
+        f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+          wl='-Qoption ld '
+          ;;
+        *)
+          wl='-Wl,'
+          ;;
+      esac
+      ;;
+    sunos4*)
+      wl='-Qoption ld '
+      ;;
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      wl='-Wl,'
+      ;;
+    sysv4*MP*)
+      ;;
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      wl='-Wl,'
+      ;;
+    unicos*)
+      wl='-Wl,'
+      ;;
+    uts4*)
+      ;;
+  esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # Set some defaults for GNU ld with shared library support. These
+  # are reset later if shared libraries are not supported. Putting them
+  # here allows them to be overridden if necessary.
+  # Unlike libtool, we use -rpath here, not --rpath, since the documented
+  # option of GNU ld is called -rpath, not --rpath.
+  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+  case "$host_os" in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+        ld_shlibs=no
+      fi
+      ;;
+    amigaos*)
+      case "$host_cpu" in
+        powerpc)
+          ;;
+        m68k)
+          hardcode_libdir_flag_spec='-L$libdir'
+          hardcode_minus_L=yes
+          ;;
+      esac
+      ;;
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    cygwin* | mingw* | pw32* | cegcc*)
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    haiku*)
+      ;;
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      ;;
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    netbsd*)
+      ;;
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+        ld_shlibs=no
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+          ld_shlibs=no
+          ;;
+        *)
+          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+          else
+            ld_shlibs=no
+          fi
+          ;;
+      esac
+      ;;
+    sunos4*)
+      hardcode_direct=yes
+      ;;
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+  esac
+  if test "$ld_shlibs" = no; then
+    hardcode_libdir_flag_spec=
+  fi
+else
+  case "$host_os" in
+    aix3*)
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes; then
+        # Neither direct hardcoding nor static linking is supported with a
+        # broken collect2.
+        hardcode_direct=unsupported
+      fi
+      ;;
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+        # On IA64, the linker does run time linking by default, so we don't
+        # have to do anything special.
+        aix_use_runtimelinking=no
+      else
+        aix_use_runtimelinking=no
+        # Test if we are trying to use run time linking or normal
+        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+        # need to do runtime linking.
+        case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+          for ld_flag in $LDFLAGS; do
+            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+              aix_use_runtimelinking=yes
+              break
+            fi
+          done
+          ;;
+        esac
+      fi
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      if test "$GCC" = yes; then
+        case $host_os in aix4.[012]|aix4.[012].*)
+          collect2name=`${CC} -print-prog-name=collect2`
+          if test -f "$collect2name" && \
+            strings "$collect2name" | grep resolve_lib_name >/dev/null
+          then
+            # We have reworked collect2
+            :
+          else
+            # We have old collect2
+            hardcode_direct=unsupported
+            hardcode_minus_L=yes
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_libdir_separator=
+          fi
+          ;;
+        esac
+      fi
+      # Begin _LT_AC_SYS_LIBPATH_AIX.
+      echo 'int main () { return 0; }' > conftest.c
+      ${CC} ${LDFLAGS} conftest.c -o conftest
+      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+      if test -z "$aix_libpath"; then
+        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+      fi
+      if test -z "$aix_libpath"; then
+        aix_libpath="/usr/lib:/lib"
+      fi
+      rm -f conftest.c conftest
+      # End _LT_AC_SYS_LIBPATH_AIX.
+      if test "$aix_use_runtimelinking" = yes; then
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+      else
+        if test "$host_cpu" = ia64; then
+          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+        else
+          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        fi
+      fi
+      ;;
+    amigaos*)
+      case "$host_cpu" in
+        powerpc)
+          ;;
+        m68k)
+          hardcode_libdir_flag_spec='-L$libdir'
+          hardcode_minus_L=yes
+          ;;
+      esac
+      ;;
+    bsdi[45]*)
+      ;;
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      libext=lib
+      ;;
+    darwin* | rhapsody*)
+      hardcode_direct=no
+      if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    dgux*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      ;;
+    freebsd2.2*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    freebsd2*)
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      ;;
+    freebsd* | dragonfly*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    hpux9*)
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      ;;
+    hpux10*)
+      if test "$with_gnu_ld" = no; then
+        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator=:
+        hardcode_direct=yes
+        # hardcode_minus_L: Not really in the search PATH,
+        # but as the default location of the library.
+        hardcode_minus_L=yes
+      fi
+      ;;
+    hpux11*)
+      if test "$with_gnu_ld" = no; then
+        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator=:
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct=no
+            ;;
+          *)
+            hardcode_direct=yes
+            # hardcode_minus_L: Not really in the search PATH,
+            # but as the default location of the library.
+            hardcode_minus_L=yes
+            ;;
+        esac
+      fi
+      ;;
+    irix5* | irix6* | nonstopux*)
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    netbsd*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    newsos6)
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    *nto* | *qnx*)
+      ;;
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+        hardcode_direct=yes
+        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+        else
+          case "$host_os" in
+            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+              hardcode_libdir_flag_spec='-R$libdir'
+              ;;
+            *)
+              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+              ;;
+          esac
+        fi
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      ;;
+    osf3*)
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    osf4* | osf5*)
+      if test "$GCC" = yes; then
+        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+        # Both cc and cxx compiler support -rpath directly
+        hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+    solaris*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      ;;
+    sunos4*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      ;;
+    sysv4)
+      case $host_vendor in
+        sni)
+          hardcode_direct=yes # is this really true???
+          ;;
+        siemens)
+          hardcode_direct=no
+          ;;
+        motorola)
+          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+          ;;
+      esac
+      ;;
+    sysv4.3*)
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+        ld_shlibs=yes
+      fi
+      ;;
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      ;;
+    sysv5* | sco3.2v5* | sco5v6*)
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator=':'
+      ;;
+    uts4*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      ;;
+    *)
+      ld_shlibs=no
+      ;;
+  esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec=      # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+  aix3*)
+    library_names_spec='$libname.a'
+    ;;
+  aix[4-9]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  amigaos*)
+    case "$host_cpu" in
+      powerpc*)
+        library_names_spec='$libname$shrext' ;;
+      m68k)
+        library_names_spec='$libname.a' ;;
+    esac
+    ;;
+  beos*)
+    library_names_spec='$libname$shrext'
+    ;;
+  bsdi[45]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  cygwin* | mingw* | pw32* | cegcc*)
+    shrext=.dll
+    library_names_spec='$libname.dll.a $libname.lib'
+    ;;
+  darwin* | rhapsody*)
+    shrext=.dylib
+    library_names_spec='$libname$shrext'
+    ;;
+  dgux*)
+    library_names_spec='$libname$shrext'
+    ;;
+  freebsd* | dragonfly*)
+    case "$host_os" in
+      freebsd[123]*)
+        library_names_spec='$libname$shrext$versuffix' ;;
+      *)
+        library_names_spec='$libname$shrext' ;;
+    esac
+    ;;
+  gnu*)
+    library_names_spec='$libname$shrext'
+    ;;
+  haiku*)
+    library_names_spec='$libname$shrext'
+    ;;
+  hpux9* | hpux10* | hpux11*)
+    case $host_cpu in
+      ia64*)
+        shrext=.so
+        ;;
+      hppa*64*)
+        shrext=.sl
+        ;;
+      *)
+        shrext=.sl
+        ;;
+    esac
+    library_names_spec='$libname$shrext'
+    ;;
+  interix[3-9]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  irix5* | irix6* | nonstopux*)
+    library_names_spec='$libname$shrext'
+    case "$host_os" in
+      irix5* | nonstopux*)
+        libsuff= shlibsuff=
+        ;;
+      *)
+        case $LD in
+          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+          *) libsuff= shlibsuff= ;;
+        esac
+        ;;
+    esac
+    ;;
+  linux*oldld* | linux*aout* | linux*coff*)
+    ;;
+  linux* | k*bsd*-gnu | kopensolaris*-gnu)
+    library_names_spec='$libname$shrext'
+    ;;
+  knetbsd*-gnu)
+    library_names_spec='$libname$shrext'
+    ;;
+  netbsd*)
+    library_names_spec='$libname$shrext'
+    ;;
+  newsos6)
+    library_names_spec='$libname$shrext'
+    ;;
+  *nto* | *qnx*)
+    library_names_spec='$libname$shrext'
+    ;;
+  openbsd*)
+    library_names_spec='$libname$shrext$versuffix'
+    ;;
+  os2*)
+    libname_spec='$name'
+    shrext=.dll
+    library_names_spec='$libname.a'
+    ;;
+  osf3* | osf4* | osf5*)
+    library_names_spec='$libname$shrext'
+    ;;
+  rdos*)
+    ;;
+  solaris*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sunos4*)
+    library_names_spec='$libname$shrext$versuffix'
+    ;;
+  sysv4 | sysv4.3*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sysv4*MP*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+    library_names_spec='$libname$shrext'
+    ;;
+  tpf*)
+    library_names_spec='$libname$shrext'
+    ;;
+  uts4*)
+    library_names_spec='$libname$shrext'
+    ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/build/autoconf/iconv.m4 b/build/autoconf/iconv.m4
new file mode 100644
index 000000000000..98fcd64d313c
--- /dev/null
+++ b/build/autoconf/iconv.m4
@@ -0,0 +1,268 @@
+# iconv.m4 serial 18 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+
+  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+  dnl accordingly.
+  AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+  dnl those with the standalone portable GNU libiconv installed).
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+  dnl accordingly.
+  AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+  dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+  dnl because if the user has installed libiconv and not disabled its use
+  dnl via --without-libiconv-prefix, he wants to use it. The first
+  dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
+  am_save_CPPFLAGS="$CPPFLAGS"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+  AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
+    am_cv_func_iconv="no, consider installing GNU libiconv"
+    am_cv_lib_iconv=no
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM(
+         [[
+#include <stdlib.h>
+#include <iconv.h>
+         ]],
+         [[iconv_t cd = iconv_open("","");
+           iconv(cd,NULL,NULL,NULL,NULL);
+           iconv_close(cd);]])],
+      [am_cv_func_iconv=yes])
+    if test "$am_cv_func_iconv" != yes; then
+      am_save_LIBS="$LIBS"
+      LIBS="$LIBS $LIBICONV"
+      AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[
+#include <stdlib.h>
+#include <iconv.h>
+           ]],
+           [[iconv_t cd = iconv_open("","");
+             iconv(cd,NULL,NULL,NULL,NULL);
+             iconv_close(cd);]])],
+        [am_cv_lib_iconv=yes]
+        [am_cv_func_iconv=yes])
+      LIBS="$am_save_LIBS"
+    fi
+  ])
+  if test "$am_cv_func_iconv" = yes; then
+    AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
+      dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
+      dnl Solaris 10.
+      am_save_LIBS="$LIBS"
+      if test $am_cv_lib_iconv = yes; then
+        LIBS="$LIBS $LIBICONV"
+      fi
+      AC_RUN_IFELSE(
+        [AC_LANG_SOURCE([[
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+  int result = 0;
+  /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+     returns.  */
+  {
+    iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+    if (cd_utf8_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\342\202\254"; /* EURO SIGN */
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_utf8_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          result |= 1;
+        iconv_close (cd_utf8_to_88591);
+      }
+  }
+  /* Test against Solaris 10 bug: Failures are not distinguishable from
+     successful returns.  */
+  {
+    iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+    if (cd_ascii_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\263";
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_ascii_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          result |= 2;
+        iconv_close (cd_ascii_to_88591);
+      }
+  }
+  /* Test against AIX 6.1..7.1 bug: Buffer overrun.  */
+  {
+    iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+    if (cd_88591_to_utf8 != (iconv_t)(-1))
+      {
+        static const char input[] = "\304";
+        static char buf[2] = { (char)0xDE, (char)0xAD };
+        const char *inptr = input;
+        size_t inbytesleft = 1;
+        char *outptr = buf;
+        size_t outbytesleft = 1;
+        size_t res = iconv (cd_88591_to_utf8,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
+          result |= 4;
+        iconv_close (cd_88591_to_utf8);
+      }
+  }
+#if 0 /* This bug could be worked around by the caller.  */
+  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
+  {
+    iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+    if (cd_88591_to_utf8 != (iconv_t)(-1))
+      {
+        static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+        char buf[50];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_88591_to_utf8,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if ((int)res > 0)
+          result |= 8;
+        iconv_close (cd_88591_to_utf8);
+      }
+  }
+#endif
+  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+     provided.  */
+  if (/* Try standardized names.  */
+      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+      /* Try IRIX, OSF/1 names.  */
+      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+      /* Try AIX names.  */
+      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+      /* Try HP-UX names.  */
+      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+    result |= 16;
+  return result;
+}]])],
+        [am_cv_func_iconv_works=yes],
+        [am_cv_func_iconv_works=no],
+        [
+changequote(,)dnl
+         case "$host_os" in
+           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+           *)            am_cv_func_iconv_works="guessing yes" ;;
+         esac
+changequote([,])dnl
+        ])
+      LIBS="$am_save_LIBS"
+    ])
+    case "$am_cv_func_iconv_works" in
+      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+      *)   am_func_iconv=yes ;;
+    esac
+  else
+    am_func_iconv=no am_cv_lib_iconv=no
+  fi
+  if test "$am_func_iconv" = yes; then
+    AC_DEFINE([HAVE_ICONV], [1],
+      [Define if you have the iconv() function and it works.])
+  fi
+  if test "$am_cv_lib_iconv" = yes; then
+    AC_MSG_CHECKING([how to link with libiconv])
+    AC_MSG_RESULT([$LIBICONV])
+  else
+    dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+    dnl either.
+    CPPFLAGS="$am_save_CPPFLAGS"
+    LIBICONV=
+    LTLIBICONV=
+  fi
+  AC_SUBST([LIBICONV])
+  AC_SUBST([LTLIBICONV])
+])
+
+dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
+dnl avoid warnings like
+dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
+dnl This is tricky because of the way 'aclocal' is implemented:
+dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
+dnl   Otherwise aclocal's initial scan pass would miss the macro definition.
+dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
+dnl   Otherwise aclocal would emit many "Use of uninitialized value $1"
+dnl   warnings.
+m4_define([gl_iconv_AC_DEFUN],
+  m4_version_prereq([2.64],
+    [[AC_DEFUN_ONCE(
+        [$1], [$2])]],
+    [m4_ifdef([gl_00GNULIB],
+       [[AC_DEFUN_ONCE(
+           [$1], [$2])]],
+       [[AC_DEFUN(
+           [$1], [$2])]])]))
+gl_iconv_AC_DEFUN([AM_ICONV],
+[
+  AM_ICONV_LINK
+  if test "$am_cv_func_iconv" = yes; then
+    AC_MSG_CHECKING([for iconv declaration])
+    AC_CACHE_VAL([am_cv_proto_iconv], [
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+           ]],
+           [[]])],
+        [am_cv_proto_iconv_arg1=""],
+        [am_cv_proto_iconv_arg1="const"])
+      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+    AC_MSG_RESULT([
+         $am_cv_proto_iconv])
+    AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+      [Define as const if the declaration of iconv() needs const.])
+    dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
+    m4_ifdef([gl_ICONV_H_DEFAULTS],
+      [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
+       if test -n "$am_cv_proto_iconv_arg1"; then
+         ICONV_CONST="const"
+       fi
+      ])
+  fi
+])
diff --git a/build/autoconf/la_uid_t.m4 b/build/autoconf/la_uid_t.m4
new file mode 100644
index 000000000000..31eef5e96fcb
--- /dev/null
+++ b/build/autoconf/la_uid_t.m4
@@ -0,0 +1,20 @@
+# la_TYPE_UID_T
+# -------------
+AC_DEFUN([la_TYPE_UID_T],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_CACHE_CHECK(for uid_t in sys/types.h, la_cv_type_uid_t,
+[AC_EGREP_HEADER(uid_t, sys/types.h,
+  la_cv_type_uid_t=yes, la_cv_type_uid_t=no)])
+if test $la_cv_type_uid_t = no; then
+  case $host in
+    *mingw*) def_uid_t=short ;;
+    *) def_uid_t=int ;;
+  esac
+  AC_DEFINE_UNQUOTED(uid_t, [$def_uid_t],
+	[Define to match typeof st_uid field of struct stat if <sys/types.h> doesn't define.])
+  AC_DEFINE_UNQUOTED(gid_t, [$def_uid_t],
+	[Define to match typeof st_gid field of struct stat if <sys/types.h> doesn't define.])
+fi
+])
+AU_ALIAS([AC_TYPE_UID_T], [la_TYPE_UID_T])
+
diff --git a/build/autoconf/lib-ld.m4 b/build/autoconf/lib-ld.m4
new file mode 100644
index 000000000000..ae003f7c5943
--- /dev/null
+++ b/build/autoconf/lib-ld.m4
@@ -0,0 +1,109 @@
+# lib-ld.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 1996-2003, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Subroutines of libtool.m4,
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
+
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  acl_cv_prog_gnu_ld=yes ;;
+*)
+  acl_cv_prog_gnu_ld=no ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-1.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+  # contains only /bin. Note that ksh looks also at the FPATH variable,
+  # so we have to set that as well for the test.
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+    && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+           || PATH_SEPARATOR=';'
+       }
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]* | [A-Za-z]:[\\/]*)]
+      [re_direlt='/[^/][^/]*/\.\./']
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL([acl_cv_path_LD],
+[if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      acl_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+      *GNU* | *'with BFD'*)
+        test "$with_gnu_ld" != no && break ;;
+      *)
+        test "$with_gnu_ld" != yes && break ;;
+      esac
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT([$LD])
+else
+  AC_MSG_RESULT([no])
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_LIB_PROG_LD_GNU
+])
diff --git a/build/autoconf/lib-link.m4 b/build/autoconf/lib-link.m4
new file mode 100644
index 000000000000..e7c9ba9d3d71
--- /dev/null
+++ b/build/autoconf/lib-link.m4
@@ -0,0 +1,777 @@
+# lib-link.m4 serial 26 (gettext-0.18.2)
+dnl Copyright (C) 2001-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ([2.54])
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+  pushdef([Name],[m4_translit([$1],[./+-], [____])])
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+    AC_LIB_LINKFLAGS_BODY([$1], [$2])
+    ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+    ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+    ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+    ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
+  ])
+  LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+  LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+  INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+  LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+  AC_SUBST([LIB]NAME)
+  AC_SUBST([LTLIB]NAME)
+  AC_SUBST([LIB]NAME[_PREFIX])
+  dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+  dnl results of this search when this library appears as a dependency.
+  HAVE_LIB[]NAME=yes
+  popdef([NAME])
+  popdef([Name])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. The missing-message
+dnl defaults to 'no' and may contain additional hints for the user.
+dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
+dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+  pushdef([Name],[m4_translit([$1],[./+-], [____])])
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+
+  dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+  dnl accordingly.
+  AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+  dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+  dnl because if the user has installed lib[]Name and not disabled its use
+  dnl via --without-lib[]Name-prefix, he wants to use it.
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+  AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+    ac_save_LIBS="$LIBS"
+    dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
+    dnl because these -l options might require -L options that are present in
+    dnl LIBS. -l options benefit only from the -L options listed before it.
+    dnl Otherwise, add it to the front of LIBS, because it may be a static
+    dnl library that depends on another static library that is present in LIBS.
+    dnl Static libraries benefit only from the static libraries listed after
+    dnl it.
+    case " $LIB[]NAME" in
+      *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
+      *)       LIBS="$LIB[]NAME $LIBS" ;;
+    esac
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM([[$3]], [[$4]])],
+      [ac_cv_lib[]Name=yes],
+      [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+    LIBS="$ac_save_LIBS"
+  ])
+  if test "$ac_cv_lib[]Name" = yes; then
+    HAVE_LIB[]NAME=yes
+    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
+    AC_MSG_CHECKING([how to link with lib[]$1])
+    AC_MSG_RESULT([$LIB[]NAME])
+  else
+    HAVE_LIB[]NAME=no
+    dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+    dnl $INC[]NAME either.
+    CPPFLAGS="$ac_save_CPPFLAGS"
+    LIB[]NAME=
+    LTLIB[]NAME=
+    LIB[]NAME[]_PREFIX=
+  fi
+  AC_SUBST([HAVE_LIB]NAME)
+  AC_SUBST([LIB]NAME)
+  AC_SUBST([LTLIB]NAME)
+  AC_SUBST([LIB]NAME[_PREFIX])
+  popdef([NAME])
+  popdef([Name])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl   acl_libext,
+dnl   acl_shlibext,
+dnl   acl_libname_spec,
+dnl   acl_library_names_spec,
+dnl   acl_hardcode_libdir_flag_spec,
+dnl   acl_hardcode_libdir_separator,
+dnl   acl_hardcode_direct,
+dnl   acl_hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+  dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+  m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+  AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS
+  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
+  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
+  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+  AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
+    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+    . ./conftest.sh
+    rm -f ./conftest.sh
+    acl_cv_rpath=done
+  ])
+  wl="$acl_cv_wl"
+  acl_libext="$acl_cv_libext"
+  acl_shlibext="$acl_cv_shlibext"
+  acl_libname_spec="$acl_cv_libname_spec"
+  acl_library_names_spec="$acl_cv_library_names_spec"
+  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+  acl_hardcode_direct="$acl_cv_hardcode_direct"
+  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+  dnl Determine whether the user wants rpath handling at all.
+  AC_ARG_ENABLE([rpath],
+    [  --disable-rpath         do not hardcode runtime library paths],
+    :, enable_rpath=yes)
+])
+
+dnl AC_LIB_FROMPACKAGE(name, package)
+dnl declares that libname comes from the given package. The configure file
+dnl will then not have a --with-libname-prefix option but a
+dnl --with-package-prefix option. Several libraries can come from the same
+dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
+dnl macro call that searches for libname.
+AC_DEFUN([AC_LIB_FROMPACKAGE],
+[
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  define([acl_frompackage_]NAME, [$2])
+  popdef([NAME])
+  pushdef([PACK],[$2])
+  pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+                                     [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  define([acl_libsinpackage_]PACKUP,
+    m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
+  popdef([PACKUP])
+  popdef([PACK])
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
+dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+  pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+                                   [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
+  pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+                                     [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+  pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
+  dnl Autoconf >= 2.61 supports dots in --with options.
+  pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
+  dnl By default, look in $includedir and $libdir.
+  use_additional=yes
+  AC_LIB_WITH_FINAL_PREFIX([
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+  ])
+  AC_ARG_WITH(P_A_C_K[-prefix],
+[[  --with-]]P_A_C_K[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
+  --without-]]P_A_C_K[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
+[
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+        AC_LIB_WITH_FINAL_PREFIX([
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+        ])
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+        if test "$acl_libdirstem2" != "$acl_libdirstem" \
+           && ! test -d "$withval/$acl_libdirstem"; then
+          additional_libdir="$withval/$acl_libdirstem2"
+        fi
+      fi
+    fi
+])
+  dnl Search the library and its dependencies in $additional_libdir and
+  dnl $LDFLAGS. Using breadth-first-seach.
+  LIB[]NAME=
+  LTLIB[]NAME=
+  INC[]NAME=
+  LIB[]NAME[]_PREFIX=
+  dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+  dnl computed. So it has to be reset here.
+  HAVE_LIB[]NAME=
+  rpathdirs=
+  ltrpathdirs=
+  names_already_handled=
+  names_next_round='$1 $2'
+  while test -n "$names_next_round"; do
+    names_this_round="$names_next_round"
+    names_next_round=
+    for name in $names_this_round; do
+      already_handled=
+      for n in $names_already_handled; do
+        if test "$n" = "$name"; then
+          already_handled=yes
+          break
+        fi
+      done
+      if test -z "$already_handled"; then
+        names_already_handled="$names_already_handled $name"
+        dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+        dnl or AC_LIB_HAVE_LINKFLAGS call.
+        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
+        eval value=\"\$HAVE_LIB$uppername\"
+        if test -n "$value"; then
+          if test "$value" = yes; then
+            eval value=\"\$LIB$uppername\"
+            test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
+            eval value=\"\$LTLIB$uppername\"
+            test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
+          else
+            dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+            dnl that this library doesn't exist. So just drop it.
+            :
+          fi
+        else
+          dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+          dnl and the already constructed $LIBNAME/$LTLIBNAME.
+          found_dir=
+          found_la=
+          found_so=
+          found_a=
+          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
+          if test -n "$acl_shlibext"; then
+            shrext=".$acl_shlibext"             # typically: shrext=.so
+          else
+            shrext=
+          fi
+          if test $use_additional = yes; then
+            dir="$additional_libdir"
+            dnl The same code as in the loop below:
+            dnl First look for a shared library.
+            if test -n "$acl_shlibext"; then
+              if test -f "$dir/$libname$shrext"; then
+                found_dir="$dir"
+                found_so="$dir/$libname$shrext"
+              else
+                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                  ver=`(cd "$dir" && \
+                        for f in "$libname$shrext".*; do echo "$f"; done \
+                        | sed -e "s,^$libname$shrext\\\\.,," \
+                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                        | sed 1q ) 2>/dev/null`
+                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                    found_dir="$dir"
+                    found_so="$dir/$libname$shrext.$ver"
+                  fi
+                else
+                  eval library_names=\"$acl_library_names_spec\"
+                  for f in $library_names; do
+                    if test -f "$dir/$f"; then
+                      found_dir="$dir"
+                      found_so="$dir/$f"
+                      break
+                    fi
+                  done
+                fi
+              fi
+            fi
+            dnl Then look for a static library.
+            if test "X$found_dir" = "X"; then
+              if test -f "$dir/$libname.$acl_libext"; then
+                found_dir="$dir"
+                found_a="$dir/$libname.$acl_libext"
+              fi
+            fi
+            if test "X$found_dir" != "X"; then
+              if test -f "$dir/$libname.la"; then
+                found_la="$dir/$libname.la"
+              fi
+            fi
+          fi
+          if test "X$found_dir" = "X"; then
+            for x in $LDFLAGS $LTLIB[]NAME; do
+              AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+              case "$x" in
+                -L*)
+                  dir=`echo "X$x" | sed -e 's/^X-L//'`
+                  dnl First look for a shared library.
+                  if test -n "$acl_shlibext"; then
+                    if test -f "$dir/$libname$shrext"; then
+                      found_dir="$dir"
+                      found_so="$dir/$libname$shrext"
+                    else
+                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                        ver=`(cd "$dir" && \
+                              for f in "$libname$shrext".*; do echo "$f"; done \
+                              | sed -e "s,^$libname$shrext\\\\.,," \
+                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                              | sed 1q ) 2>/dev/null`
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                          found_dir="$dir"
+                          found_so="$dir/$libname$shrext.$ver"
+                        fi
+                      else
+                        eval library_names=\"$acl_library_names_spec\"
+                        for f in $library_names; do
+                          if test -f "$dir/$f"; then
+                            found_dir="$dir"
+                            found_so="$dir/$f"
+                            break
+                          fi
+                        done
+                      fi
+                    fi
+                  fi
+                  dnl Then look for a static library.
+                  if test "X$found_dir" = "X"; then
+                    if test -f "$dir/$libname.$acl_libext"; then
+                      found_dir="$dir"
+                      found_a="$dir/$libname.$acl_libext"
+                    fi
+                  fi
+                  if test "X$found_dir" != "X"; then
+                    if test -f "$dir/$libname.la"; then
+                      found_la="$dir/$libname.la"
+                    fi
+                  fi
+                  ;;
+              esac
+              if test "X$found_dir" != "X"; then
+                break
+              fi
+            done
+          fi
+          if test "X$found_dir" != "X"; then
+            dnl Found the library.
+            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+            if test "X$found_so" != "X"; then
+              dnl Linking with a shared library. We attempt to hardcode its
+              dnl directory into the executable's runpath, unless it's the
+              dnl standard /usr/lib.
+              if test "$enable_rpath" = no \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+                dnl No hardcoding is needed.
+                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+              else
+                dnl Use an explicit option to hardcode DIR into the resulting
+                dnl binary.
+                dnl Potentially add DIR to ltrpathdirs.
+                dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+                haveit=
+                for x in $ltrpathdirs; do
+                  if test "X$x" = "X$found_dir"; then
+                    haveit=yes
+                    break
+                  fi
+                done
+                if test -z "$haveit"; then
+                  ltrpathdirs="$ltrpathdirs $found_dir"
+                fi
+                dnl The hardcoding into $LIBNAME is system dependent.
+                if test "$acl_hardcode_direct" = yes; then
+                  dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+                  dnl resulting binary.
+                  LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+                else
+                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+                    dnl Use an explicit option to hardcode DIR into the resulting
+                    dnl binary.
+                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+                    dnl Potentially add DIR to rpathdirs.
+                    dnl The rpathdirs will be appended to $LIBNAME at the end.
+                    haveit=
+                    for x in $rpathdirs; do
+                      if test "X$x" = "X$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      rpathdirs="$rpathdirs $found_dir"
+                    fi
+                  else
+                    dnl Rely on "-L$found_dir".
+                    dnl But don't add it if it's already contained in the LDFLAGS
+                    dnl or the already constructed $LIBNAME
+                    haveit=
+                    for x in $LDFLAGS $LIB[]NAME; do
+                      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                      if test "X$x" = "X-L$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+                    fi
+                    if test "$acl_hardcode_minus_L" != no; then
+                      dnl FIXME: Not sure whether we should use
+                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+                      dnl here.
+                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+                    else
+                      dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
+                      dnl here, because this doesn't fit in flags passed to the
+                      dnl compiler. So give up. No hardcoding. This affects only
+                      dnl very old systems.
+                      dnl FIXME: Not sure whether we should use
+                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+                      dnl here.
+                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+                    fi
+                  fi
+                fi
+              fi
+            else
+              if test "X$found_a" != "X"; then
+                dnl Linking with a static library.
+                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+              else
+                dnl We shouldn't come here, but anyway it's good to have a
+                dnl fallback.
+                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+              fi
+            fi
+            dnl Assume the include files are nearby.
+            additional_includedir=
+            case "$found_dir" in
+              */$acl_libdirstem | */$acl_libdirstem/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+                if test "$name" = '$1'; then
+                  LIB[]NAME[]_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+              */$acl_libdirstem2 | */$acl_libdirstem2/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+                if test "$name" = '$1'; then
+                  LIB[]NAME[]_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
+            esac
+            if test "X$additional_includedir" != "X"; then
+              dnl Potentially add $additional_includedir to $INCNAME.
+              dnl But don't add it
+              dnl   1. if it's the standard /usr/include,
+              dnl   2. if it's /usr/local/include and we are using GCC on Linux,
+              dnl   3. if it's already present in $CPPFLAGS or the already
+              dnl      constructed $INCNAME,
+              dnl   4. if it doesn't exist as a directory.
+              if test "X$additional_includedir" != "X/usr/include"; then
+                haveit=
+                if test "X$additional_includedir" = "X/usr/local/include"; then
+                  if test -n "$GCC"; then
+                    case $host_os in
+                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                    esac
+                  fi
+                fi
+                if test -z "$haveit"; then
+                  for x in $CPPFLAGS $INC[]NAME; do
+                    AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                    if test "X$x" = "X-I$additional_includedir"; then
+                      haveit=yes
+                      break
+                    fi
+                  done
+                  if test -z "$haveit"; then
+                    if test -d "$additional_includedir"; then
+                      dnl Really add $additional_includedir to $INCNAME.
+                      INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
+                    fi
+                  fi
+                fi
+              fi
+            fi
+            dnl Look for dependencies.
+            if test -n "$found_la"; then
+              dnl Read the .la file. It defines the variables
+              dnl dlname, library_names, old_library, dependency_libs, current,
+              dnl age, revision, installed, dlopen, dlpreopen, libdir.
+              save_libdir="$libdir"
+              case "$found_la" in
+                */* | *\\*) . "$found_la" ;;
+                *) . "./$found_la" ;;
+              esac
+              libdir="$save_libdir"
+              dnl We use only dependency_libs.
+              for dep in $dependency_libs; do
+                case "$dep" in
+                  -L*)
+                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+                    dnl But don't add it
+                    dnl   1. if it's the standard /usr/lib,
+                    dnl   2. if it's /usr/local/lib and we are using GCC on Linux,
+                    dnl   3. if it's already present in $LDFLAGS or the already
+                    dnl      constructed $LIBNAME,
+                    dnl   4. if it doesn't exist as a directory.
+                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
+                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                      haveit=
+                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                        if test -n "$GCC"; then
+                          case $host_os in
+                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+                          esac
+                        fi
+                      fi
+                      if test -z "$haveit"; then
+                        haveit=
+                        for x in $LDFLAGS $LIB[]NAME; do
+                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                            dnl Really add $additional_libdir to $LIBNAME.
+                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+                          fi
+                        fi
+                        haveit=
+                        for x in $LDFLAGS $LTLIB[]NAME; do
+                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                            dnl Really add $additional_libdir to $LTLIBNAME.
+                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+                          fi
+                        fi
+                      fi
+                    fi
+                    ;;
+                  -R*)
+                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
+                    if test "$enable_rpath" != no; then
+                      dnl Potentially add DIR to rpathdirs.
+                      dnl The rpathdirs will be appended to $LIBNAME at the end.
+                      haveit=
+                      for x in $rpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        rpathdirs="$rpathdirs $dir"
+                      fi
+                      dnl Potentially add DIR to ltrpathdirs.
+                      dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+                      haveit=
+                      for x in $ltrpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        ltrpathdirs="$ltrpathdirs $dir"
+                      fi
+                    fi
+                    ;;
+                  -l*)
+                    dnl Handle this in the next round.
+                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+                    ;;
+                  *.la)
+                    dnl Handle this in the next round. Throw away the .la's
+                    dnl directory; it is already contained in a preceding -L
+                    dnl option.
+                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+                    ;;
+                  *)
+                    dnl Most likely an immediate library name.
+                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+                    LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+                    ;;
+                esac
+              done
+            fi
+          else
+            dnl Didn't find the library; assume it is in the system directories
+            dnl known to the linker and runtime loader. (All the system
+            dnl directories known to the linker should also be known to the
+            dnl runtime loader, otherwise the system is severely misconfigured.)
+            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+          fi
+        fi
+      fi
+    done
+  done
+  if test "X$rpathdirs" != "X"; then
+    if test -n "$acl_hardcode_libdir_separator"; then
+      dnl Weird platform: only the last -rpath option counts, the user must
+      dnl pass all path elements in one option. We can arrange that for a
+      dnl single library, but not when more than one $LIBNAMEs are used.
+      alldirs=
+      for found_dir in $rpathdirs; do
+        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+      done
+      dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
+      acl_save_libdir="$libdir"
+      libdir="$alldirs"
+      eval flag=\"$acl_hardcode_libdir_flag_spec\"
+      libdir="$acl_save_libdir"
+      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+    else
+      dnl The -rpath options are cumulative.
+      for found_dir in $rpathdirs; do
+        acl_save_libdir="$libdir"
+        libdir="$found_dir"
+        eval flag=\"$acl_hardcode_libdir_flag_spec\"
+        libdir="$acl_save_libdir"
+        LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+      done
+    fi
+  fi
+  if test "X$ltrpathdirs" != "X"; then
+    dnl When using libtool, the option that works for both libraries and
+    dnl executables is -R. The -R options are cumulative.
+    for found_dir in $ltrpathdirs; do
+      LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+    done
+  fi
+  popdef([P_A_C_K])
+  popdef([PACKLIBS])
+  popdef([PACKUP])
+  popdef([PACK])
+  popdef([NAME])
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+  for element in [$2]; do
+    haveit=
+    for x in $[$1]; do
+      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+      if test "X$x" = "X$element"; then
+        haveit=yes
+        break
+      fi
+    done
+    if test -z "$haveit"; then
+      [$1]="${[$1]}${[$1]:+ }$element"
+    fi
+  done
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+  AC_REQUIRE([AC_LIB_RPATH])
+  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+  $1=
+  if test "$enable_rpath" != no; then
+    if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+      dnl Use an explicit option to hardcode directories into the resulting
+      dnl binary.
+      rpathdirs=
+      next=
+      for opt in $2; do
+        if test -n "$next"; then
+          dir="$next"
+          dnl No need to hardcode the standard /usr/lib.
+          if test "X$dir" != "X/usr/$acl_libdirstem" \
+             && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+            rpathdirs="$rpathdirs $dir"
+          fi
+          next=
+        else
+          case $opt in
+            -L) next=yes ;;
+            -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+                 dnl No need to hardcode the standard /usr/lib.
+                 if test "X$dir" != "X/usr/$acl_libdirstem" \
+                    && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+                   rpathdirs="$rpathdirs $dir"
+                 fi
+                 next= ;;
+            *) next= ;;
+          esac
+        fi
+      done
+      if test "X$rpathdirs" != "X"; then
+        if test -n ""$3""; then
+          dnl libtool is used for linking. Use -R options.
+          for dir in $rpathdirs; do
+            $1="${$1}${$1:+ }-R$dir"
+          done
+        else
+          dnl The linker is used for linking directly.
+          if test -n "$acl_hardcode_libdir_separator"; then
+            dnl Weird platform: only the last -rpath option counts, the user
+            dnl must pass all path elements in one option.
+            alldirs=
+            for dir in $rpathdirs; do
+              alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
+            done
+            acl_save_libdir="$libdir"
+            libdir="$alldirs"
+            eval flag=\"$acl_hardcode_libdir_flag_spec\"
+            libdir="$acl_save_libdir"
+            $1="$flag"
+          else
+            dnl The -rpath options are cumulative.
+            for dir in $rpathdirs; do
+              acl_save_libdir="$libdir"
+              libdir="$dir"
+              eval flag=\"$acl_hardcode_libdir_flag_spec\"
+              libdir="$acl_save_libdir"
+              $1="${$1}${$1:+ }$flag"
+            done
+          fi
+        fi
+      fi
+    fi
+  fi
+  AC_SUBST([$1])
+])
diff --git a/build/autoconf/lib-prefix.m4 b/build/autoconf/lib-prefix.m4
new file mode 100644
index 000000000000..7e5f0bde03d8
--- /dev/null
+++ b/build/autoconf/lib-prefix.m4
@@ -0,0 +1,224 @@
+# lib-prefix.m4 serial 7 (gettext-0.18)
+dnl Copyright (C) 2001-2005, 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+  AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  dnl By default, look in $includedir and $libdir.
+  use_additional=yes
+  AC_LIB_WITH_FINAL_PREFIX([
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+  ])
+  AC_LIB_ARG_WITH([lib-prefix],
+[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+  --without-lib-prefix    don't search for libraries in includedir and libdir],
+[
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+        AC_LIB_WITH_FINAL_PREFIX([
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+        ])
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/$acl_libdirstem"
+      fi
+    fi
+])
+  if test $use_additional = yes; then
+    dnl Potentially add $additional_includedir to $CPPFLAGS.
+    dnl But don't add it
+    dnl   1. if it's the standard /usr/include,
+    dnl   2. if it's already present in $CPPFLAGS,
+    dnl   3. if it's /usr/local/include and we are using GCC on Linux,
+    dnl   4. if it doesn't exist as a directory.
+    if test "X$additional_includedir" != "X/usr/include"; then
+      haveit=
+      for x in $CPPFLAGS; do
+        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+        if test "X$x" = "X-I$additional_includedir"; then
+          haveit=yes
+          break
+        fi
+      done
+      if test -z "$haveit"; then
+        if test "X$additional_includedir" = "X/usr/local/include"; then
+          if test -n "$GCC"; then
+            case $host_os in
+              linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+            esac
+          fi
+        fi
+        if test -z "$haveit"; then
+          if test -d "$additional_includedir"; then
+            dnl Really add $additional_includedir to $CPPFLAGS.
+            CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+          fi
+        fi
+      fi
+    fi
+    dnl Potentially add $additional_libdir to $LDFLAGS.
+    dnl But don't add it
+    dnl   1. if it's the standard /usr/lib,
+    dnl   2. if it's already present in $LDFLAGS,
+    dnl   3. if it's /usr/local/lib and we are using GCC on Linux,
+    dnl   4. if it doesn't exist as a directory.
+    if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+      haveit=
+      for x in $LDFLAGS; do
+        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+        if test "X$x" = "X-L$additional_libdir"; then
+          haveit=yes
+          break
+        fi
+      done
+      if test -z "$haveit"; then
+        if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
+          if test -n "$GCC"; then
+            case $host_os in
+              linux*) haveit=yes;;
+            esac
+          fi
+        fi
+        if test -z "$haveit"; then
+          if test -d "$additional_libdir"; then
+            dnl Really add $additional_libdir to $LDFLAGS.
+            LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+          fi
+        fi
+      fi
+    fi
+  fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+  dnl Unfortunately, prefix and exec_prefix get only finally determined
+  dnl at the end of configure.
+  if test "X$prefix" = "XNONE"; then
+    acl_final_prefix="$ac_default_prefix"
+  else
+    acl_final_prefix="$prefix"
+  fi
+  if test "X$exec_prefix" = "XNONE"; then
+    acl_final_exec_prefix='${prefix}'
+  else
+    acl_final_exec_prefix="$exec_prefix"
+  fi
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+  prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  $1
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates
+dnl - a variable acl_libdirstem, containing the basename of the libdir, either
+dnl   "lib" or "lib64" or "lib/64",
+dnl - a variable acl_libdirstem2, as a secondary possible value for
+dnl   acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
+dnl   "lib/amd64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+  dnl There is no formal standard regarding lib and lib64.
+  dnl On glibc systems, the current practice is that on a system supporting
+  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
+  dnl the compiler's default mode by looking at the compiler's library search
+  dnl path. If at least one of its elements ends in /lib64 or points to a
+  dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
+  dnl Otherwise we use the default, namely "lib".
+  dnl On Solaris systems, the current practice is that on a system supporting
+  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+  dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
+  dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  acl_libdirstem=lib
+  acl_libdirstem2=
+  case "$host_os" in
+    solaris*)
+      dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
+      dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+      dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
+      dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+      dnl symlink is missing, so we set acl_libdirstem2 too.
+      AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
+        [AC_EGREP_CPP([sixtyfour bits], [
+#ifdef _LP64
+sixtyfour bits
+#endif
+           ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
+        ])
+      if test $gl_cv_solaris_64bit = yes; then
+        acl_libdirstem=lib/64
+        case "$host_cpu" in
+          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
+          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+        esac
+      fi
+      ;;
+    *)
+      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+      if test -n "$searchpath"; then
+        acl_save_IFS="${IFS= 	}"; IFS=":"
+        for searchdir in $searchpath; do
+          if test -d "$searchdir"; then
+            case "$searchdir" in
+              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+              */../ | */.. )
+                # Better ignore directories of this form. They are misleading.
+                ;;
+              *) searchdir=`cd "$searchdir" && pwd`
+                 case "$searchdir" in
+                   */lib64 ) acl_libdirstem=lib64 ;;
+                 esac ;;
+            esac
+          fi
+        done
+        IFS="$acl_save_IFS"
+      fi
+      ;;
+  esac
+  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+])
diff --git a/build/autogen.sh b/build/autogen.sh
new file mode 100755
index 000000000000..e73162465d2a
--- /dev/null
+++ b/build/autogen.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+PATH=/usr/local/gnu-autotools/bin/:$PATH
+export PATH
+
+# Start from one level above the build directory
+if [ -f version ]; then
+    cd ..
+fi
+
+if [ \! -f build/version ]; then
+    echo "Can't find source directory"
+    exit 1
+fi
+
+# BSD make's "OBJDIR" support freaks out the automake-generated
+# Makefile.  Effectively disable it.
+export MAKEOBJDIRPREFIX=/junk
+
+# Start from the build directory, where the version file is located
+if [ -f build/version ]; then
+    cd build
+fi
+
+if [ \! -f version ]; then
+    echo "Can't find version file"
+    exit 1
+fi
+
+# Update the build number in the 'version' file.
+# Separate number from additional alpha/beta/etc marker
+MARKER=`cat version | sed 's/[0-9.]//g'`
+# Bump the number
+VN=`cat version | sed 's/[^0-9.]//g'`
+# Build out the string.
+VS="$(($VN/1000000)).$(( ($VN/1000)%1000 )).$(( $VN%1000 ))$MARKER"
+
+cd ..
+
+# Clean up the source dir as much as we can.
+/bin/sh build/clean.sh
+
+# Substitute the versions into Libarchive's archive.h and archive_entry.h
+perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive.h
+perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive_entry.h
+perl -p -i -e "s/^(#define\tARCHIVE_VERSION_STRING).*/\$1 \"libarchive $VS\"/" libarchive/archive.h
+# Substitute versions into configure.ac as well
+perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_S\]),.*\)/$1,['"$VS"'])/' configure.ac
+perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_N\]),.*\)/$1,['"$VN"'])/' configure.ac
+
+# Remove developer CFLAGS if a release build is being made
+if [ -n "${MAKE_LIBARCHIVE_RELEASE}" ]; then
+  perl -p -i -e "s/^(DEV_CFLAGS.*)/# \$1/" Makefile.am
+fi
+
+set -xe
+aclocal -I build/autoconf
+
+# Note: --automake flag needed only for libtoolize from
+# libtool 1.5.x; in libtool 2.2.x it is a synonym for --quiet
+case `uname` in
+Darwin) glibtoolize --automake -c;;
+*) libtoolize --automake -c;;
+esac
+autoconf
+autoheader
+automake -a -c
diff --git a/build/bump-version.sh b/build/bump-version.sh
new file mode 100755
index 000000000000..eec42354fd47
--- /dev/null
+++ b/build/bump-version.sh
@@ -0,0 +1,36 @@
+#!/bin/sh +v
+
+# Start from the build directory, where the version file is located
+if [ -f build/version ]; then
+    cd build
+fi
+
+if [ \! -f version ]; then
+    echo "Can't find version file"
+    exit 1
+fi
+
+# Update the build number in the 'version' file.
+# Separate number from additional alpha/beta/etc marker
+MARKER=`cat version | sed 's/[0-9.]//g'`
+# Bump the number
+VN=`cat version | sed 's/[^0-9.]//g'`
+# Reassemble and write back out
+VN=$(($VN + 1))
+rm -f version.old
+mv version version.old
+chmod +w version.old
+echo $VN$MARKER > version
+VS="$(($VN/1000000)).$(( ($VN/1000)%1000 )).$(( $VN%1000 ))$MARKER"
+cd ..
+
+ANNOUNCE=`date +"%b %d, %Y:"`" libarchive $VS released"
+
+echo $ANNOUNCE
+
+# Add a version notice to NEWS
+mv NEWS NEWS.bak
+chmod +w NEWS.bak
+echo $ANNOUNCE >> NEWS
+echo >> NEWS
+cat NEWS.bak >> NEWS
diff --git a/build/clean.sh b/build/clean.sh
new file mode 100755
index 000000000000..e4465f8a786c
--- /dev/null
+++ b/build/clean.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+#
+# Attempt to remove as many generated files as we can.
+# Ideally, a well-used development sandbox would look like
+# a pristine checkout after running this script.
+#
+
+if [ \! -f build/version ]; then
+    echo 'Must run the clean script from the top-level dir of the libarchive distribution' 1>&2
+    exit 1
+fi
+
+# If we're on BSD, blow away the build dir under /usr/obj
+rm -rf /usr/obj`pwd`
+
+#
+# Try to clean up a bit more...
+#
+
+find . -name '*.So' | xargs rm -f
+find . -name '*.a' | xargs rm -f
+find . -name '*.la' | xargs rm -f
+find . -name '*.lo' | xargs rm -f
+find . -name '*.o' | xargs rm -f
+find . -name '*.orig' | xargs rm -f
+find . -name '*.po' | xargs rm -f
+find . -name '*.rej' | xargs rm -f
+find . -name '*~' | xargs rm -f
+find . -name '.depend' | xargs rm -f
+find . -name '.deps' | xargs rm -rf
+find . -name '.dirstamp' | xargs rm -f
+find . -name '.libs' | xargs rm -rf
+find . -name 'CMakeFiles' | xargs rm -rf
+find . -name 'cmake_install.cmake' | xargs rm -f
+find . -name 'CTestTestfile.cmake' | xargs rm -f
+
+rm -rf Testing
+rm -rf autom4te.cache
+rm -rf bin
+rm -rf cmake.tmp
+rm -rf libarchive/Testing
+
+rm -f CMakeCache.txt
+rm -f DartConfiguration.tcl
+rm -f Makefile
+rm -f Makefile.in
+rm -f aclocal.m4
+rm -f bsdcpio
+rm -f bsdcpio_test
+rm -f bsdtar
+rm -f bsdtar_test
+rm -f build/autoconf/compile
+rm -f build/autoconf/config.guess
+rm -f build/autoconf/config.sub
+rm -f build/autoconf/depcomp
+rm -f build/autoconf/install-sh
+rm -f build/autoconf/libtool.m4
+rm -f build/autoconf/ltmain.sh
+rm -f build/autoconf/ltoptions.m4
+rm -f build/autoconf/ltsugar.m4
+rm -f build/autoconf/ltversion.m4
+rm -f build/autoconf/lt~obsolete.m4
+rm -f build/autoconf/missing
+rm -f build/pkgconfig/libarchive.pc
+rm -f build/version.old
+rm -f config.h
+rm -f config.h.in
+rm -f config.log
+rm -f config.status
+rm -f configure
+rm -f cpio/*.1.gz
+rm -f cpio/Makefile
+rm -f cpio/bsdcpio
+rm -f cpio/test/Makefile
+rm -f cpio/test/bsdcpio_test
+rm -f cpio/test/list.h
+rm -f doc/html/*
+rm -f doc/man/*
+rm -f doc/pdf/*
+rm -f doc/text/*
+rm -f doc/wiki/*
+rm -f libarchive/*.[35].gz
+rm -f libarchive/Makefile
+rm -f libarchive/libarchive.so*
+rm -f libarchive/test/Makefile
+rm -f libarchive/test/libarchive_test
+rm -f libarchive/test/list.h
+rm -f libarchive_test
+rm -f libtool
+rm -f stamp-h1
+rm -f tar/*.1.gz
+rm -f tar/Makefile
+rm -f tar/bsdtar
+rm -f tar/test/Makefile
+rm -f tar/test/bsdtar_test
+rm -f tar/test/list.h
diff --git a/build/cmake/CheckFileOffsetBits.c b/build/cmake/CheckFileOffsetBits.c
new file mode 100644
index 000000000000..d948fecf2b4e
--- /dev/null
+++ b/build/cmake/CheckFileOffsetBits.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+
+#define KB ((off_t)1024)
+#define MB ((off_t)1024 * KB)
+#define GB ((off_t)1024 * MB)
+#define TB ((off_t)1024 * GB)
+int t2[(((64 * GB -1) % 671088649) == 268434537)
+       && (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1];
+
+int main()
+{
+  ;
+  return 0;
+}
diff --git a/build/cmake/CheckFileOffsetBits.cmake b/build/cmake/CheckFileOffsetBits.cmake
new file mode 100644
index 000000000000..b347c9366e4a
--- /dev/null
+++ b/build/cmake/CheckFileOffsetBits.cmake
@@ -0,0 +1,44 @@
+# - Check if _FILE_OFFSET_BITS macro needed for large files
+# CHECK_FILE_OFFSET_BITS ()
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+# Copyright (c) 2009, Michihiro NAKAJIMA
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+#INCLUDE(CheckCXXSourceCompiles)
+
+GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits
+	 "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+MACRO (CHECK_FILE_OFFSET_BITS)
+  IF(NOT DEFINED _FILE_OFFSET_BITS)
+    MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files")
+    TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64
+      ${CMAKE_CURRENT_BINARY_DIR}
+      ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
+    IF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
+      TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64
+        ${CMAKE_CURRENT_BINARY_DIR}
+        ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
+        COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64)
+    ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
+
+    IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
+      SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
+      MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - needed")
+    ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
+      SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
+      MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - not needed")
+    ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
+  ENDIF(NOT DEFINED _FILE_OFFSET_BITS)
+
+ENDMACRO (CHECK_FILE_OFFSET_BITS)
+
diff --git a/build/cmake/CheckFuncs.cmake b/build/cmake/CheckFuncs.cmake
new file mode 100644
index 000000000000..0670df97f869
--- /dev/null
+++ b/build/cmake/CheckFuncs.cmake
@@ -0,0 +1,49 @@
+# Check if the system has the specified function; treat glibc "stub"
+# functions as nonexistent:
+# CHECK_FUNCTION_EXISTS_GLIBC (FUNCTION FUNCVAR)
+#
+#  FUNCTION - the function(s) where the prototype should be declared
+#  FUNCVAR - variable to define if the function does exist
+#
+# In particular, this understands the glibc convention of
+# defining macros __stub_XXXX or __stub___XXXX if the function
+# does appear in the library but is merely a stub that does nothing.
+# By detecting this case, we can select alternate behavior on
+# platforms that don't support this functionality.
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+# Copyright (c) 2009, Michihiro NAKAJIMA
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+INCLUDE(CheckFunctionExists)
+GET_FILENAME_COMPONENT(_selfdir_CheckFunctionExistsGlibc
+	 "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+MACRO (CHECK_FUNCTION_EXISTS_GLIBC _FUNC _FUNCVAR)
+   IF(NOT DEFINED ${_FUNCVAR})
+     SET(CHECK_STUB_FUNC_1 "__stub_${_FUNC}")
+     SET(CHECK_STUB_FUNC_2 "__stub___${_FUNC}")
+     CONFIGURE_FILE( ${_selfdir_CheckFunctionExistsGlibc}/CheckFuncs_stub.c.in
+       ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c IMMEDIATE)
+     TRY_COMPILE(__stub
+       ${CMAKE_CURRENT_BINARY_DIR}
+       ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c
+       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+       CMAKE_FLAGS
+       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
+       "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}")
+     IF (__stub)
+       SET("${_FUNCVAR}" "" CACHE INTERNAL "Have function ${_FUNC}")
+     ELSE (__stub)
+       CHECK_FUNCTION_EXISTS("${_FUNC}" "${_FUNCVAR}")
+     ENDIF (__stub)
+  ENDIF(NOT DEFINED ${_FUNCVAR})
+ENDMACRO (CHECK_FUNCTION_EXISTS_GLIBC)
+
diff --git a/build/cmake/CheckFuncs_stub.c.in b/build/cmake/CheckFuncs_stub.c.in
new file mode 100644
index 000000000000..50da414b5f51
--- /dev/null
+++ b/build/cmake/CheckFuncs_stub.c.in
@@ -0,0 +1,16 @@
+#ifdef __STDC__
+#include <limits.h>
+#else
+#include <assert.h>
+#endif
+
+int
+main()
+{
+#if defined ${CHECK_STUB_FUNC_1} || defined ${CHECK_STUB_FUNC_2}
+  return 0;
+#else
+this system have stub
+  return 0;
+#endif
+}
diff --git a/build/cmake/CheckHeaderDirent.cmake b/build/cmake/CheckHeaderDirent.cmake
new file mode 100644
index 000000000000..e9a7ea855326
--- /dev/null
+++ b/build/cmake/CheckHeaderDirent.cmake
@@ -0,0 +1,32 @@
+# - Check if the system has the specified type
+# CHECK_HEADER_DIRENT (HEADER1 HEARDER2 ...)
+#
+#  HEADER - the header(s) where the prototype should be declared
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+# Copyright (c) 2009, Michihiro NAKAJIMA
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckTypeExists)
+
+MACRO (CHECK_HEADER_DIRENT)
+  CHECK_TYPE_EXISTS("DIR *" dirent.h     HAVE_DIRENT_H)
+  IF(NOT HAVE_DIRENT_H)
+    CHECK_TYPE_EXISTS("DIR *" sys/ndir.h  HAVE_SYS_NDIR_H)
+    IF(NOT HAVE_SYS_NDIR_H)
+      CHECK_TYPE_EXISTS("DIR *" ndir.h      HAVE_NDIR_H)
+      IF(NOT HAVE_NDIR_H)
+        CHECK_TYPE_EXISTS("DIR *" sys/dir.h   HAVE_SYS_DIR_H)
+      ENDIF(NOT HAVE_NDIR_H)
+    ENDIF(NOT HAVE_SYS_NDIR_H)
+  ENDIF(NOT HAVE_DIRENT_H)
+ENDMACRO (CHECK_HEADER_DIRENT)
+
diff --git a/build/cmake/CheckStructMember.cmake b/build/cmake/CheckStructMember.cmake
new file mode 100644
index 000000000000..05ddb3a11f20
--- /dev/null
+++ b/build/cmake/CheckStructMember.cmake
@@ -0,0 +1,43 @@
+# - Check if the given struct or class has the specified member variable
+# CHECK_STRUCT_MEMBER (STRUCT MEMBER HEADER VARIABLE)
+#
+#  STRUCT - the name of the struct or class you are interested in
+#  MEMBER - the member which existence you want to check
+#  HEADER - the header(s) where the prototype should be declared
+#  VARIABLE - variable to store the result
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckCSourceCompiles)
+
+MACRO (CHECK_STRUCT_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
+   SET(_INCLUDE_FILES)
+   FOREACH (it ${_HEADER})
+      SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+   ENDFOREACH (it)
+
+   SET(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
+${_INCLUDE_FILES}
+int main()
+{
+   static ${_STRUCT} tmp;
+   if (sizeof(tmp.${_MEMBER}))
+      return 0;
+  return 0;
+}
+")
+   CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (CHECK_STRUCT_MEMBER)
+
diff --git a/build/cmake/CheckTypeExists.cmake b/build/cmake/CheckTypeExists.cmake
new file mode 100644
index 000000000000..b05234fd8753
--- /dev/null
+++ b/build/cmake/CheckTypeExists.cmake
@@ -0,0 +1,42 @@
+# - Check if the system has the specified type
+# CHECK_TYPE_EXISTS (TYPE HEADER VARIABLE)
+#
+#  TYPE - the name of the type or struct or class you are interested in
+#  HEADER - the header(s) where the prototype should be declared
+#  VARIABLE - variable to store the result
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+# Copyright (c) 2009, Michihiro NAKAJIMA
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckCSourceCompiles)
+
+MACRO (CHECK_TYPE_EXISTS _TYPE _HEADER _RESULT)
+   SET(_INCLUDE_FILES)
+   FOREACH (it ${_HEADER})
+      SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+   ENDFOREACH (it)
+
+   SET(_CHECK_TYPE_EXISTS_SOURCE_CODE "
+${_INCLUDE_FILES}
+int main()
+{
+   static ${_TYPE} tmp;
+   if (sizeof(tmp))
+      return 0;
+  return 0;
+}
+")
+   CHECK_C_SOURCE_COMPILES("${_CHECK_TYPE_EXISTS_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (CHECK_TYPE_EXISTS)
+
diff --git a/build/cmake/FindLZMA.cmake b/build/cmake/FindLZMA.cmake
new file mode 100644
index 000000000000..0b46b2cdd125
--- /dev/null
+++ b/build/cmake/FindLZMA.cmake
@@ -0,0 +1,48 @@
+# - Find lzma and lzmadec
+# Find the native LZMA includes and library
+#
+#  LZMA_INCLUDE_DIR    - where to find lzma.h, etc.
+#  LZMA_LIBRARIES      - List of libraries when using liblzma.
+#  LZMA_FOUND          - True if liblzma found.
+#  LZMADEC_INCLUDE_DIR - where to find lzmadec.h, etc.
+#  LZMADEC_LIBRARIES   - List of libraries when using liblzmadec.
+#  LZMADEC_FOUND       - True if liblzmadec found.
+
+IF (LZMA_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(LZMA_FIND_QUIETLY TRUE)
+ENDIF (LZMA_INCLUDE_DIR)
+
+FIND_PATH(LZMA_INCLUDE_DIR lzma.h)
+FIND_LIBRARY(LZMA_LIBRARY NAMES lzma liblzma)
+
+# handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZMA DEFAULT_MSG LZMA_LIBRARY LZMA_INCLUDE_DIR)
+
+IF(LZMA_FOUND)
+  SET( LZMA_LIBRARIES ${LZMA_LIBRARY} )
+ELSE(LZMA_FOUND)
+  SET( LZMA_LIBRARIES )
+
+  IF (LZMADEC_INCLUDE_DIR)
+    # Already in cache, be silent
+    SET(LZMADEC_FIND_QUIETLY TRUE)
+  ENDIF (LZMADEC_INCLUDE_DIR)
+
+  FIND_PATH(LZMADEC_INCLUDE_DIR lzmadec.h)
+  FIND_LIBRARY(LZMADEC_LIBRARY NAMES lzmadec )
+
+  # handle the QUIETLY and REQUIRED arguments and set LZMADEC_FOUND to TRUE if 
+  # all listed variables are TRUE
+  INCLUDE(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZMADEC DEFAULT_MSG LZMADEC_LIBRARY
+    LZMADEC_INCLUDE_DIR)
+
+  IF(LZMADEC_FOUND)
+    SET( LZMADEC_LIBRARIES ${LZMADEC_LIBRARY} )
+  ELSE(LZMADEC_FOUND)
+    SET( LZMADEC_LIBRARIES )
+  ENDIF(LZMADEC_FOUND)
+ENDIF(LZMA_FOUND)
diff --git a/build/cmake/FindLibGCC.cmake b/build/cmake/FindLibGCC.cmake
new file mode 100644
index 000000000000..5883ff802642
--- /dev/null
+++ b/build/cmake/FindLibGCC.cmake
@@ -0,0 +1,22 @@
+# - Find libgcc
+# Find the libgcc library.
+#
+#  LIBGCC_LIBRARIES      - List of libraries when using libgcc
+#  LIBGCC_FOUND          - True if libgcc found.
+
+IF (LIBGCC_LIBRARY)
+  # Already in cache, be silent
+  SET(LIBGCC_FIND_QUIETLY TRUE)
+ENDIF (LIBGCC_LIBRARY)
+
+FIND_LIBRARY(LIBGCC_LIBRARY NAMES gcc libgcc)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGCC_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGCC DEFAULT_MSG LIBGCC_LIBRARY)
+
+IF(LIBGCC_FOUND)
+  SET(LIBGCC_LIBRARIES ${LIBGCC_LIBRARY})
+  SET(HAVE_LIBGCC 1)
+ENDIF(LIBGCC_FOUND)
diff --git a/build/cmake/FindNettle.cmake b/build/cmake/FindNettle.cmake
new file mode 100644
index 000000000000..54ec9f5d39b5
--- /dev/null
+++ b/build/cmake/FindNettle.cmake
@@ -0,0 +1,23 @@
+# - Find Nettle
+# Find the Nettle include directory and library
+#
+#  NETTLE_INCLUDE_DIR    - where to find <nettle/sha.h>, etc.
+#  NETTLE_LIBRARIES      - List of libraries when using libnettle.
+#  NETTLE_FOUND          - True if libnettle found.
+
+IF (NETTLE_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(NETTLE_FIND_QUIETLY TRUE)
+ENDIF (NETTLE_INCLUDE_DIR)
+
+FIND_PATH(NETTLE_INCLUDE_DIR nettle/md5.h nettle/ripemd160.h nettle/sha.h)
+FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle libnettle)
+
+# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR)
+
+IF(NETTLE_FOUND)
+  SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
+ENDIF(NETTLE_FOUND)
diff --git a/build/cmake/FindPCREPOSIX.cmake b/build/cmake/FindPCREPOSIX.cmake
new file mode 100644
index 000000000000..56cc17eacb47
--- /dev/null
+++ b/build/cmake/FindPCREPOSIX.cmake
@@ -0,0 +1,34 @@
+# - Find pcreposix
+# Find the native PCRE and PCREPOSIX include and libraries
+#
+#  PCRE_INCLUDE_DIR    - where to find pcreposix.h, etc.
+#  PCREPOSIX_LIBRARIES - List of libraries when using libpcreposix.
+#  PCRE_LIBRARIES      - List of libraries when using libpcre.
+#  PCREPOSIX_FOUND     - True if libpcreposix found.
+#  PCRE_FOUND          - True if libpcre found.
+
+IF (PCRE_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(PCRE_FIND_QUIETLY TRUE)
+ENDIF (PCRE_INCLUDE_DIR)
+
+FIND_PATH(PCRE_INCLUDE_DIR pcreposix.h)
+FIND_LIBRARY(PCREPOSIX_LIBRARY NAMES pcreposix libpcreposix)
+FIND_LIBRARY(PCRE_LIBRARY NAMES pcre libpcre)
+
+# handle the QUIETLY and REQUIRED arguments and set PCREPOSIX_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCREPOSIX DEFAULT_MSG PCREPOSIX_LIBRARY PCRE_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY)
+
+IF(PCREPOSIX_FOUND)
+  SET(PCREPOSIX_LIBRARIES ${PCREPOSIX_LIBRARY})
+  SET(HAVE_LIBPCREPOSIX 1)
+  SET(HAVE_PCREPOSIX_H 1)
+ENDIF(PCREPOSIX_FOUND)
+
+IF(PCRE_FOUND)
+  SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
+  SET(HAVE_LIBPCRE 1)
+ENDIF(PCRE_FOUND)
diff --git a/build/cmake/LibarchiveCheckCSourceCompiles.cmake b/build/cmake/LibarchiveCheckCSourceCompiles.cmake
new file mode 100644
index 000000000000..6b6f59334da4
--- /dev/null
+++ b/build/cmake/LibarchiveCheckCSourceCompiles.cmake
@@ -0,0 +1,106 @@
+# - Check if given C source compiles and links into an executable
+# CHECK_C_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
+#  <code>       - source code to try to compile, must define 'main'
+#  <var>        - variable to store whether the source code compiled
+#  <fail-regex> - fail if test output matches this regex
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+#
+# Extra arguments added by libarchive
+# CMAKE_REQUIRED_LINKER_FLAGS = string of linker command line flags
+#
+
+include(CMakeExpandImportedTargets)
+
+
+macro(LIBARCHIVE_CHECK_C_SOURCE_COMPILES SOURCE VAR)
+  if("${VAR}" MATCHES "^${VAR}$")
+    set(_FAIL_REGEX)
+    set(_key)
+    foreach(arg ${ARGN})
+      if("${arg}" MATCHES "^(FAIL_REGEX)$")
+        set(_key "${arg}")
+      elseif(_key)
+        list(APPEND _${_key} "${arg}")
+      else()
+        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
+      endif()
+    endforeach()
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
+      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+    if(CMAKE_REQUIRED_LIBRARIES)
+      # this one translates potentially used imported library targets to their files on disk
+      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+      set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
+        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+    else()
+      set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+	if(CMAKE_REQUIRED_LINKER_FLAGS)
+	  set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS
+	    "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
+	else()
+	  set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS)
+	endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
+      "${SOURCE}\n")
+
+    message(STATUS "Performing Test ${VAR}")
+    try_compile(${VAR}
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} ${CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS}
+      "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
+      "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
+      OUTPUT_VARIABLE OUTPUT)
+
+    foreach(_regex ${_FAIL_REGEX})
+      if("${OUTPUT}" MATCHES "${_regex}")
+        set(${VAR} 0)
+      endif()
+    endforeach()
+
+    if(${VAR})
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      message(STATUS "Performing Test ${VAR} - Success")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${SOURCE}\n")
+    else()
+      message(STATUS "Performing Test ${VAR} - Failed")
+      set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${SOURCE}\n")
+    endif()
+  endif()
+endmacro()
+
diff --git a/build/cmake/LibarchiveCheckCSourceRuns.cmake b/build/cmake/LibarchiveCheckCSourceRuns.cmake
new file mode 100644
index 000000000000..498f52265aca
--- /dev/null
+++ b/build/cmake/LibarchiveCheckCSourceRuns.cmake
@@ -0,0 +1,102 @@
+# - Check if the given C source code compiles and runs.
+# CHECK_C_SOURCE_RUNS(<code> <var>)
+#  <code>   - source code to try to compile
+#  <var>    - variable to store the result
+#             (1 for success, empty for failure)
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+#
+# Extra arguments added by libarchive
+# CMAKE_REQUIRED_LINKER_FLAGS = string of linker command line flags
+#
+
+include(CMakeExpandImportedTargets)
+
+
+macro(LIBARCHIVE_CHECK_C_SOURCE_RUNS SOURCE VAR)
+  if("${VAR}" MATCHES "^${VAR}$")
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
+      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+    if(CMAKE_REQUIRED_LIBRARIES)
+      # this one translates potentially used imported library targets to their files on disk
+      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+      set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
+        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+    else()
+      set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+	if(CMAKE_REQUIRED_LINKER_FLAGS)
+	  set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS
+	    "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
+	else()
+	  set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS)
+	endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
+      "${SOURCE}\n")
+
+    message(STATUS "Performing Test ${VAR}")
+    try_run(${VAR}_EXITCODE ${VAR}_COMPILED
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} ${CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS}
+      -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
+      "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
+      "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
+      COMPILE_OUTPUT_VARIABLE OUTPUT)
+    # if it did not compile make the return value fail code of 1
+    if(NOT ${VAR}_COMPILED)
+      set(${VAR}_EXITCODE 1)
+    endif()
+    # if the return value was 0 then it worked
+    if("${${VAR}_EXITCODE}" EQUAL 0)
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      message(STATUS "Performing Test ${VAR} - Success")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
+        "${OUTPUT}\n"
+        "Return value: ${${VAR}}\n"
+        "Source file was:\n${SOURCE}\n")
+    else()
+      if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
+        set(${VAR} "${${VAR}_EXITCODE}")
+      else()
+        set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      endif()
+
+      message(STATUS "Performing Test ${VAR} - Failed")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
+        "${OUTPUT}\n"
+        "Return value: ${${VAR}_EXITCODE}\n"
+        "Source file was:\n${SOURCE}\n")
+
+    endif()
+  endif()
+endmacro()
+
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
new file mode 100644
index 000000000000..c04314ee5e32
--- /dev/null
+++ b/build/cmake/config.h.in
@@ -0,0 +1,1143 @@
+/* config.h.  Generated from build/cmake/config.h.in by cmake configure */
+
+/*
+ * Ensure we have C99-style int64_t, etc, all defined.
+ */
+
+/* First, we need to know if the system has already defined them. */
+#cmakedefine HAVE_INT16_T
+#cmakedefine HAVE_INT32_T
+#cmakedefine HAVE_INT64_T
+#cmakedefine HAVE_INTMAX_T
+
+#cmakedefine HAVE_UINT8_T
+#cmakedefine HAVE_UINT16_T
+#cmakedefine HAVE_UINT32_T
+#cmakedefine HAVE_UINT64_T
+#cmakedefine HAVE_UINTMAX_T
+
+/* We might have the types we want under other spellings. */
+#cmakedefine HAVE___INT64
+#cmakedefine HAVE_U_INT64_T
+#cmakedefine HAVE_UNSIGNED___INT64
+
+/* The sizes of various standard integer types. */
+@SIZE_OF_SHORT_CODE@
+@SIZE_OF_INT_CODE@
+@SIZE_OF_LONG_CODE@
+@SIZE_OF_LONG_LONG_CODE@
+@SIZE_OF_UNSIGNED_SHORT_CODE@
+@SIZE_OF_UNSIGNED_CODE@
+@SIZE_OF_UNSIGNED_LONG_CODE@
+@SIZE_OF_UNSIGNED_LONG_LONG_CODE@
+
+/*
+ * If we lack int64_t, define it to the first of __int64, int, long, and long long
+ * that exists and is the right size.
+ */
+#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
+typedef __int64 int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8
+typedef int int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8
+typedef long int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8
+typedef long long int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T)
+#error No 64-bit integer type was found.
+#endif
+
+/*
+ * Similarly for int32_t
+ */
+#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
+typedef long int32_t;
+#define HAVE_INT32_T
+#endif
+
+#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4
+typedef long int32_t;
+#define HAVE_INT32_T
+#endif
+
+#if !defined(HAVE_INT32_T)
+#error No 32-bit integer type was found.
+#endif
+
+/*
+ * Similarly for int16_t
+ */
+#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2
+typedef int int16_t;
+#define HAVE_INT16_T
+#endif
+
+#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2
+typedef short int16_t;
+#define HAVE_INT16_T
+#endif
+
+#if !defined(HAVE_INT16_T)
+#error No 16-bit integer type was found.
+#endif
+
+/*
+ * Similarly for uint64_t
+ */
+#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
+typedef unsigned __int64 uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8
+typedef unsigned uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8
+typedef unsigned long uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8
+typedef unsigned long long uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T)
+#error No 64-bit unsigned integer type was found.
+#endif
+
+
+/*
+ * Similarly for uint32_t
+ */
+#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4
+typedef unsigned uint32_t;
+#define HAVE_UINT32_T
+#endif
+
+#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4
+typedef unsigned long uint32_t;
+#define HAVE_UINT32_T
+#endif
+
+#if !defined(HAVE_UINT32_T)
+#error No 32-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint16_t
+ */
+#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2
+typedef unsigned uint16_t;
+#define HAVE_UINT16_T
+#endif
+
+#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2
+typedef unsigned short uint16_t;
+#define HAVE_UINT16_T
+#endif
+
+#if !defined(HAVE_UINT16_T)
+#error No 16-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint8_t
+ */
+#if !defined(HAVE_UINT8_T)
+typedef unsigned char uint8_t;
+#define HAVE_UINT8_T
+#endif
+
+#if !defined(HAVE_UINT16_T)
+#error No 8-bit unsigned integer type was found.
+#endif
+
+/* Define intmax_t and uintmax_t if they are not already defined. */
+#if !defined(HAVE_INTMAX_T)
+typedef int64_t intmax_t;
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#endif
+
+#if !defined(HAVE_UINTMAX_T)
+typedef uint64_t uintmax_t;
+#endif
+
+/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
+#cmakedefine ZLIB_WINAPI 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_OPENSSL 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_WIN 1
+
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_LIBC 1
+
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
+
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBC 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_OPENSSL 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_WIN 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC2 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC3 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_OPENSSL 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_WIN 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC2 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC3 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_OPENSSL 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_WIN 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC2 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC3 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_OPENSSL 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_WIN 1
+
+/* Version number of bsdcpio */
+#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
+
+/* Version number of bsdtar */
+#cmakedefine BSDTAR_VERSION_STRING "${BSDTAR_VERSION_STRING}"
+
+/* Define to 1 if you have the `acl_create_entry' function. */
+#cmakedefine HAVE_ACL_CREATE_ENTRY 1
+
+/* Define to 1 if you have the `acl_get_link' function. */
+#cmakedefine HAVE_ACL_GET_LINK 1
+
+/* Define to 1 if you have the `acl_get_link_np' function. */
+#cmakedefine HAVE_ACL_GET_LINK_NP 1
+
+/* Define to 1 if you have the `acl_get_perm' function. */
+#cmakedefine HAVE_ACL_GET_PERM 1
+
+/* Define to 1 if you have the `acl_get_perm_np' function. */
+#cmakedefine HAVE_ACL_GET_PERM_NP 1
+
+/* Define to 1 if you have the `acl_init' function. */
+#cmakedefine HAVE_ACL_INIT 1
+
+/* Define to 1 if you have the <acl/libacl.h> header file. */
+#cmakedefine HAVE_ACL_LIBACL_H 1
+
+/* Define to 1 if the system has the type `acl_permset_t'. */
+#cmakedefine HAVE_ACL_PERMSET_T 1
+
+/* Define to 1 if you have the `acl_set_fd' function. */
+#cmakedefine HAVE_ACL_SET_FD 1
+
+/* Define to 1 if you have the `acl_set_fd_np' function. */
+#cmakedefine HAVE_ACL_SET_FD_NP 1
+
+/* Define to 1 if you have the `acl_set_file' function. */
+#cmakedefine HAVE_ACL_SET_FILE 1
+
+/* True for systems with POSIX ACL support */
+#cmakedefine HAVE_ACL_USER 1
+
+/* Define to 1 if you have the <attr/xattr.h> header file. */
+#cmakedefine HAVE_ATTR_XATTR_H 1
+
+/* Define to 1 if you have the <bsdxml.h> header file. */
+#cmakedefine HAVE_BSDXML_H 1
+
+/* Define to 1 if you have the <bzlib.h> header file. */
+#cmakedefine HAVE_BZLIB_H 1
+
+/* Define to 1 if you have the `chflags' function. */
+#cmakedefine HAVE_CHFLAGS 1
+
+/* Define to 1 if you have the `chown' function. */
+#cmakedefine HAVE_CHOWN 1
+
+/* Define to 1 if you have the `chroot' function. */
+#cmakedefine HAVE_CHROOT 1
+
+/* Define to 1 if you have the <copyfile.h> header file. */
+#cmakedefine HAVE_COPYFILE_H 1
+
+/* Define to 1 if you have the `ctime_r' function. */
+#cmakedefine HAVE_CTIME_R 1
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#cmakedefine HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the `cygwin_conv_path' function. */
+#cmakedefine HAVE_CYGWIN_CONV_PATH 1
+
+/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_INT64_MAX 1
+
+/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_INT64_MIN 1
+
+/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_SIZE_MAX 1
+
+/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_SSIZE_MAX 1
+
+/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_STRERROR_R 1
+
+/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_UINT32_MAX 1
+
+/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you
+   don't. */
+#cmakedefine HAVE_DECL_UINT64_MAX 1
+
+/* Define to 1 if you have the <direct.h> header file. */
+#cmakedefine HAVE_DIRECT_H 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#cmakedefine HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the `dirfd' function. */
+#cmakedefine HAVE_DIRFD 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#cmakedefine HAVE_DOPRNT 1
+
+/* Define to 1 if nl_langinfo supports D_MD_ORDER */
+#cmakedefine HAVE_D_MD_ORDER 1
+
+/* A possible errno value for invalid file format errors */
+#cmakedefine HAVE_EFTYPE 1
+
+/* A possible errno value for invalid file format errors */
+#cmakedefine HAVE_EILSEQ 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#cmakedefine HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <expat.h> header file. */
+#cmakedefine HAVE_EXPAT_H 1
+
+/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
+#cmakedefine HAVE_EXT2FS_EXT2_FS_H 1
+
+/* Define to 1 if you have the `extattr_get_file' function. */
+#cmakedefine HAVE_EXTATTR_GET_FILE 1
+
+/* Define to 1 if you have the `extattr_list_file' function. */
+#cmakedefine HAVE_EXTATTR_LIST_FILE 1
+
+/* Define to 1 if you have the `extattr_set_fd' function. */
+#cmakedefine HAVE_EXTATTR_SET_FD 1
+
+/* Define to 1 if you have the `extattr_set_file' function. */
+#cmakedefine HAVE_EXTATTR_SET_FILE 1
+
+/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
+#cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1
+
+/* Define to 1 if you have the `fchdir' function. */
+#cmakedefine HAVE_FCHDIR 1
+
+/* Define to 1 if you have the `fchflags' function. */
+#cmakedefine HAVE_FCHFLAGS 1
+
+/* Define to 1 if you have the `fchmod' function. */
+#cmakedefine HAVE_FCHMOD 1
+
+/* Define to 1 if you have the `fchown' function. */
+#cmakedefine HAVE_FCHOWN 1
+
+/* Define to 1 if you have the `fcntl' function. */
+#cmakedefine HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#cmakedefine HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fdopendir' function. */
+#cmakedefine HAVE_FDOPENDIR 1
+
+/* Define to 1 if you have the `fgetea' function. */
+#cmakedefine HAVE_FGETEA 1
+
+/* Define to 1 if you have the `fgetxattr' function. */
+#cmakedefine HAVE_FGETXATTR 1
+
+/* Define to 1 if you have the `flistea' function. */
+#cmakedefine HAVE_FLISTEA 1
+
+/* Define to 1 if you have the `flistxattr' function. */
+#cmakedefine HAVE_FLISTXATTR 1
+
+/* Define to 1 if you have the `fork' function. */
+#cmakedefine HAVE_FORK 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#cmakedefine HAVE_FSEEKO 1
+
+/* Define to 1 if you have the `fsetea' function. */
+#cmakedefine HAVE_FSETEA 1
+
+/* Define to 1 if you have the `fsetxattr' function. */
+#cmakedefine HAVE_FSETXATTR 1
+
+/* Define to 1 if you have the `fstat' function. */
+#cmakedefine HAVE_FSTAT 1
+
+/* Define to 1 if you have the `fstatat' function. */
+#cmakedefine HAVE_FSTATAT 1
+
+/* Define to 1 if you have the `fstatfs' function. */
+#cmakedefine HAVE_FSTATFS 1
+
+/* Define to 1 if you have the `fstatvfs' function. */
+#cmakedefine HAVE_FSTATVFS 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#cmakedefine HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the `futimens' function. */
+#cmakedefine HAVE_FUTIMENS 1
+
+/* Define to 1 if you have the `futimes' function. */
+#cmakedefine HAVE_FUTIMES 1
+
+/* Define to 1 if you have the `futimesat' function. */
+#cmakedefine HAVE_FUTIMESAT 1
+
+/* Define to 1 if you have the `getea' function. */
+#cmakedefine HAVE_GETEA 1
+
+/* Define to 1 if you have the `geteuid' function. */
+#cmakedefine HAVE_GETEUID 1
+
+/* Define to 1 if you have the `getgrgid_r' function. */
+#cmakedefine HAVE_GETGRGID_R 1
+
+/* Define to 1 if you have the `getgrnam_r' function. */
+#cmakedefine HAVE_GETGRNAM_R 1
+
+/* Define to 1 if you have the `getpid' function. */
+#cmakedefine HAVE_GETPID 1
+
+/* Define to 1 if you have the `getpwnam_r' function. */
+#cmakedefine HAVE_GETPWNAM_R 1
+
+/* Define to 1 if you have the `getpwuid_r' function. */
+#cmakedefine HAVE_GETPWUID_R 1
+
+/* Define to 1 if you have the `getvfsbyname' function. */
+#cmakedefine HAVE_GETVFSBYNAME 1
+
+/* Define to 1 if you have the `getxattr' function. */
+#cmakedefine HAVE_GETXATTR 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#cmakedefine HAVE_GMTIME_R 1
+
+/* Define to 1 if you have the <grp.h> header file. */
+#cmakedefine HAVE_GRP_H 1
+
+/* Define to 1 if you have the `iconv' function. */
+#cmakedefine HAVE_ICONV 1
+
+/* Define to 1 if you have the <iconv.h> header file. */
+#cmakedefine HAVE_ICONV_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#cmakedefine HAVE_IO_H 1
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#cmakedefine HAVE_LANGINFO_H 1
+
+/* Define to 1 if you have the `lchflags' function. */
+#cmakedefine HAVE_LCHFLAGS 1
+
+/* Define to 1 if you have the `lchmod' function. */
+#cmakedefine HAVE_LCHMOD 1
+
+/* Define to 1 if you have the `lchown' function. */
+#cmakedefine HAVE_LCHOWN 1
+
+/* Define to 1 if you have the `lgetea' function. */
+#cmakedefine HAVE_LGETEA 1
+
+/* Define to 1 if you have the `lgetxattr' function. */
+#cmakedefine HAVE_LGETXATTR 1
+
+/* Define to 1 if you have the `acl' library (-lacl). */
+#cmakedefine HAVE_LIBACL 1
+
+/* Define to 1 if you have the `attr' library (-lattr). */
+#cmakedefine HAVE_LIBATTR 1
+
+/* Define to 1 if you have the `bsdxml' library (-lbsdxml). */
+#cmakedefine HAVE_LIBBSDXML 1
+
+/* Define to 1 if you have the `bz2' library (-lbz2). */
+#cmakedefine HAVE_LIBBZ2 1
+
+/* Define to 1 if you have the `expat' library (-lexpat). */
+#cmakedefine HAVE_LIBEXPAT 1
+
+/* Define to 1 if you have the `gcc' library (-lgcc). */
+#cmakedefine HAVE_LIBGCC 1
+
+/* Define to 1 if you have the `lzma' library (-llzma). */
+#cmakedefine HAVE_LIBLZMA 1
+
+/* Define to 1 if you have the `lzmadec' library (-llzmadec). */
+#cmakedefine HAVE_LIBLZMADEC 1
+
+/* Define to 1 if you have the `lzo2' library (-llzo2). */
+#cmakedefine HAVE_LIBLZO2 1
+
+/* Define to 1 if you have the `nettle' library (-lnettle). */
+#cmakedefine HAVE_LIBNETTLE 1
+
+/* Define to 1 if you have the `pcre' library (-lpcre). */
+#cmakedefine HAVE_LIBPCRE 1
+
+/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */
+#cmakedefine HAVE_LIBPCREPOSIX 1
+
+/* Define to 1 if you have the `xml2' library (-lxml2). */
+#cmakedefine HAVE_LIBXML2 1
+
+/* Define to 1 if you have the <libxml/xmlreader.h> header file. */
+#cmakedefine HAVE_LIBXML_XMLREADER_H 1
+
+/* Define to 1 if you have the <libxml/xmlwriter.h> header file. */
+#cmakedefine HAVE_LIBXML_XMLWRITER_H 1
+
+/* Define to 1 if you have the `z' library (-lz). */
+#cmakedefine HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#cmakedefine HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `link' function. */
+#cmakedefine HAVE_LINK 1
+
+/* Define to 1 if you have the <linux/fiemap.h> header file. */
+#cmakedefine HAVE_LINUX_FIEMAP_H 1
+
+/* Define to 1 if you have the <linux/fs.h> header file. */
+#cmakedefine HAVE_LINUX_FS_H 1
+
+/* Define to 1 if you have the <linux/magic.h> header file. */
+#cmakedefine HAVE_LINUX_MAGIC_H 1
+
+/* Define to 1 if you have the <linux/types.h> header file. */
+#cmakedefine HAVE_LINUX_TYPES_H 1
+
+/* Define to 1 if you have the `listea' function. */
+#cmakedefine HAVE_LISTEA 1
+
+/* Define to 1 if you have the `listxattr' function. */
+#cmakedefine HAVE_LISTXATTR 1
+
+/* Define to 1 if you have the `llistea' function. */
+#cmakedefine HAVE_LLISTEA 1
+
+/* Define to 1 if you have the `llistxattr' function. */
+#cmakedefine HAVE_LLISTXATTR 1
+
+/* Define to 1 if you have the <localcharset.h> header file. */
+#cmakedefine HAVE_LOCALCHARSET_H 1
+
+/* Define to 1 if you have the `locale_charset' function. */
+#cmakedefine HAVE_LOCALE_CHARSET 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#cmakedefine HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#cmakedefine HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the system has the type `long long int'. */
+#cmakedefine HAVE_LONG_LONG_INT 1
+
+/* Define to 1 if you have the `lsetea' function. */
+#cmakedefine HAVE_LSETEA 1
+
+/* Define to 1 if you have the `lsetxattr' function. */
+#cmakedefine HAVE_LSETXATTR 1
+
+/* Define to 1 if you have the `lstat' function. */
+#cmakedefine HAVE_LSTAT 1
+
+/* Define to 1 if `lstat' has the bug that it succeeds when given the
+   zero-length file name argument. */
+#cmakedefine HAVE_LSTAT_EMPTY_STRING_BUG 1
+
+/* Define to 1 if you have the `lutimes' function. */
+#cmakedefine HAVE_LUTIMES 1
+
+/* Define to 1 if you have the <lzmadec.h> header file. */
+#cmakedefine HAVE_LZMADEC_H 1
+
+/* Define to 1 if you have the <lzma.h> header file. */
+#cmakedefine HAVE_LZMA_H 1
+
+/* Define to 1 if you have the <lzo/lzo1x.h> header file. */
+#cmakedefine HAVE_LZO_LZO1X_H 1
+
+/* Define to 1 if you have the <lzo/lzoconf.h> header file. */
+#cmakedefine HAVE_LZO_LZOCONF_H 1
+
+/* Define to 1 if you have the `mbrtowc' function. */
+#cmakedefine HAVE_MBRTOWC 1
+
+/* Define to 1 if you have the `memmove' function. */
+#cmakedefine HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkdir' function. */
+#cmakedefine HAVE_MKDIR 1
+
+/* Define to 1 if you have the `mkfifo' function. */
+#cmakedefine HAVE_MKFIFO 1
+
+/* Define to 1 if you have the `mknod' function. */
+#cmakedefine HAVE_MKNOD 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#cmakedefine HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#cmakedefine HAVE_NDIR_H 1
+
+/* Define to 1 if you have the <nettle/md5.h> header file. */
+#cmakedefine HAVE_NETTLE_MD5_H 1
+
+/* Define to 1 if you have the <nettle/ripemd160.h> header file. */
+#cmakedefine HAVE_NETTLE_RIPEMD160_H 1
+
+/* Define to 1 if you have the <nettle/sha.h> header file. */
+#cmakedefine HAVE_NETTLE_SHA_H 1
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#cmakedefine HAVE_NL_LANGINFO 1
+
+/* Define to 1 if you have the `openat' function. */
+#cmakedefine HAVE_OPENAT 1
+
+/* Define to 1 if you have the <paths.h> header file. */
+#cmakedefine HAVE_PATHS_H 1
+
+/* Define to 1 if you have the <pcreposix.h> header file. */
+#cmakedefine HAVE_PCREPOSIX_H 1
+
+/* Define to 1 if you have the `pipe' function. */
+#cmakedefine HAVE_PIPE 1
+
+/* Define to 1 if you have the `poll' function. */
+#cmakedefine HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#cmakedefine HAVE_POLL_H 1
+
+/* Define to 1 if you have the `posix_spawnp' function. */
+#cmakedefine HAVE_POSIX_SPAWNP 1
+
+/* Define to 1 if you have the <process.h> header file. */
+#cmakedefine HAVE_PROCESS_H 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#cmakedefine HAVE_PWD_H 1
+
+/* Define to 1 if you have the `readdir_r' function. */
+#cmakedefine HAVE_READDIR_R 1
+
+/* Define to 1 if you have the `readlink' function. */
+#cmakedefine HAVE_READLINK 1
+
+/* Define to 1 if you have the `readlinkat' function. */
+#cmakedefine HAVE_READLINKAT 1
+
+/* Define to 1 if you have the <regex.h> header file. */
+#cmakedefine HAVE_REGEX_H 1
+
+/* Define to 1 if you have the `select' function. */
+#cmakedefine HAVE_SELECT 1
+
+/* Define to 1 if you have the `setenv' function. */
+#cmakedefine HAVE_SETENV 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#cmakedefine HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `sigaction' function. */
+#cmakedefine HAVE_SIGACTION 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#cmakedefine HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the <spawn.h> header file. */
+#cmakedefine HAVE_SPAWN_H 1
+
+/* Define to 1 if you have the `statfs' function. */
+#cmakedefine HAVE_STATFS 1
+
+/* Define to 1 if you have the `statvfs' function. */
+#cmakedefine HAVE_STATVFS 1
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+   zero-length file name argument. */
+#cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#cmakedefine HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#cmakedefine HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#cmakedefine HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#cmakedefine HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#cmakedefine HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `strftime' function. */
+#cmakedefine HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#cmakedefine HAVE_STRRCHR 1
+
+/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
+
+/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */
+#cmakedefine HAVE_STRUCT_STATVFS_F_IOSIZE 1
+
+/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+
+/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
+
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if `st_flags' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_FLAGS 1
+
+/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+
+/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_N 1
+
+/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_USEC 1
+
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
+
+/* Define to 1 if `st_umtime' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_UMTIME 1
+
+/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
+#cmakedefine HAVE_STRUCT_TM_TM_GMTOFF 1
+
+/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
+#cmakedefine HAVE_STRUCT_TM___TM_GMTOFF 1
+
+/* Define to 1 if you have the `symlink' function. */
+#cmakedefine HAVE_SYMLINK 1
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+#cmakedefine HAVE_SYS_ACL_H 1
+
+/* Define to 1 if you have the <sys/cdefs.h> header file. */
+#cmakedefine HAVE_SYS_CDEFS_H 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#cmakedefine HAVE_SYS_DIR_H 1
+
+/* Define to 1 if you have the <sys/ea.h> header file. */
+#cmakedefine HAVE_SYS_EA_H 1
+
+/* Define to 1 if you have the <sys/extattr.h> header file. */
+#cmakedefine HAVE_SYS_EXTATTR_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#cmakedefine HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/mkdev.h> header file. */
+#cmakedefine HAVE_SYS_MKDEV_H 1
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#cmakedefine HAVE_SYS_MOUNT_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#cmakedefine HAVE_SYS_NDIR_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#cmakedefine HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#cmakedefine HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#cmakedefine HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#cmakedefine HAVE_SYS_STATFS_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#cmakedefine HAVE_SYS_STATVFS_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+#cmakedefine HAVE_SYS_UTIME_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#cmakedefine HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#cmakedefine HAVE_SYS_VFS_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#cmakedefine HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <sys/xattr.h> header file. */
+#cmakedefine HAVE_SYS_XATTR_H 1
+
+/* Define to 1 if you have the `timegm' function. */
+#cmakedefine HAVE_TIMEGM 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#cmakedefine HAVE_TIME_H 1
+
+/* Define to 1 if you have the `tzset' function. */
+#cmakedefine HAVE_TZSET 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unsetenv' function. */
+#cmakedefine HAVE_UNSETENV 1
+
+/* Define to 1 if the system has the type `unsigned long long'. */
+#cmakedefine HAVE_UNSIGNED_LONG_LONG 1
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#cmakedefine HAVE_UNSIGNED_LONG_LONG_INT 1
+
+/* Define to 1 if you have the `utime' function. */
+#cmakedefine HAVE_UTIME 1
+
+/* Define to 1 if you have the `utimensat' function. */
+#cmakedefine HAVE_UTIMENSAT 1
+
+/* Define to 1 if you have the `utimes' function. */
+#cmakedefine HAVE_UTIMES 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#cmakedefine HAVE_UTIME_H 1
+
+/* Define to 1 if you have the `vfork' function. */
+#cmakedefine HAVE_VFORK 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#cmakedefine HAVE_VPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#cmakedefine HAVE_WCHAR_H 1
+
+/* Define to 1 if the system has the type `wchar_t'. */
+#cmakedefine HAVE_WCHAR_T 1
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#cmakedefine HAVE_WCRTOMB 1
+
+/* Define to 1 if you have the `wcscmp' function. */
+#cmakedefine HAVE_WCSCMP 1
+
+/* Define to 1 if you have the `wcscpy' function. */
+#cmakedefine HAVE_WCSCPY 1
+
+/* Define to 1 if you have the `wcslen' function. */
+#cmakedefine HAVE_WCSLEN 1
+
+/* Define to 1 if you have the `wctomb' function. */
+#cmakedefine HAVE_WCTOMB 1
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#cmakedefine HAVE_WCTYPE_H 1
+
+/* Define to 1 if you have the <wincrypt.h> header file. */
+#cmakedefine HAVE_WINCRYPT_H 1
+
+/* Define to 1 if you have the <windows.h> header file. */
+#cmakedefine HAVE_WINDOWS_H 1
+
+/* Define to 1 if you have the <winioctl.h> header file. */
+#cmakedefine HAVE_WINIOCTL_H 1
+
+/* Define to 1 if you have _CrtSetReportMode in <crtdbg.h>  */
+#cmakedefine HAVE__CrtSetReportMode 1
+
+/* Define to 1 if you have the `wmemcmp' function. */
+#cmakedefine HAVE_WMEMCMP 1
+
+/* Define to 1 if you have the `wmemcpy' function. */
+#cmakedefine HAVE_WMEMCPY 1
+
+/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
+#cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#cmakedefine HAVE_ZLIB_H 1
+
+/* Define to 1 if you have the `_ctime64_s' function. */
+#cmakedefine HAVE__CTIME64_S 1
+
+/* Define to 1 if you have the `_fseeki64' function. */
+#cmakedefine HAVE__FSEEKI64 1
+
+/* Define to 1 if you have the `_get_timezone' function. */
+#cmakedefine HAVE__GET_TIMEZONE 1
+
+/* Define to 1 if you have the `_localtime64_s' function. */
+#cmakedefine HAVE__LOCALTIME64_S 1
+
+/* Define to 1 if you have the `_mkgmtime64' function. */
+#cmakedefine HAVE__MKGMTIME64 1
+
+/* Define as const if the declaration of iconv() needs const. */
+#define ICONV_CONST ${ICONV_CONST}
+
+/* Version number of libarchive as a single integer */
+#cmakedefine LIBARCHIVE_VERSION_NUMBER "${LIBARCHIVE_VERSION_NUMBER}"
+
+/* Version number of libarchive */
+#cmakedefine LIBARCHIVE_VERSION_STRING "${LIBARCHIVE_VERSION_STRING}"
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+   slash. */
+#cmakedefine LSTAT_FOLLOWS_SLASHED_SYMLINK 1
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
+   */
+#cmakedefine MAJOR_IN_MKDEV 1
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in
+   <sysmacros.h>. */
+#cmakedefine MAJOR_IN_SYSMACROS 1
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#cmakedefine NO_MINUS_C_MINUS_O 1
+
+/* The size of `wchar_t', as computed by sizeof. */
+#cmakedefine SIZEOF_WCHAR_T ${SIZEOF_WCHAR_T}
+
+/* Define to 1 if strerror_r returns char *. */
+#cmakedefine STRERROR_R_CHAR_P 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#cmakedefine TIME_WITH_SYS_TIME 1
+
+/*
+ * Some platform requires a macro to use extension functions.
+ */
+#cmakedefine SAFE_TO_DEFINE_EXTENSIONS 1
+#ifdef SAFE_TO_DEFINE_EXTENSIONS
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+#endif /* SAFE_TO_DEFINE_EXTENSIONS */
+
+/* Version number of package */
+#cmakedefine VERSION "${VERSION}"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#cmakedefine _LARGEFILE_SOURCE 1
+
+/* Define for large files, on AIX-style hosts. */
+#cmakedefine _LARGE_FILES ${_LARGE_FILES}
+
+/* Define for Windows to use Windows 2000+ APIs. */
+#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#cmakedefine WINVER ${WINVER}
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#cmakedefine const ${const}
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#cmakedefine gid_t ${gid_t}
+
+/* Define to `unsigned long' if <sys/types.h> does not define. */
+#cmakedefine id_t ${id_t}
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine mode_t ${mode_t}
+
+/* Define to `long long' if <sys/types.h> does not define. */
+#cmakedefine off_t ${off_t}
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#cmakedefine pid_t ${pid_t}
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#cmakedefine size_t ${size_t}
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine ssize_t ${ssize_t}
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#cmakedefine uid_t ${uid_t}
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine intptr_t ${intptr_t}
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#cmakedefine uintptr_t ${uintptr_t}
diff --git a/build/makerelease.sh b/build/makerelease.sh
new file mode 100755
index 000000000000..f2869dfca5ed
--- /dev/null
+++ b/build/makerelease.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+#
+# This script exists primarily to document some of the
+# steps needed when building an "official libarchive distribution".
+# Feel free to hack it up as necessary to adjust to the peculiarities
+# of a particular build environment.
+#
+
+PATH=/usr/local/gnu-autotools/bin/:$PATH
+export PATH
+
+# Start from one level above the build directory
+if [ -f version ]; then
+    cd ..
+fi
+
+if [ \! -f build/version ]; then
+    echo "Can't find source directory"
+    exit 1
+fi
+
+# BSD make's "OBJDIR" support freaks out the automake-generated
+# Makefile.  Effectively disable it.
+export MAKEOBJDIRPREFIX=/junk
+
+set -ex
+
+#
+# Scrub the local tree before running the build tests below.
+#
+/bin/sh build/clean.sh
+
+#
+# Verify the CMake-generated build
+#
+mkdir -p _cmtest
+cd _cmtest
+cmake ..
+make
+make test
+cd ..
+rm -rf _cmtest
+# TODO: Build distribution using cmake
+
+#
+# Construct and verify the autoconf build system
+#
+export MAKE_LIBARCHIVE_RELEASE="1"
+/bin/sh build/autogen.sh
+
+# Get the newest config.guess/config.sub from savannah.gnu.org
+curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' > build/autoconf/config.guess
+curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' > build/autoconf/config.sub
+
+./configure
+make distcheck
+make dist-zip
diff --git a/build/pkgconfig/libarchive.pc.in b/build/pkgconfig/libarchive.pc.in
new file mode 100644
index 000000000000..95d715951774
--- /dev/null
+++ b/build/pkgconfig/libarchive.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libarchive
+Description: library that can create and read several streaming archive formats
+Version: @VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -larchive
+Libs.private: @LIBS@
diff --git a/build/utils/gen_archive_string_composition_h.sh b/build/utils/gen_archive_string_composition_h.sh
new file mode 100755
index 000000000000..925de5c85e78
--- /dev/null
+++ b/build/utils/gen_archive_string_composition_h.sh
@@ -0,0 +1,455 @@
+#!/bin/sh
+#
+# This needs http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
+#
+inputfile="$1"	# Expect UnicodeData.txt
+outfile=archive_string_composition.h
+pickout=/tmp/mk_unicode_composition_tbl$$.awk
+pickout2=/tmp/mk_unicode_composition_tbl2$$.awk
+#nfdtmp=/tmp/mk_unicode_decomposition_tmp$$.txt
+nfdtmp="nfdtmpx"
+#################################################################################
+#
+# Append the file header of "archive_string_composition.h"
+#
+#################################################################################
+append_copyright()
+{
+cat > ${outfile} <<CR_END
+/*-
+ * Copyright (c) 2011-2012 libarchive Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \$FreeBSD\$
+ *
+ */
+
+/*
+ * ATTENTION!
+ *  This file is generated by build/utils/gen_archive_string_composition_h.sh
+ *  from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
+ *
+ *  See also http://unicode.org/report/tr15/
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+
+struct unicode_composition_table {
+	uint32_t cp1;
+	uint32_t cp2;
+	uint32_t nfc;
+};
+
+CR_END
+}
+#################################################################################
+#
+# awk script
+#
+#################################################################################
+cat > ${pickout} <<AWK_END
+#
+BEGIN {
+  FS = ";"
+  min = "";
+  max = "";
+  cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'"
+  nfdtbl="${nfdtmp}"
+  print "static const struct unicode_composition_table u_composition_table[] = {"
+}
+END {
+  close(cmd)
+  print "};"
+  print ""
+  #
+  # Output Canonical Combining Class tables used for translating NFD to NFC.
+  #
+  printf "#define CANONICAL_CLASS_MIN\\t0x%s\\n", min
+  printf "#define CANONICAL_CLASS_MAX\\t0x%s\\n", max
+  print ""
+  printf "#define IS_DECOMPOSABLE_BLOCK(uc)\\t\\\\\n"
+  printf "\\t(((uc)>>8) <= 0x%X && u_decomposable_blocks[(uc)>>8])\\n", highnum
+  printf "static const char u_decomposable_blocks[0x%X+1] = {\\n\\t", highnum
+  #
+  # Output blockmap
+  for (i = 0; i <= highnum; i++) {
+    if (i != 0 && i % 32 == 0)
+      printf "\\n\\t"
+    # Additionally Hangul[11XX(17), AC00(172) - D7FF(215)] is decomposable.
+    if (blockmap[i] || i == 17 || (i >= 172 && i <= 215))
+        printf "1,"
+    else
+        printf "0,"
+  }
+  printf "\\n};\\n\\n"
+  #
+  # Output a macro to get a canonical combining class.
+  #
+  print "/* Get Canonical Combining Class(CCC). */"
+  printf "#define CCC(uc)\\t\\\\\n"
+  printf "\\t(((uc) > 0x%s)?0:\\\\\\n", max
+  printf "\\tccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])\\n"
+  print ""
+  #
+  # Output a canonical combining class value table.
+  #
+  midcnt = 0
+  printf "/* The table of the value of Canonical Cimbining Class */\\n"
+  print "static const unsigned char ccc_val[][16] = {"
+  print " /* idx=0: XXXX0 - XXXXF */"
+  print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
+  for (h = 0; h <= highnum; h++) {
+    if (!blockmap[h])
+      continue;
+    for (m = 0; m < 16; m++) {
+      if (!xx_blockmap[h, m])
+        continue;
+      midcnt++
+      printf " /* idx=%d: %03X%1X0 - %03X%1XF */\\n {", midcnt, h, m, h, m
+      for (l = 0; l < 15; l++) {
+        printf "%d, ", xxx_blockmap[h, m, l]
+      }
+      printf "%d },\n", xxx_blockmap[h, m, 15]
+    }
+  }
+  printf "};\n"
+  #
+  # Output the index table of the canonical combining class value table.
+  #
+  cnt = 0
+  midcnt = 0
+  printf "\\n/* The index table to ccc_val[*][16] */\\n"
+  print "static const unsigned char ccc_val_index[][16] = {"
+  print " /* idx=0: XXX00 - XXXFF */"
+  print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
+  for (h = 0; h <= highnum; h++) {
+    if (!blockmap[h])
+      continue;
+    cnt++
+    printf " /* idx=%d: %03X00 - %03XFF */\\n {", cnt, h, h
+    for (m = 0; m < 16; m++) {
+      if (m != 0)
+          printf ","
+      if (xx_blockmap[h, m]) {
+          midcnt++
+          printf "%2d", midcnt
+      } else
+          printf " 0"
+    }
+    printf " },\\n"
+  }
+  printf "};\\n"
+  #
+  # Output the index table to the index table of the canonical combining
+  # class value table.
+  #
+  printf "\\n/* The index table to ccc_val_index[*][16] */\\n"
+  printf "static const unsigned char ccc_index[] = {\\n ", h
+  cnt = 0
+  for (h = 0; h <= highnum; h++) {
+    if (h != 0 && h % 24 == 0)
+      printf "\\n "
+    if (blockmap[h]) {
+      cnt++;
+      printf "%2d,", cnt
+    } else
+      printf " 0,"
+  }
+  print "};"
+  print ""
+}
+#
+#
+function hextoi(hex)
+{
+  dec = 0
+  for (i=0; i < length(hex); i++) {
+    x = substr(hex, i+1, 1)
+    if (x ~/[0-9]/)
+	dec = dec * 16 + x;
+    else if (x == "A")
+	dec = dec * 16 + 10;
+    else if (x == "B")
+	dec = dec * 16 + 11;
+    else if (x == "C")
+	dec = dec * 16 + 12;
+    else if (x == "D")
+	dec = dec * 16 + 13;
+    else if (x == "E")
+	dec = dec * 16 + 14;
+    else if (x == "F")
+	dec = dec * 16 + 15;
+  }
+  return dec
+}
+#
+# Collect Canonical Combining Class values.
+#
+\$4 ~/^[0-9A-F]+$/ {
+  if (\$4 !~/^0$/) {
+    if (min == "") {
+      min = \$1
+    }
+    max = \$1
+    high = substr(\$1, 1, length(\$1) -2)
+    highnum = hextoi(high)
+    mid = substr(\$1, length(\$1) -1, 1)
+    midnum = hextoi(mid)
+    low = substr(\$1, length(\$1), 1)
+    lownum = hextoi(low)
+    blockmap[highnum] = 1
+    xx_blockmap[highnum, midnum] = 1
+    xxx_blockmap[highnum, midnum, lownum] = \$4
+  }
+}
+#
+# Following code points are not decomposed in MAC OS.
+#   U+2000  - U+2FFF
+#   U+F900  - U+FAFF
+#   U+2F800 - U+2FAFF
+#
+#\$1 ~/^2[0-9A-F][0-9A-F][0-9A-F]\$/ {
+#        next
+#}
+#\$1 ~/^F[9A][0-9A-F][0-9A-F]\$/ {
+#        next
+#}
+#\$1 ~/^2F[89A][0-9A-F][0-9A-F]\$/ {
+#        next
+#}
+#
+# Exclusion code points specified by  
+# http://unicode.org/Public/6.0.0/ucd/CompositionExclusions.txt
+##
+# 1. Script Specifices
+##
+\$1 ~/^095[89ABCDEF]\$/ {
+    next
+}
+\$1 ~/^09D[CDF]\$/ {
+    next
+}
+\$1 ~/^0A3[36]\$/ {
+    next
+}
+\$1 ~/^0A5[9ABE]\$/ {
+    next
+}
+\$1 ~/^0B5[CD]\$/ {
+    next
+}
+\$1 ~/^0F4[3D]\$/ {
+    next
+}
+\$1 ~/^0F5[27C]\$/ {
+    next
+}
+\$1 ~/^0F69\$/ {
+    next
+}
+\$1 ~/^0F7[68]\$/ {
+    next
+}
+\$1 ~/^0F9[3D]\$/ {
+    next
+}
+\$1 ~/^0FA[27C]\$/ {
+    next
+}
+\$1 ~/^0FB9\$/ {
+    next
+}
+\$1 ~/^FB1[DF]\$/ {
+    next
+}
+\$1 ~/^FB2[ABCDEF]\$/ {
+    next
+}
+\$1 ~/^FB3[012345689ABCE]\$/ {
+    next
+}
+\$1 ~/^FB4[01346789ABCDE]\$/ {
+    next
+}
+##
+# 2. Post Composition Version precomposed characters
+##
+\$1 ~/^2ADC\$/ {
+    next
+}
+\$1 ~/^1D15[EF]\$/ {
+    next
+}
+\$1 ~/^1D16[01234]\$/ {
+    next
+}
+\$1 ~/^1D1B[BCDEF]\$/ {
+    next
+}
+\$1 ~/^1D1C0\$/ {
+    next
+}
+##
+# 3. Singleton Decompositions
+##
+\$1 ~/^034[01]\$/ {
+    next
+}
+\$1 ~/^037[4E]\$/ {
+    next
+}
+\$1 ~/^0387\$/ {
+    next
+}
+\$1 ~/^1F7[13579BD]\$/ {
+    next
+}
+\$1 ~/^1FB[BE]\$/ {
+    next
+}
+\$1 ~/^1FC[9B]\$/ {
+    next
+}
+\$1 ~/^1FD[3B]\$/ {
+    next
+}
+\$1 ~/^1FE[3BEF]\$/ {
+    next
+}
+\$1 ~/^1FF[9BD]\$/ {
+    next
+}
+\$1 ~/^200[01]\$/ {
+    next
+}
+\$1 ~/^212[6AB]\$/ {
+    next
+}
+\$1 ~/^232[9A]\$/ {
+    next
+}
+\$1 ~/^F9[0-9A-F][0-9A-F]\$/ {
+    next
+}
+\$1 ~/^FA0[0-9A-D]\$/ {
+    next
+}
+\$1 ~/^FA1[025-9A-E]\$/ {
+    next
+}
+\$1 ~/^FA2[0256A-D]\$/ {
+    next
+}
+\$1 ~/^FA[3-5][0-9A-F]\$/ {
+    next
+}
+\$1 ~/^FA6[0-9A-D]\$/ {
+    next
+}
+\$1 ~/^FA[7-9A-C][0-9A-F]\$/ {
+    next
+}
+\$1 ~/^FAD[0-9]\$/ {
+    next
+}
+\$1 ~/^2F[89][0-9A-F][0-9A-F]\$/ {
+    next
+}
+\$1 ~/^2FA0[0-9A-F]\$/ {
+    next
+}
+\$1 ~/^2FA1[0-9A-D]\$/ {
+    next
+}
+##
+# 4. Non-Starter Decompositions
+##
+\$1 ~/^0344\$/ {
+    next
+}
+\$1 ~/^0F7[35]\$/ {
+    next
+}
+\$1 ~/^0F81\$/ {
+    next
+}
+#
+# Output combinations for NFD ==> NFC.
+#
+\$6 ~/^[0-9A-F]+ [0-9A-F]+\$/ {
+    split(\$6, cp, " ")
+    if (length(\$1) == 4)
+        print "0"cp[1], "0"cp[2], "0"\$1 | cmd
+    else
+        print cp[1], cp[2], \$1 | cmd
+    # NFC ==> NFD table.
+    if (length(\$1) == 4)
+        print "0"\$1, "0"cp[1], "0"cp[2] >>nfdtbl
+    else
+        print \$1, cp[1], cp[2] >>nfdtbl
+}
+AWK_END
+#################################################################################
+# awk script
+#
+#################################################################################
+cat > ${pickout2} <<AWK_END
+#
+BEGIN {
+  FS = " "
+  print "struct unicode_decomposition_table {"
+  print "\tuint32_t nfc;"
+  print "\tuint32_t cp1;"
+  print "\tuint32_t cp2;"
+  print "};"
+  print ""
+  print "static const struct unicode_decomposition_table u_decomposition_table[] = {"
+}
+END {
+  print "};"
+  print ""
+}
+{
+printf "\t{ 0x%s , 0x%s , 0x%s },\n", \$1, \$2, \$3;
+}
+AWK_END
+#################################################################################
+#
+# Run awk a script.
+#
+#################################################################################
+append_copyright
+awk -f ${pickout} ${inputfile} >> ${outfile}
+awk -f ${pickout2} ${nfdtmp} >> ${outfile}
+echo "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */" >> ${outfile}
+echo "" >> ${outfile}
+#
+# Remove awk the script.
+rm ${pickout}
+rm ${pickout2}
+rm ${nfdtmp}
diff --git a/build/version b/build/version
new file mode 100644
index 000000000000..937b126a2ede
--- /dev/null
+++ b/build/version
@@ -0,0 +1 @@
+3001002
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 000000000000..73944d3e0754
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,788 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl First, define all of the version numbers up front.
+dnl In particular, this allows the version macro to be used in AC_INIT
+
+dnl These first two version numbers are updated automatically on each release.
+m4_define([LIBARCHIVE_VERSION_S],[3.1.2])
+m4_define([LIBARCHIVE_VERSION_N],[3001002])
+
+dnl bsdtar and bsdcpio versioning tracks libarchive
+m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
+m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S())
+
+AC_PREREQ(2.65)
+
+#
+# Now starts the "real" configure script.
+#
+
+AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[libarchive-discuss@googlegroups.com])
+# Make sure the srcdir contains "libarchive" directory
+AC_CONFIG_SRCDIR([libarchive])
+# Use auxiliary subscripts from this subdirectory (cleans up root)
+AC_CONFIG_AUX_DIR([build/autoconf])
+# M4 scripts
+AC_CONFIG_MACRO_DIR([build/autoconf])
+# Must follow AC_CONFIG macros above...
+AM_INIT_AUTOMAKE()
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# Libtool's "interface version" can be computed from the libarchive version.
+
+# Libtool interface version bumps on any API change, so increments
+# whenever libarchive minor version does.
+ARCHIVE_MINOR=$(( (LIBARCHIVE_VERSION_N() / 1000) % 1000 ))
+# Libarchive 2.7 == libtool interface 9 = 2 + 7
+# Libarchive 2.8 == libtool interface 10 = 2 + 8
+# Libarchive 2.9 == libtool interface 11 = 2 + 8
+# Libarchive 3.0 == libtool interface 12
+# Libarchive 3.1 == libtool interface 13
+ARCHIVE_INTERFACE=`echo $((13 + ${ARCHIVE_MINOR}))`
+# Libarchive revision is bumped on any source change === libtool revision
+ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 ))
+# Libarchive minor is bumped on any interface addition === libtool age
+ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR
+
+# Stick the version numbers into config.h
+AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()",
+	[Version number of libarchive])
+AC_DEFINE_UNQUOTED([LIBARCHIVE_VERSION_NUMBER],"LIBARCHIVE_VERSION_N()",
+	[Version number of libarchive as a single integer])
+AC_DEFINE([BSDCPIO_VERSION_STRING],"BSDCPIO_VERSION_S()",
+	[Version number of bsdcpio])
+AC_DEFINE([BSDTAR_VERSION_STRING],"BSDTAR_VERSION_S()",
+	[Version number of bsdtar])
+
+# The shell variables here must be the same as the AC_SUBST() variables
+# below, but the shell variable names apparently cannot be the same as
+# the m4 macro names above.  Why?  Ask autoconf.
+BSDCPIO_VERSION_STRING=BSDCPIO_VERSION_S()
+BSDTAR_VERSION_STRING=BSDTAR_VERSION_S()
+LIBARCHIVE_VERSION_STRING=LIBARCHIVE_VERSION_S()
+LIBARCHIVE_VERSION_NUMBER=LIBARCHIVE_VERSION_N()
+
+# Substitute the above version numbers into the various files below.
+# Yes, I believe this is the fourth time we define what are essentially
+# the same symbols.  Why? Ask autoconf.
+AC_SUBST(ARCHIVE_LIBTOOL_VERSION)
+AC_SUBST(BSDCPIO_VERSION_STRING)
+AC_SUBST(BSDTAR_VERSION_STRING)
+AC_SUBST(LIBARCHIVE_VERSION_STRING)
+AC_SUBST(LIBARCHIVE_VERSION_NUMBER)
+
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([build/pkgconfig/libarchive.pc])
+
+# Check for host type
+AC_CANONICAL_HOST
+
+dnl Compilation on mingw and Cygwin needs special Makefile rules
+inc_windows_files=no
+inc_cygwin_files=no
+case "$host_os" in
+  *mingw* ) inc_windows_files=yes ;;
+  *cygwin*) inc_cygwin_files=yes ;;
+esac
+AM_CONDITIONAL([INC_WINDOWS_FILES], [test $inc_windows_files = yes])
+AM_CONDITIONAL([INC_CYGWIN_FILES], [test $inc_cygwin_files = yes])
+
+dnl Defines that are required for specific platforms (e.g. -D_POSIX_SOURCE, etc)
+PLATFORMCPPFLAGS=
+case "$host_os" in
+  *mingw* ) PLATFORMCPPFLAGS=-D__USE_MINGW_ANSI_STDIO ;;
+esac
+AC_SUBST(PLATFORMCPPFLAGS)
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_USE_SYSTEM_EXTENSIONS
+AC_LIBTOOL_WIN32_DLL
+AC_PROG_LIBTOOL
+AC_CHECK_TOOL([STRIP],[strip])
+
+#
+# Options for building bsdtar.
+#
+# Default is to build bsdtar, but allow people to override that.
+#
+AC_ARG_ENABLE([bsdtar],
+	[AS_HELP_STRING([--enable-bsdtar], [enable build of bsdtar (default)])
+	AS_HELP_STRING([--enable-bsdtar=static], [force static build of bsdtar])
+	AS_HELP_STRING([--enable-bsdtar=shared], [force dynamic build of bsdtar])
+AS_HELP_STRING([--disable-bsdtar], [disable build of bsdtar])],
+	[], [enable_bsdtar=yes])
+
+case "$enable_bsdtar" in
+yes)
+	if test "$enable_static" = "no"; then
+		static_bsdtar=no
+	else
+		static_bsdtar=yes
+	fi
+	build_bsdtar=yes
+	;;
+dynamic|shared)
+	if test "$enable_shared" = "no"; then
+		AC_MSG_FAILURE([Shared linking of bsdtar requires shared libarchive])
+	fi
+	build_bsdtar=yes
+	static_bsdtar=no
+	;;
+static)
+	build_bsdtar=yes
+	static_bsdtar=yes
+	;;
+no)
+	build_bsdtar=no
+	static_bsdtar=no
+	;;
+*)
+	AC_MSG_FAILURE([Unsupported value for --enable-bsdtar])
+	;;
+esac
+
+AM_CONDITIONAL([BUILD_BSDTAR], [ test "$build_bsdtar" = yes ])
+AM_CONDITIONAL([STATIC_BSDTAR], [ test "$static_bsdtar" = yes ])
+
+#
+# Options for building bsdcpio.
+#
+# Default is not to build bsdcpio, but that can be overridden.
+#
+AC_ARG_ENABLE([bsdcpio],
+	[AS_HELP_STRING([--enable-bsdcpio], [enable build of bsdcpio (default)])
+	AS_HELP_STRING([--enable-bsdcpio=static], [static build of bsdcpio])
+	AS_HELP_STRING([--enable-bsdcpio=shared], [dynamic build of bsdcpio])
+AS_HELP_STRING([--disable-bsdcpio], [disable build of bsdcpio])],
+	[], [enable_bsdcpio=yes])
+
+case "$enable_bsdcpio" in
+yes)
+	if test "$enable_static" = "no"; then
+	   static_bsdcpio=no
+	else
+	   static_bsdcpio=yes
+        fi
+	build_bsdcpio=yes
+	;;
+dynamic|shared)
+	if test "$enabled_shared" = "no"; then
+	   AC_MSG_FAILURE([Shared linking of bsdcpio requires shared libarchive])
+	fi
+	build_bsdcpio=yes
+	;;
+static)
+	build_bsdcpio=yes
+	static_bsdcpio=yes
+	;;
+no)
+	build_bsdcpio=no
+	static_bsdcpio=no
+	;;
+*)
+	AC_MSG_FAILURE([Unsupported value for --enable-bsdcpio])
+	;;
+esac
+
+AM_CONDITIONAL([BUILD_BSDCPIO], [ test "$build_bsdcpio" = yes ])
+AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ])
+
+# Set up defines needed before including any headers
+case $host in
+  *mingw* | *cygwin* )
+  AC_DEFINE([_WIN32_WINNT], 0x0500, [Define to '0x0500' for Windows 2000 APIs.])
+  AC_DEFINE([WINVER], 0x0500, [Define to '0x0500' for Windows 2000 APIs.])
+  ;;
+esac
+
+# Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h copyfile.h ctype.h])
+AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
+
+AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable],
+    [ac_cv_have_decl_EXT2_IOC_GETFLAGS],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <sys/ioctl.h>
+@%:@include <ext2fs/ext2_fs.h>],
+                                   [int x = EXT2_IOC_GETFLAGS])],
+                  [AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes])],
+                  [AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [no])])])
+
+AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
+    [AC_DEFINE_UNQUOTED([HAVE_WORKING_EXT2_IOC_GETFLAGS], [1],
+                    [Define to 1 if you have a working EXT2_IOC_GETFLAGS])])
+
+AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
+AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
+AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h signal.h spawn.h])
+AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
+AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h])
+AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
+AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
+AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
+AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([windows.h])
+# check windows.h first; the other headers require it.
+AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
+[[#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+]])
+
+# Checks for libraries.
+AC_ARG_WITH([zlib],
+  AS_HELP_STRING([--without-zlib], [Don't build support for gzip through zlib]))
+
+if test "x$with_zlib" != "xno"; then
+  AC_CHECK_HEADERS([zlib.h])
+  AC_CHECK_LIB(z,inflate)
+fi
+
+AC_ARG_WITH([bz2lib],
+  AS_HELP_STRING([--without-bz2lib], [Don't build support for bzip2 through bz2lib]))
+
+if test "x$with_bz2lib" != "xno"; then
+  AC_CHECK_HEADERS([bzlib.h])
+  case "$host_os" in
+    *mingw* | *cygwin*)
+      dnl AC_CHECK_LIB cannot be used on the Windows port of libbz2, therefore
+	  dnl use AC_LINK_IFELSE.
+	  AC_MSG_CHECKING([for BZ2_bzDecompressInit in -lbz2])
+      old_LIBS="$LIBS"
+      LIBS="-lbz2 $LIBS"
+      AC_LINK_IFELSE(
+        [AC_LANG_SOURCE(#include <bzlib.h>
+          int main() { return BZ2_bzDecompressInit(NULL, 0, 0); })],
+        [ac_cv_lib_bz2_BZ2_bzDecompressInit=yes],
+        [ac_cv_lib_bz2_BZ2_bzDecompressInit=no])
+      LIBS="$old_LIBS"
+	  AC_MSG_RESULT($ac_cv_lib_bz2_BZ2_bzDecompressInit)
+      if test "x$ac_cv_lib_bz2_BZ2_bzDecompressInit" = xyes; then
+        AC_DEFINE([HAVE_LIBBZ2], [1], [Define to 1 if you have the `bz2' library (-lbz2).])
+        LIBS="-lbz2 $LIBS"
+      fi
+    ;;
+    *)
+      AC_CHECK_LIB(bz2,BZ2_bzDecompressInit)
+    ;;
+  esac
+fi
+
+AC_ARG_WITH([lzmadec],
+  AS_HELP_STRING([--without-lzmadec], [Don't build support for lzma through lzmadec]))
+
+if test "x$with_lzmadec" != "xno"; then
+  AC_CHECK_HEADERS([lzmadec.h])
+  AC_CHECK_LIB(lzmadec,lzmadec_decode)
+fi
+
+AC_ARG_WITH([iconv],
+  AS_HELP_STRING([--without-iconv], [Don't try to link against iconv]))
+
+if test "x$with_iconv" != "xno"; then
+  AM_ICONV
+  AC_CHECK_HEADERS([iconv.h],[],[],[#include <stdlib.h>])
+  if test "x$am_cv_func_iconv" = "xyes"; then
+    AC_CHECK_HEADERS([localcharset.h])
+    am_save_LIBS="$LIBS"
+    LIBS="${LIBS} ${LIBICONV}"
+    AC_CHECK_FUNCS([locale_charset])
+    LIBS="${am_save_LIBS}"
+    if test "x$ac_cv_func_locale_charset" != "xyes"; then
+      # If locale_charset() is not in libiconv, we have to find libcharset. 
+      AC_CHECK_LIB(charset,locale_charset)
+    fi
+  fi
+fi
+
+AC_ARG_WITH([lzma],
+  AS_HELP_STRING([--without-lzma], [Don't build support for xz through lzma]))
+
+if test "x$with_lzma" != "xno"; then
+  AC_CHECK_HEADERS([lzma.h])
+  AC_CHECK_LIB(lzma,lzma_stream_decoder)
+fi
+
+AC_ARG_WITH([lzo2],
+  AS_HELP_STRING([--without-lzo2], [Don't build support for lzop through liblzo2]))
+
+if test "x$with_lzo2" != "xno"; then
+  AC_CHECK_HEADERS([lzo/lzoconf.h lzo/lzo1x.h])
+  AC_CHECK_LIB(lzo2,lzo1x_decompress_safe)
+fi
+
+AC_ARG_WITH([nettle],
+  AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
+AC_ARG_WITH([openssl],
+  AS_HELP_STRING([--without-openssl], [Don't build support for mtree and xar hashes through openssl]))
+case "$host_os" in
+  *darwin* ) with_openssl=no ;;
+esac
+
+AC_ARG_WITH([xml2],
+  AS_HELP_STRING([--without-xml2], [Don't build support for xar through libxml2]))
+AC_ARG_WITH([expat],
+  AS_HELP_STRING([--without-expat], [Don't build support for xar through expat]))
+
+if test "x$with_xml2" != "xno"; then
+  AC_PATH_PROG([XML2_CONFIG], [xml2-config],, [${PATH}])
+  if test "x$XML2_CONFIG" != "x"; then
+    CPPFLAGS="${CPPFLAGS} `${XML2_CONFIG} --cflags`"
+    LIBS="${LIBS} `${XML2_CONFIG} --libs`"
+    AC_CHECK_LIB(xml2,xmlInitParser,[true],AC_MSG_FAILURE(Missing xml2 library))
+  else
+    AC_CHECK_LIB(xml2,xmlInitParser)
+  fi
+  AC_CHECK_HEADERS([libxml/xmlreader.h libxml/xmlwriter.h])
+fi
+if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
+  if test "x$with_expat" != "xno"; then
+    AC_CHECK_HEADERS([expat.h])
+    AC_CHECK_LIB(expat,XML_ParserCreate)
+  fi
+fi
+
+AC_ARG_ENABLE([posix-regex-lib],
+  [AS_HELP_STRING([--enable-posix-regex-lib],
+    [choose what library to use for POSIX regular expression support (default: auto)])
+  AS_HELP_STRING([--enable-posix-regex-lib=libc], [use libc POSIX regular expression support])
+  AS_HELP_STRING([--enable-posix-regex-lib=libregex], [use libregex POSIX regular expression support])
+  AS_HELP_STRING([--enable-posix-regex-lib=libpcreposix], [use libpcreposix POSIX regular expression support])
+  AS_HELP_STRING([--disable-posix-regex-lib], [don't enable POSIX regular expression support])],
+  [], [enable_posix_regex_lib=auto])
+
+posix_regex_lib_found=
+if test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libc" || test "$enable_posix_regex_lib" = "libregex"; then
+  AC_CHECK_HEADERS([regex.h])
+  if test "x$ac_cv_header_regex_h" != "xno"; then
+    AC_CHECK_FUNC(regcomp)
+    if test "x$ac_cv_func_regcomp" = xyes; then
+      posix_regex_lib_found=1
+    else
+      AC_CHECK_LIB(regex,regcomp)
+      if test "x$ac_cv_lib_regex_regcomp" = xyes; then
+        posix_regex_lib_found=1
+      fi
+    fi
+  fi
+fi
+if test -z $posix_regex_lib_found && (test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libpcreposix"); then
+  AC_CHECK_HEADERS([pcreposix.h])
+  AC_CHECK_LIB(pcreposix,regcomp)
+  if test "x$ac_cv_lib_pcreposix_regcomp" != xyes; then
+    AC_MSG_NOTICE(trying libpcreposix check again with libpcre)
+	unset ac_cv_lib_pcreposix_regcomp
+	AC_CHECK_LIB(pcre,pcre_exec)
+    AC_CHECK_LIB(pcreposix,regcomp)
+    if test "x$ac_cv_lib_pcre_pcre_exec" = xyes && test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then
+      AC_MSG_CHECKING(if PCRE_STATIC needs to be defined)
+      AC_LINK_IFELSE(
+        [AC_LANG_SOURCE(#include <pcreposix.h>
+          int main() { return regcomp(NULL, NULL, 0); })],
+        [without_pcre_static=yes],
+        [without_pcre_static=no])
+      AC_LINK_IFELSE(
+        [AC_LANG_SOURCE(#define PCRE_STATIC
+          #include <pcreposix.h>
+          int main() { return regcomp(NULL, NULL, 0); })],
+        [with_pcre_static=yes],
+        [with_pcre_static=no])
+      if test "x$without_pcre_static" != xyes && test "x$with_pcre_static" = xyes; then
+        AC_MSG_RESULT(yes)
+        AC_DEFINE([PCRE_STATIC], [1], [Define to 1 if PCRE_STATIC needs to be defined.])
+      elif test "x$without_pcre_static" = xyes || test "x$with_pcre_static" = xyes; then
+        AC_MSG_RESULT(no)
+      fi
+      posix_regex_lib_found=1
+    fi
+  else
+    posix_regex_lib_found=1
+  fi
+fi
+
+# TODO: Give the user the option of using a pre-existing system
+# libarchive.  This will define HAVE_LIBARCHIVE which will cause
+# bsdtar_platform.h to use #include <...> for the libarchive headers.
+# Need to include Makefile.am magic to link against system
+# -larchive in that case.
+#AC_CHECK_LIB(archive,archive_version)
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+# AC_TYPE_UID_T defaults to "int", which is incorrect for MinGW
+# and MSVC. Use a customized version.
+la_TYPE_UID_T
+AC_TYPE_MODE_T
+# AC_TYPE_OFF_T defaults to "long", which limits us to 4GB files on
+# most systems... default to "long long" instead.
+AC_CHECK_TYPE(off_t, [long long])
+AC_TYPE_SIZE_T
+AC_CHECK_TYPE(id_t, [unsigned long])
+AC_CHECK_TYPE(uintptr_t, [unsigned int])
+
+# Check for tm_gmtoff in struct tm
+AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,
+[
+#include <time.h>
+])
+
+# Check for f_namemax in struct statfs
+AC_CHECK_MEMBERS([struct statfs.f_namemax],,,
+[
+#include <sys/param.h>
+#include <sys/mount.h>
+])
+
+# Check for f_iosize in struct statvfs
+AC_CHECK_MEMBERS([struct statvfs.f_iosize],,,
+[
+#include <sys/statvfs.h>
+])
+
+# Check for birthtime in struct stat
+AC_CHECK_MEMBERS([struct stat.st_birthtime])
+
+# Check for high-resolution timestamps in struct stat
+AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec])
+AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec])
+AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
+AC_CHECK_MEMBERS([struct stat.st_mtime_n]) # AIX
+AC_CHECK_MEMBERS([struct stat.st_umtime]) # Tru64
+AC_CHECK_MEMBERS([struct stat.st_mtime_usec]) # Hurd
+# Check for block size support in struct stat
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+# Check for st_flags in struct stat (BSD fflags)
+AC_CHECK_MEMBERS([struct stat.st_flags])
+
+# If you have uintmax_t, we assume printf supports %ju
+# If you have unsigned long long, we assume printf supports %llu
+# TODO: Check for %ju and %llu support directly.
+AC_CHECK_TYPES([uintmax_t, unsigned long long])
+
+# We use C99-style integer types
+# Declare them if the local platform doesn't already do so.
+AC_TYPE_INTMAX_T
+AC_TYPE_UINTMAX_T
+AC_TYPE_INT64_T
+AC_TYPE_UINT64_T
+AC_TYPE_INT32_T
+AC_TYPE_UINT32_T
+AC_TYPE_INT16_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT8_T
+
+AC_CHECK_DECLS([SIZE_MAX, INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX])
+
+AC_CHECK_DECL([SSIZE_MAX],
+		[AC_DEFINE(HAVE_DECL_SSIZE_MAX, 1, [Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you don't.])],
+		[],
+		[#include <limits.h>])
+
+AC_CHECK_DECL([EFTYPE],
+		[AC_DEFINE(HAVE_EFTYPE, 1, [A possible errno value for invalid file format errors])],
+		[],
+		[#include <errno.h>])
+AC_CHECK_DECL([EILSEQ],
+		[AC_DEFINE(HAVE_EILSEQ, 1, [A possible errno value for invalid file format errors])],
+		[],
+		[#include <errno.h>])
+AC_CHECK_TYPE([wchar_t],
+	        [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]wchar_t), 1, [Define to 1 if the system has the type `wchar_t'.])dnl
+		AC_CHECK_SIZEOF([wchar_t])],
+		[])
+
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_HEADER_MAJOR
+AC_FUNC_FSEEKO
+AC_FUNC_MEMCMP
+AC_FUNC_LSTAT
+AC_FUNC_STAT
+AC_FUNC_STRERROR_R
+AC_FUNC_STRFTIME
+AC_FUNC_VPRINTF
+# check for:
+#   CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES)
+# To avoid necessity for including windows.h or special forward declaration
+# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
+AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
+AC_CHECK_FUNCS([chflags chown chroot ctime_r dirfd])
+AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork])
+AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
+AC_CHECK_FUNCS([futimens futimes futimesat])
+AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r])
+AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
+AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes])
+AC_CHECK_FUNCS([mbrtowc memmove memset])
+AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
+AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat])
+AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
+AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
+AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
+AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy])
+AC_CHECK_FUNCS([_ctime64_s _fseeki64])
+AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64])
+# detects cygwin-1.7, as opposed to older versions
+AC_CHECK_FUNCS([cygwin_conv_path])
+
+# There are several variants of readdir_r around; we only
+# accept the POSIX-compliant version.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <dirent.h>]],
+                  [[DIR *dir; struct dirent e, *r;
+		    return(readdir_r(dir, &e, &r));]])],
+ [AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])]
+)
+
+# FreeBSD's nl_langinfo supports an option to specify whether the
+# current locale uses month/day or day/month ordering.  It makes the
+# output a little prettier...
+AC_CHECK_DECL([D_MD_ORDER],
+[AC_DEFINE(HAVE_D_MD_ORDER, 1, [Define to 1 if nl_langinfo supports D_MD_ORDER])],
+[],
+[#if HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+])
+
+# Check for dirent.d_namlen field explicitly
+# (This is a bit more straightforward than, if not quite as portable as,
+# the recipe given by the autoconf maintainers.)
+AC_CHECK_MEMBER(struct dirent.d_namlen,,,
+[#if HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+])
+
+# Check for Extended Attributes support
+AC_ARG_ENABLE([xattr],
+		AS_HELP_STRING([--disable-xattr],
+		[Enable Extended Attributes support (default: check)]))
+
+if test "x$enable_xattr" != "xno"; then
+	AC_CHECK_HEADERS([attr/xattr.h])
+	AC_CHECK_HEADERS([sys/xattr.h sys/ea.h])
+	AC_CHECK_LIB(attr,setxattr)
+	AC_CHECK_FUNCS([extattr_get_file extattr_list_file])
+	AC_CHECK_FUNCS([extattr_set_fd extattr_set_file])
+	AC_CHECK_FUNCS([fgetxattr flistxattr fsetxattr getxattr])
+	AC_CHECK_FUNCS([lgetxattr listxattr llistxattr lsetxattr])
+	AC_CHECK_FUNCS([fgetea flistea fsetea getea])
+	AC_CHECK_FUNCS([lgetea listea llistea lsetea])
+	AC_CHECK_DECLS([EXTATTR_NAMESPACE_USER], [], [], [#include <sys/types.h>
+#include <sys/extattr.h>
+])
+fi
+
+# Check for ACL support
+#
+# The ACL support in libarchive is written against the POSIX1e draft,
+# which was never officially approved and varies quite a bit across
+# platforms.  Worse, some systems have completely non-POSIX acl functions,
+# which makes the following checks rather more complex than I would like.
+#
+AC_ARG_ENABLE([acl],
+		AS_HELP_STRING([--disable-acl],
+		[Enable ACL support (default: check)]))
+
+if test "x$enable_acl" != "xno"; then
+   AC_CHECK_HEADERS([sys/acl.h])
+   AC_CHECK_LIB([acl],[acl_get_file])
+   AC_CHECK_FUNCS([acl_create_entry acl_init acl_set_fd acl_set_fd_np acl_set_file])
+
+   AC_CHECK_TYPES(acl_permset_t,,,
+	[#if HAVE_SYS_TYPES_H
+	#include <sys/types.h>
+	#endif
+	#if HAVE_SYS_ACL_H
+	#include <sys/acl.h>
+	#endif
+	])
+
+    # The "acl_get_perm()" function was omitted from the POSIX draft.
+    # (It's a pretty obvious oversight; otherwise, there's no way to
+    # test for specific permissions in a permset.)  Linux uses the obvious
+    # name, FreeBSD adds _np to mark it as "non-Posix extension."
+    # Test for both as a double-check that we really have POSIX-style ACL support.
+    AC_CHECK_FUNCS(acl_get_perm_np acl_get_perm acl_get_link acl_get_link_np,,,
+	[#if HAVE_SYS_TYPES_H
+	#include <sys/types.h>
+	#endif
+	#if HAVE_SYS_ACL_H
+	#include <sys/acl.h>
+	#endif
+	])
+
+    # MacOS has an acl.h that isn't POSIX.  It can be detected by
+    # checking for ACL_USER
+    AC_CHECK_DECL([ACL_USER],
+		[AC_DEFINE(HAVE_ACL_USER, 1, [True for systems with POSIX ACL support])],
+		[],
+		[#include <sys/acl.h>])
+fi
+
+# Additional requirements
+AC_SYS_LARGEFILE
+
+dnl NOTE: Crypto checks must run last.
+AC_DEFUN([CRYPTO_CHECK], [
+  if test "$found_$1" != yes; then
+    saved_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive"
+    touch "check_crypto_md.h"
+    AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_$2])
+    AC_LINK_IFELSE([AC_LANG_SOURCE([
+#define ARCHIVE_$1_COMPILE_TEST
+#define ARCHIVE_CRYPTO_$1_$2
+#define PLATFORM_CONFIG_H "check_crypto_md.h"
+
+$(cat "$srcdir/libarchive/archive_crypto.c")
+
+int
+main(int argc, char **argv)
+{
+  archive_$3_ctx ctx;
+  archive_$3_init(&ctx);
+  archive_$3_update(&ctx, *argv, argc);
+  archive_$3_final(&ctx, NULL);
+  return 0;
+}
+])],
+    [ AC_MSG_RESULT([yes])
+      found_$1=yes
+      found_$2=yes
+      AC_DEFINE(ARCHIVE_CRYPTO_$1_$2, 1, [ $1 via ARCHIVE_CRYPTO_$1_$2 supported.])
+    ],
+    [ AC_MSG_RESULT([no])])
+    CPPFLAGS="$saved_CPPFLAGS"
+    rm "check_crypto_md.h"
+  fi
+])
+
+AC_DEFUN([CRYPTO_CHECK_WIN], [
+  if test "$found_$1" != yes; then
+    AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_WIN])
+    AC_LINK_IFELSE([AC_LANG_SOURCE([
+#define ARCHIVE_$1_COMPILE_TEST
+#include <windows.h>
+#include <wincrypt.h>
+
+int
+main(int argc, char **argv)
+{
+	(void)argc;
+	(void)argv;
+
+	return ($2);
+}
+])],
+    [ AC_MSG_RESULT([yes])
+      found_$1=yes
+      found_WIN=yes
+      AC_DEFINE(ARCHIVE_CRYPTO_$1_WIN, 1, [ $1 via ARCHIVE_CRYPTO_$1_WIN supported.])
+    ],
+    [ AC_MSG_RESULT([no])])
+  fi
+])
+
+case "$host_os" in
+  *mingw* | *cygwin*)
+	;;
+  *)
+	CRYPTO_CHECK(MD5, LIBC, md5)
+	CRYPTO_CHECK(MD5, LIBSYSTEM, md5)
+	CRYPTO_CHECK(RMD160, LIBC, rmd160)
+	CRYPTO_CHECK(SHA1, LIBC, sha1)
+	CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1)
+	CRYPTO_CHECK(SHA256, LIBC, sha256)
+	CRYPTO_CHECK(SHA256, LIBC2, sha256)
+	CRYPTO_CHECK(SHA256, LIBC3, sha256)
+	CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256)
+	CRYPTO_CHECK(SHA384, LIBC, sha384)
+	CRYPTO_CHECK(SHA384, LIBC2, sha384)
+	CRYPTO_CHECK(SHA384, LIBC3, sha384)
+	CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384)
+	CRYPTO_CHECK(SHA512, LIBC, sha512)
+	CRYPTO_CHECK(SHA512, LIBC2, sha512)
+	CRYPTO_CHECK(SHA512, LIBC3, sha512)
+	CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512)
+	;;
+esac
+
+if test "x$with_nettle" != "xno"; then
+    AC_CHECK_HEADERS([nettle/md5.h nettle/ripemd160.h nettle/sha.h])
+    saved_LIBS=$LIBS
+    AC_CHECK_LIB(nettle,main)
+    CRYPTO_CHECK(MD5, NETTLE, md5)
+    CRYPTO_CHECK(RMD160, NETTLE, rmd160)
+    CRYPTO_CHECK(SHA1, NETTLE, sha1)
+    CRYPTO_CHECK(SHA256, NETTLE, sha256)
+    CRYPTO_CHECK(SHA384, NETTLE, sha384)
+    CRYPTO_CHECK(SHA512, NETTLE, sha512)
+    if test "x$found_NETTLE" != "xyes"; then
+      LIBS=$saved_LIBS
+    fi
+fi
+if test "x$with_openssl" != "xno"; then
+    AC_CHECK_HEADERS([openssl/evp.h])
+    saved_LIBS=$LIBS
+    case "$host_os" in
+      *mingw* | *cygwin*)
+        case "$host_cpu" in
+          x86_64)
+            AC_CHECK_LIB(eay64,main)
+            if test "x$ac_cv_lib_eay64_main" != "xyes"; then
+              AC_CHECK_LIB(eay32,main)
+            fi
+            ;;
+          *)
+            AC_CHECK_LIB(eay32,main)
+            ;;
+        esac
+        ;;
+      *)
+        AC_CHECK_LIB(crypto,main)
+        ;;
+    esac
+    CRYPTO_CHECK(MD5, OPENSSL, md5)
+    CRYPTO_CHECK(RMD160, OPENSSL, rmd160)
+    CRYPTO_CHECK(SHA1, OPENSSL, sha1)
+    CRYPTO_CHECK(SHA256, OPENSSL, sha256)
+    CRYPTO_CHECK(SHA384, OPENSSL, sha384)
+    CRYPTO_CHECK(SHA512, OPENSSL, sha512)
+    if test "x$found_OPENSSL" != "xyes"; then
+      LIBS=$saved_LIBS
+    fi
+fi
+
+# Probe libmd AFTER OpenSSL/libcrypto.
+# The two are incompatible and OpenSSL is more complete.
+AC_CHECK_HEADERS([md5.h ripemd.h sha.h sha256.h sha512.h])
+saved_LIBS=$LIBS
+AC_CHECK_LIB(md,main)
+CRYPTO_CHECK(MD5, LIBMD, md5)
+CRYPTO_CHECK(RMD160, LIBMD, rmd160)
+CRYPTO_CHECK(SHA1, LIBMD, sha1)
+CRYPTO_CHECK(SHA256, LIBMD, sha256)
+CRYPTO_CHECK(SHA512, LIBMD, sha512)
+if test "x$found_LIBMD" != "xyes"; then
+  LIBS=$saved_LIBS
+fi
+
+case "$host_os" in
+  *mingw* | *cygwin*)
+	CRYPTO_CHECK_WIN(MD5, CALG_MD5)
+	CRYPTO_CHECK_WIN(SHA1, CALG_SHA1)
+	CRYPTO_CHECK_WIN(SHA256, CALG_SHA_256)
+	CRYPTO_CHECK_WIN(SHA384, CALG_SHA_384)
+	CRYPTO_CHECK_WIN(SHA512, CALG_SHA_512)
+	;;
+esac
+
+AC_OUTPUT
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 000000000000..8ad352a30204
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,59 @@
+Many people have graciously sent me configuration
+files, small programs that use libarchive, and other
+useful and interesting tidbits.
+
+I do not support or use any of these; but if you can use them, enjoy!
+
+======================================================================
+
+From: Andre Stechert <andre@splunk.com>
+
+libarchive_autodetect-st_lib_archive.m4
+
+M4 macros for use with autoconf to detect whether a suitable
+version of libarchive is installed on this system.
+
+
+======================================================================
+
+libarchive.spec
+
+An RPM ".spec" file for building libarchive on most systems.
+This apparently was originally developed by a group at pld-linux.org.
+Several people have sent me different versions of this file.
+
+======================================================================
+
+From: Robert Meier <rm1023@dcx.com>
+
+libarchive.1aix53.spec
+
+As above, for use on AIX5.3.
+
+======================================================================
+
+psota-benchmark
+
+Some scripts used by Jan Psota in benchmarking
+various tar implementations.
+
+I've edited his results slightly to correctly reflect that
+bsdtar does not support a "compare" operation.
+
+======================================================================
+
+shar
+
+A simple shar program written on top of libarchive.
+
+======================================================================
+
+untar.c
+
+A very simple and very portable standalone program that can
+extract basic ustar archives.
+This does not use libarchive and so can be used to extract
+the libarchive distribution on any system that has a C compiler
+but does not have a tar program.
+
+======================================================================
diff --git a/contrib/libarchive.1aix53.spec b/contrib/libarchive.1aix53.spec
new file mode 100644
index 000000000000..fe81d147e03e
--- /dev/null
+++ b/contrib/libarchive.1aix53.spec
@@ -0,0 +1,160 @@
+# $LastChangedRevision$, $LastChangedDate$
+Summary:        Library to create and read several different archive formats
+Summary(pl):    Biblioteka do tworzenia i odczytu r�nych format�w archiw�w
+Name:           libarchive
+Version:        2.0a3
+Release:        1aix53
+License:        BSD
+Group:          Libraries
+Source0: http://people.freebsd.org/~kientzle/libarchive/src/%{name}-%{version}.tar.gz
+Patch:          %{name}-0123457890.patch
+URL:            http://people.freebsd.org/~kientzle/libarchive/
+Requires:       glibc
+Requires:       zlib
+Requires:       bzip2
+BuildRequires:  gcc
+BuildRequires:  gcc-c++
+BuildRequires:  gawk
+BuildRequires:  zlib-devel
+BuildRequires:  bzip2
+BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+
+%description
+Libarchive is a programming library that can create and read several
+different streaming archive formats, including most popular TAR
+variants and several CPIO formats. It can also write SHAR archives.
+
+%description -l pl
+Libarchive jest bibliotek� s�u�ac� to tworzenia i odczytu wielu
+r�nych strumieniowych format�w archiw�w, w��czaj�c w to popularne
+odmiany TAR oraz wiele format�w CPIO. Biblioteka ta potrafi tak�e
+zapisywa� archiwa SHAR.
+
+%package devel
+Summary:        Header files for libarchive library
+Summary(pl):    Pliki nag��wkowe biblioteki libarchive
+Group:          Development/Libraries
+Requires:       %{name} = %{version}-%{release}
+
+%description devel
+Header files for libarchive library.
+
+%description devel -l pl
+Pliki nag��wkowe biblioteki libarchive.
+
+%package static
+Summary:        Static libarchive library
+Summary(pl):    Statyczna biblioteka libarchive
+Group:          Development/Libraries
+Requires:       %{name}-devel = %{version}-%{release}
+
+%description static
+Static libarchive library.
+
+%description static -l pl
+Statyczna biblioteka libarchive.
+
+%package -n bsdtar
+Summary:        bsdtar - tar(1) implementation based on libarchive
+Summary(pl):    bsdtar - implementacja programu tar(1) oparta na libarchive
+Group:          Applications/Archiving
+Requires:       %{name} = %{version}-%{release}
+
+%description -n bsdtar
+bsdtar - tar(1) implementation based on libarchive.
+
+%description -n bsdtar -l pl
+bsdtar - implementacja programu tar(1), oparta na libarchive.
+
+%prep
+%setup -q
+%patch0 -p1
+
+%build
+# Specify paths to avoid use of vacpp
+# -maix64 - required to use large files with aix-5.3
+# -static - required for interoperability without copying libraries
+# -D_BSD - required to include definition of makedev
+# -X64 - required to assemble 64-bit COFF files
+mkdir -p %{buildroot}
+PATH=/opt/freeware/libexec:/opt/freeware/bin:/usr/local/bin:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:. \
+CPATH=/opt/freeware/include:/usr/local/include \
+LIBPATH=/opt/freeware/lib:/usr/local/lib:/usr/share/lib \
+LD_LIBRARY_PATH=/opt/freeware/lib:/usr/local/lib:/usr/share/lib \
+CFLAGS="$RPM_OPT_FLAGS -maix64 -static -D_BSD" \
+CXXFLAGS="$RPM_OPT_FLAGS -maix64 -static -D_BSD" \
+AR="ar -X64" \
+./configure \
+--prefix=%{_prefix} \
+--libexecdir=%{_libexecdir} \
+--mandir=%{_mandir} \
+--infodir=%{_infodir} \
+--enable-shared=yes \
+--enable-static=yes \
+| tee %{buildroot}/config.log
+make | tee %{buildroot}/make.log
+
+%install
+[ "%buildroot" != "/" ] && [ -d %buildroot ] && rm -rf %buildroot;
+make DESTDIR=%buildroot install
+# original install builds, but does install bsdtar
+cp .libs/%{name}.a %{buildroot}%{_libdir}
+cp bsdtar %{buildroot}%{_bindir}
+cp tar/bsdtar.1 %{buildroot}%{_mandir}/man1
+
+%clean
+rm -fr %buildroot
+
+%files
+%defattr(644,root,root,755)
+%{_libdir}/libarchive.a
+
+%files devel
+%defattr(644,root,root,755)
+%{_libdir}/libarchive.la
+%{_includedir}/*.h
+%doc %{_mandir}/man3/*
+%doc %{_mandir}/man5/*
+
+%files -n bsdtar
+%defattr(644,root,root,755)
+%attr(755,root,root) %{_bindir}/bsdtar
+%doc %{_mandir}/man1/bsdtar.1*
+
+%define date    %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
+%changelog
+* %{date} PLD Team <feedback@pld-linux.org>
+All persons listed below can be reached at <cvs_login>@pld-linux.org
+
+$Log: libarchive.spec,v $
+Release 1aix53  2006/12/12 rm1023@dcx.com
+- tweak for aix-5.3
+- added libarchive-0123457890.patch for "0123457890" error
+- replaced libarchive-1.3.1.tar.gz with libarchive-2.0a3.tar.gz
+- removed obsolete -CVE-2006-5680.patch and -man_progname.patch
+
+Revision 1.6  2006/11/15 10:41:28  qboosh
+- BR: acl-devel,attr-devel
+- devel deps
+
+Revision 1.5  2006/11/08 22:22:25  twittner
+- up to 1.3.1
+- added BR: e2fsprogs-devel
+- added -CVE-2006-5680.patch against entering an infinite
+loop in corrupt archives
+- added bsdtar package (bsdtar is included now in libarchive
+sources)
+- rel. 0.1 for testing
+
+Revision 1.4  2005/12/15 18:26:36  twittner
+- up to 1.2.37
+- removed -shared.patch (no longer needed)
+
+Revision 1.3  2005/10/05 17:00:12  arekm
+- up to 1.02.034
+
+Revision 1.2  2005/07/27 20:17:21  qboosh
+- typo
+
+Revision 1.1  2005/07/27 08:36:03  adamg
+- new
diff --git a/contrib/libarchive.spec b/contrib/libarchive.spec
new file mode 100644
index 000000000000..b5b658a874b1
--- /dev/null
+++ b/contrib/libarchive.spec
@@ -0,0 +1,147 @@
+# $LastChangedRevision$, $LastChangedDate$
+Summary:        Library to create and read several different archive formats
+Summary(pl):    Biblioteka do tworzenia i odczytu r�nych format�w archiw�w
+Name:           libarchive
+Version:        2.0a3
+Release:        1
+License:        BSD
+Group:          Libraries
+Source0: http://people.freebsd.org/~kientzle/libarchive/src/%{name}-%{version}.tar.gz
+Patch:          %{name}-0123457890.patch
+URL:            http://people.freebsd.org/~kientzle/libarchive/
+Requires:       glibc
+Requires:       zlib
+Requires:       bzip2
+BuildRequires:  gcc
+BuildRequires:  gcc-c++
+BuildRequires:  gawk
+BuildRequires:  zlib-devel
+BuildRequires:  bzip2
+BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+
+%description
+Libarchive is a programming library that can create and read several
+different streaming archive formats, including most popular TAR
+variants and several CPIO formats. It can also write SHAR archives.
+
+%description -l pl
+Libarchive jest bibliotek� s�u�ac� to tworzenia i odczytu wielu
+r�nych strumieniowych format�w archiw�w, w��czaj�c w to popularne
+odmiany TAR oraz wiele format�w CPIO. Biblioteka ta potrafi tak�e
+zapisywa� archiwa SHAR.
+
+%package devel
+Summary:        Header files for libarchive library
+Summary(pl):    Pliki nag��wkowe biblioteki libarchive
+Group:          Development/Libraries
+Requires:       %{name} = %{version}-%{release}
+
+%description devel
+Header files for libarchive library.
+
+%description devel -l pl
+Pliki nag��wkowe biblioteki libarchive.
+
+%package static
+Summary:        Static libarchive library
+Summary(pl):    Statyczna biblioteka libarchive
+Group:          Development/Libraries
+Requires:       %{name}-devel = %{version}-%{release}
+
+%description static
+Static libarchive library.
+
+%description static -l pl
+Statyczna biblioteka libarchive.
+
+%package -n bsdtar
+Summary:        bsdtar - tar(1) implementation based on libarchive
+Summary(pl):    bsdtar - implementacja programu tar(1) oparta na libarchive
+Group:          Applications/Archiving
+Requires:       %{name} = %{version}-%{release}
+
+%description -n bsdtar
+bsdtar - tar(1) implementation based on libarchive.
+
+%description -n bsdtar -l pl
+bsdtar - implementacja programu tar(1), oparta na libarchive.
+
+%prep
+%setup -q
+%patch0 -p1
+
+%build
+mkdir -p %{buildroot}
+./configure \
+--prefix=%{_prefix} \
+--libexecdir=%{_libexecdir} \
+--mandir=%{_mandir} \
+--infodir=%{_infodir} \
+--enable-shared=yes \
+--enable-static=yes \
+| tee %{buildroot}/config.log
+make | tee %{buildroot}/make.log
+
+%install
+[ "%buildroot" != "/" ] && [ -d %buildroot ] && rm -rf %buildroot;
+make DESTDIR=%buildroot install
+# original install builds, but does install bsdtar
+cp .libs/%{name}.a %{buildroot}%{_libdir}
+cp bsdtar %{buildroot}%{_bindir}
+cp tar/bsdtar.1 %{buildroot}%{_mandir}/man1
+
+%clean
+rm -fr %buildroot
+
+%files
+%defattr(644,root,root,755)
+%{_libdir}/libarchive.a
+
+%files devel
+%defattr(644,root,root,755)
+%{_libdir}/libarchive.la
+%{_includedir}/*.h
+%doc %{_mandir}/man3/*
+%doc %{_mandir}/man5/*
+
+%files -n bsdtar
+%defattr(644,root,root,755)
+%attr(755,root,root) %{_bindir}/bsdtar
+%doc %{_mandir}/man1/bsdtar.1*
+
+%define date    %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
+%changelog
+* %{date} PLD Team <feedback@pld-linux.org>
+All persons listed below can be reached at <cvs_login>@pld-linux.org
+
+$Log: libarchive.spec,v $
+Release 1  2006/12/12 rm1023@dcx.com
+- added libarchive-0123457890.patch for "0123457890" error
+- replaced libarchive-1.3.1.tar.gz with libarchive-2.0a3.tar.gz
+- removed obsolete -CVE-2006-5680.patch and -man_progname.patch
+
+Revision 1.6  2006/11/15 10:41:28  qboosh
+- BR: acl-devel,attr-devel
+- devel deps
+
+Revision 1.5  2006/11/08 22:22:25  twittner
+- up to 1.3.1
+- added BR: e2fsprogs-devel
+- added -CVE-2006-5680.patch against entering an infinite
+loop in corrupt archives
+- added bsdtar package (bsdtar is included now in libarchive
+sources)
+- rel. 0.1 for testing
+
+Revision 1.4  2005/12/15 18:26:36  twittner
+- up to 1.2.37
+- removed -shared.patch (no longer needed)
+
+Revision 1.3  2005/10/05 17:00:12  arekm
+- up to 1.02.034
+
+Revision 1.2  2005/07/27 20:17:21  qboosh
+- typo
+
+Revision 1.1  2005/07/27 08:36:03  adamg
+- new
diff --git a/contrib/libarchive_autodetect-st_lib_archive.m4 b/contrib/libarchive_autodetect-st_lib_archive.m4
new file mode 100644
index 000000000000..4419e888f240
--- /dev/null
+++ b/contrib/libarchive_autodetect-st_lib_archive.m4
@@ -0,0 +1,154 @@
+dnl
+dnl @synopsis ST_LIB_ARCHIVE([ENABLED-DEFAULT])
+dnl
+dnl This macro figures out what's necessary to link a program against an
+dnl instance of the BSD libarchive package by Tim Kientzle.
+dnl 
+dnl See http://people.freebsd.org/~kientzle/libarchive/ for more info.
+dnl
+dnl It exports and substitutes the variables LIBARCHIVE_LIBS, LIBARCHIVE_LDFLAGS,
+dnl and LIBARCHIVE_CPPFLAGS to appropriate values for the identified instance of
+dnl libarchive.  The values are AC_SUBST'd, so a user could, for example, simply
+dnl include @LIBARCHIVE_CPPFLAGS@ in the definition of AM_CPPFLAGS in a Makefile.am.
+dnl
+dnl ENABLED-DEFAULT is either "yes" or "no" and determines whether the default value
+dnl is --with-libarchive or --without-libarchive.  It is not possible to specify a
+dnl default directory.  More simply, any reasonable choice for a default should just
+dnl go into the auto-detect list.
+dnl
+dnl The macro defines the symbol HAVE_LIBARCHIVE if the library is found. You
+dnl should use autoheader to include a definition for this symbol in a config.h
+dnl file. Sample usage in a C/C++ source is as follows:
+dnl
+dnl   #ifdef HAVE_LIBARCHIVE
+dnl   #include <archive.h>
+dnl   #endif /* HAVE_LIBARCHIVE */
+dnl
+dnl @category InstalledPackages
+dnl @author Andre Stechert <andre@splunk.com>
+dnl @version 2006-04-20
+dnl @license GPLWithACException
+
+AC_DEFUN([ST_LIB_ARCHIVE],
+[
+#
+# Handle input from the configurer and blend with the requirements from the maintainer.
+# We go through the trouble of creating a second set of variables other than the with_foo
+# variables in order to be sure that error/corner cases have been cleaned up.
+#
+# After this statement, three trusted variable are defined.
+#
+# st_lib_archive_ENABLED will be either "yes" or "no".  its value determines whether
+# or not we bother with the rest of the checks and whether or not we export a
+# bunch of variables.
+#
+# st_lib_archive_LOCATION will be either "auto" or "defined".  if it is "auto", then
+# we try a bunch of standard locations.  if it is "defined", then we just try the value
+# provided in st_lib_archive_DIR.
+#
+# st_lib_archive_DIR will contain the string provided by the user, provided that it's
+# actually a directory.
+#
+AC_MSG_CHECKING([if libarchive is wanted])
+AC_ARG_WITH([libarchive],
+	AS_HELP_STRING([--with-libarchive=DIR], [libarchive installation directory]),
+	[if test "x$with_libarchive" = "xno" ; then
+		st_lib_archive_ENABLED=no
+	elif test "x$with_libarchive" = "xyes" ; then
+		st_lib_archive_ENABLED=yes
+		st_lib_archive_LOCATION=auto
+	else
+		st_lib_archive_ENABLED=yes
+		st_lib_archive_LOCATION=defined
+		if test -d "$with_libarchive" ; then
+			st_lib_archive_DIR="$with_libarchive"
+		else
+			AC_MSG_ERROR([$with_libarchive is not a directory])
+		fi
+	fi],
+	[if test "x$1" = "xno" ; then
+		st_lib_archive_ENABLED=no
+	elif test "x$1" = "xyes" ; then
+		st_lib_archive_ENABLED=yes
+	else
+		st_lib_archive_ENABLED=yes
+	fi])
+
+if test "$st_lib_archive_ENABLED" = "yes" ; then
+	AC_MSG_RESULT([yes])
+#
+# After this statement, one trusted variable is defined.
+#
+# st_lib_archive_LIB will be either "lib" or "lib64", depending on whether the configurer
+# specified 32, 64.  The default is "lib".
+#
+	AC_MSG_CHECKING([whether to use lib or lib64])
+	AC_ARG_WITH([libarchive-bits],
+		AS_HELP_STRING([--with-libarchive-bits=32/64], [if 64, look in /lib64 on hybrid systems]),
+		[if test "x$with_libarchive_bits" = "x32" ; then
+			st_lib_archive_LIB=lib
+		elif test "x$with_libarchive_bits" = "x64" ; then
+			st_lib_archive_LIB=lib64
+		else
+			AC_MSG_ERROR([the argument must be either 32 or 64])
+		fi],
+		[st_lib_archive_LIB=lib])
+	AC_MSG_RESULT($st_lib_archive_LIB)
+#
+# Save the environment before verifying libarchive availability
+#
+	st_lib_archive_SAVECPPFLAGS="$CPPFLAGS"
+	st_lib_archive_SAVELDFLAGS="$LDFLAGS"
+	AC_LANG_SAVE
+	AC_LANG_C
+
+	if test "x$st_lib_archive_LOCATION" = "xdefined" ; then
+		CPPFLAGS="-I$st_lib_archive_DIR/include $st_lib_archive_SAVECPPFLAGS"
+		LDFLAGS="-L$st_lib_archive_DIR/$st_lib_archive_LIB $st_lib_archive_SAVELDFLAGS"
+		AC_CHECK_LIB(archive, archive_read_new, [st_lib_archive_found_lib=yes], [st_lib_archive_found_lib=no])
+		AC_CHECK_HEADER(archive.h, [st_lib_archive_found_hdr=yes], [st_lib_archive_found_hdr=no])
+		if test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes"; then
+			LIBARCHIVE_CPPFLAGS="-I$dir/include"
+			LIBARCHIVE_LDFLAGS="-L$dir/$st_lib_archive_LIB"
+		else
+			AC_MSG_ERROR([could not find libarchive in the requested location])
+		fi
+	else
+		#
+		# These are the common install directories for Linux, FreeBSD, Solaris, and Mac.
+		#
+		for dir in /usr /usr/local /usr/sfw /opt/csw /opt/local /sw
+		do
+			if test -d "$dir" ; then
+				CPPFLAGS="-I$dir/include $st_lib_archive_SAVECPPFLAGS"
+				LDFLAGS="-L$dir/$st_lib_archive_LIB $st_lib_archive_SAVELDFLAGS"
+				AC_CHECK_LIB(archive, archive_read_new, [st_lib_archive_found_lib=yes], [st_lib_archive_found_lib=no])
+				AC_CHECK_HEADER(archive.h, [st_lib_archive_found_hdr=yes], [st_lib_archive_found_hdr=no])
+				if test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes"; then
+					LIBARCHIVE_CPPFLAGS="-I$dir/include"
+					LIBARCHIVE_LDFLAGS="-L$dir/$st_lib_archive_LIB"
+					break
+				fi
+			fi
+		done
+	fi
+
+	if test "x$st_lib_archive_found_hdr" = "xyes" && test "x$st_lib_archive_found_lib" = "xyes" ; then
+		LIBARCHIVE_LIBS="-larchive"
+		AC_DEFINE([HAVE_LIBARCHIVE], [1], [Defined to 1 if libarchive is available for use.])
+		AC_SUBST(LIBARCHIVE_LIBS)
+		AC_SUBST(LIBARCHIVE_CPPFLAGS)
+		AC_SUBST(LIBARCHIVE_LDFLAGS)
+	fi
+
+#
+# Restore the environment now that we're done.
+#
+	AC_LANG_RESTORE
+	CPPFLAGS="$st_lib_archive_SAVECPPFLAGS"
+	LDFLAGS="$st_lib_archive_SAVELDFLAGS"
+else
+	AC_MSG_RESULT([no])
+fi
+AM_CONDITIONAL(LIBARCHIVE, test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes")
+])
diff --git a/contrib/psota-benchmark/results.txt b/contrib/psota-benchmark/results.txt
new file mode 100644
index 000000000000..2d364c5558dd
--- /dev/null
+++ b/contrib/psota-benchmark/results.txt
@@ -0,0 +1,136 @@
+ODP: [Bug-tar] GNU tar, star and BSD tar speed comparison +new script
+
+Jan Psota
+Thu, 25 Oct 2007 06:51:13 -0700
+
+Latest TCP script at the bottom (3180 bytes).
+4 tests: 64bit dual core Athlon tmpfs / disk (reiserfs) - 60MB/s,
+        32bit Athlon tmpfs / disk (reiserfs) - 55MB/s
+Both machines were idle -- used for testing only.
+Tarball and extracted files were on different physical devices.
+Test data: linux 2.6.22/3 kernel sources for memory operations,
+for the other data average file size should bring enough info.
+
+2 x [...] processor means 1 processor with 2 cores (2 entries in cpuinfo).
+Archive format is set to pax (Joerg).
+Let's end with it. I only wanted to send You a new version of TCP script :-).
+
+--
+Jan Psota
+
+TCP, version 2007-10-25
+Linux 2.6.22-suspend2-r2 / Gentoo Base System release 2.0.0_rc5
+2012MB of memory, 2 x AMD Athlon(tm) 64 X2 Dual Core Processor 4200+ 2211.348 
+512 KB 4426.24 bmips
+gcc (GCC) 4.2.2 (Gentoo 4.2.2 p1.0)
+CFLAGS="-O2 -march=k8 -pipe"
+
+bsdtar: bsdtar 2.3.4 - libarchive 2.3.4
+gnutar: tar (GNU tar) 1.19
+star:   star: star 1.5a85 (x86_64-unknown-linux-gnu)
+
+best time of 5 repetitions,
+        src=linux-2.6.23, 291M in 23867 files, avg 13KB/file,
+        archive=/tmp/tcp.tar, extract to /tmp/tcptmp
+program operation       real    user    system  %CPU         speed
+bsdtar  create          0.764   0.232   0.532   99.96       370308 KB/s
+gnutar  create          0.743   0.200   0.512   95.87       380775 KB/s
+star    create          0.587   0.040   0.820   100.00      441247 KB/s
+
+bsdtar  list            0.164   0.096   0.068   99.84      1579341 KB/s
+gnutar  list            0.218   0.064   0.152   98.92      1188128 KB/s
+star    list            0.359   0.044   0.240   79.09       721481 KB/s
+
+bsdtar  extract         0.733   0.200   0.504   96.02       353358 KB/s
+gnutar  extract         0.625   0.092   0.508   96.02       414419 KB/s
+star    extract         0.875   0.096   0.980   100.00      296013 KB/s
+
+bsdtar  compare         0.001   0.000   0.000   0.00     259012000 KB/s
+gnutar  compare         0.719   0.288   0.400   95.66       360239 KB/s
+star    compare         0.695   0.224   0.636   100.00      372679 KB/s
+
+[...]
+best time of 3 repetitions,
+        src=/home, 3.2G in 7447 files, avg 554KB/file,
+        archive=/var/tcp.tar, extract to /mnt/a/tcptmp
+program operation       real    user    system  %CPU         speed
+bsdtar  create          184.680 0.552   13.365  7.53         17958 KB/s
+gnutar  create          159.240 0.256   12.417  7.95         20827 KB/s
+star    create          181.779 0.140   14.789  8.21         18203 KB/s
+
+bsdtar  list            0.053   0.032   0.016   91.41     62435471 KB/s
+gnutar  list            56.535  0.136   3.764   6.89         58531 KB/s
+star    list            56.652  0.080   5.236   9.38         58410 KB/s
+
+bsdtar  extract         78.914  0.820   15.149  20.23        41932 KB/s
+gnutar  extract         78.480  0.196   14.197  18.33        42164 KB/s
+star    extract         79.439  0.132   12.973  16.49        41655 KB/s
+
+bsdtar  compare         0.001   0.000   0.000   0.00    3309080000 KB/s
+gnutar  compare         61.771  3.464   8.905   20.02        53570 KB/s
+star    compare         57.561  1.728   9.897   20.19        57488 KB/s
+
+
+Linux 2.6.22-suspend2-smp / Gentoo Base System release 2.0.0_rc5
+504MB of memory, 1 x AMD Athlon(tm) Processor 1500.033 256 KB 3002.55 bmips
+gcc (GCC) 4.2.2 (Gentoo 4.2.2 p1.0)
+CFLAGS="-O2 -march=athlon-xp -mfpmath=sse -frename-registers -pipe"
+
+bsdtar: bsdtar 2.3.4 - libarchive 2.3.4
+gnutar: tar (GNU tar) 1.19
+star:   star: star 1.5a85 (i686-pc-linux-gnu)
+
+best time of 3 repetitions,
+        src=/usr/src/linux-2.6.22-suspend2/drivers, 119M in 5900 files,
+        avg 21KB/file, archive=/tmp/tcp.tar, extract to /tmp/tcptmp
+program operation       real    user    system  %CPU         speed
+bsdtar  create          1.329   0.192   1.132   99.63        89784 KB/s
+gnutar  create          1.223   0.124   1.092   99.46        97566 KB/s
+star    create          1.848   0.036   1.708   94.36        61372 KB/s
+
+bsdtar  list            0.167   0.060   0.108   100.00      679137 KB/s
+gnutar  list            0.161   0.040   0.124   100.00      704447 KB/s
+star    list            0.859   0.044   0.716   88.51       132032 KB/s
+
+bsdtar  extract         1.186   0.172   1.012   99.87        95629 KB/s
+gnutar  extract         1.064   0.056   1.004   99.63       106593 KB/s
+star    extract         1.920   0.088   1.724   94.40        59070 KB/s
+
+bsdtar  compare         0.002   0.000   0.000   0.00      56708000 KB/s
+gnutar  compare         0.925   0.232   0.692   99.90       122611 KB/s
+star    compare         1.569   0.376   1.096   93.79        72285 KB/s
+
+[...]
+best time of 3 repetitions,
+        src=/home/jasiu, 2.1G in 8416 files, avg 277KB/file,
+        archive=/home/j2/tcp.tar, extract to /mnt/a/tar/tcptmp
+program operation       real    user    system  %CPU         speed
+bsdtar  create          182.171 1.692   29.130  16.91        11584 KB/s
+gnutar  create          174.999 0.632   27.450  16.04        12059 KB/s
+star    create          180.004 0.360   41.795  23.41        11677 KB/s
+
+bsdtar  list            0.214   0.076   0.136   99.04      9822294 KB/s
+gnutar  list            0.210   0.076   0.136   100.00    10009385 KB/s
+star    list            43.462  0.148   18.109  42.00        48363 KB/s
+
+bsdtar  extract         94.912  4.476   31.574  37.98        22146 KB/s
+gnutar  extract         94.657  0.396   29.462  31.54        22206 KB/s
+star    extract         100.814 0.400   39.906  39.98        20849 KB/s
+
+bsdtar  compare         0.003   0.000   0.004   100.00   700657000 KB/s
+gnutar  compare         80.174  3.932   20.365  30.30        26217 KB/s
+star    compare         73.911  8.341   27.670  48.72        28439 KB/s
+
+=============================================================
+
+Note by Tim Kientzle:  The "bsdtar compare" results here are
+invalid since bsdtar does not support that operation.
+For the list numbers, note that libarchive automatically optimizes
+list operations on uncompressed tar archives on disk by using lseek()
+to skip over the bodies of entries.  GNU tar added an option to
+provide the same feature.
+
+The biggest problem with these tests is that they only
+cover uncompressed archives stored on disk.  The results for
+compressed archives and/or archives stored on tape are
+likely quite different.
diff --git a/contrib/psota-benchmark/tcp.sh b/contrib/psota-benchmark/tcp.sh
new file mode 100755
index 000000000000..3f630732be7c
--- /dev/null
+++ b/contrib/psota-benchmark/tcp.sh
@@ -0,0 +1,110 @@
+#!/bin/sh
+# tar comparison program
+# 2007-10-25 Jan Psota
+
+n=3                                     # number of repetitions
+TAR="bsdtar gnutar star"                # Tape archivers to compare
+OPT=("" "--seek" "-no-fsync")
+pax="--format=pax"                      # comment out for defaults
+OPN=(create list extract compare)       # operations
+version="2007-10-25"
+TIMEFORMAT=$'%R\t%U\t%S\t%P'
+LC_ALL=C
+
+test $# -ge 2 || {
+        echo -e "usage:\t$0 source_dir where_to_place_archive 
+[where_to_extract_it]
+
+TCP, version $version
+TCP stands for Tar Comparison Program here.
+It currently compares: BSD tar (bsdtar), GNU tar (gnutar) and star in archive
+creation, listing, extraction and archive-to-extracted comparison.
+Tcp prints out best time of n=$n repetitions.
+
+Tcp creates temporary archive named tcp.tar with $pax and some native
+(--seek/-no-fsync) options and extracts it to [\$3]/tcptmp/.
+If unset, third argument defaults to [\$2].
+After normal exit tcp removes tarball and extracted files.
+Tcp does not check filesystems destination directories are on for free space,
+so make sure there is enough space (a bit more than source_dir uses) for both:
+archive and extracted files.
+Do not use white space in arguments.
+        Jan Psota, $version"
+        exit 0
+}
+src=$1
+dst=$2/tcp.tar
+dst_path=${3:-$2}/tcptmp
+test -e $dst -o -e /tmp/tcp \
+        && { echo "$dst or /tmp/tcp exists, exiting"; exit 1; }
+mkdir $dst_path || exit 2
+
+use_times ()
+{
+        awk -F"\t" -vN=$n -vL="`du -k $dst`" -vOFS="\t" -vORS="" '
+                { if (NF==4) { printf "\t%s\t%10.1d KB/s\n", $0, ($1+0>0 ? 
+(L+0)/($1+0) : 0) } }' \
+                /tmp/tcp | sort | head -1
+        > /tmp/tcp
+}
+
+test -d $src || { echo "'$src' is not a directory"; exit 3; }
+
+# system information: type, release, memory, cpu(s), compiler and flags
+echo -e "TCP, version $version\n"`uname -sr`" / "`head -1 /etc/*-release`
+free -m | awk '/^Mem/ { printf "%dMB of memory, ", $2 }'
+test -e /proc/cpuinfo \
+        && awk -F: '/name|cache size|MHz|mips/ { if (!a) b=b $2 }
+        /^$/ { a++ } END { print a" x"b" bmips" }' /proc/cpuinfo
+test -e /etc/gentoo-release \
+        && gcc --version | head -1 && grep ^CFLAGS /etc/make.conf
+
+# tar versions
+t=
+echo
+for tar in $TAR; do 
+	if which $tar &> /dev/null; then
+		t="$t $tar";
+		echo -ne "$tar:\t"; $tar --version | head -1; 
+	fi
+done
+
+TAR="$t"
+
+echo -e "\nbest time of $n repetitions,\n"\
+"       src=$src, "\
+`du -sh $src | awk '{print $1}'`" in "`find $src | wc -l`" files, "\
+"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc -l`))"KB/file,\n"\
+"       archive=$dst, extract to $dst_path"
+
+echo -e "program\toperation\treal\tuser\tsystem\t%CPU\t     speed"
+> /tmp/tcp
+let op_num=0
+for op in "cf $dst $pax -C $src ." "tf $dst" "xf $dst -C $dst_path" \
+        "f $dst -C $dst_path --diff"; do
+        let tar_num=0
+        for tar in $TAR; do
+                echo -en "$tar\t${OPN[op_num]}\t"
+                for ((i=1; i<=$n; i++)); do
+                        echo $op | grep -q ^cf && rm -f $dst
+                        echo $op | grep -q ^xf &&
+                                { chmod -R u+w $dst_path
+                                rm -rf $dst_path; mkdir $dst_path; }
+                        sync
+                        if echo $op | grep -q ^f; then  # op == compare
+                                time $tar $op ${OPT[$tar_num]} > /dev/null
+                        else    # op in (create | list | extract)
+                                time $tar $op ${OPT[$tar_num]} > /dev/null \
+                                        || break 3
+                        fi 2>> /tmp/tcp
+                done
+                use_times
+                let tar_num++
+        done
+        let op_num++
+        echo
+done
+rm -rf $dst_path $dst
+echo
+cat /tmp/tcp
+rm -f /tmp/tcp
diff --git a/contrib/shar/Makefile b/contrib/shar/Makefile
new file mode 100644
index 000000000000..3bd94d4192cb
--- /dev/null
+++ b/contrib/shar/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+PROG=	shar
+SRCS=	shar.c tree.c
+
+WARNS?=	6
+
+DPADD=	${LIBARCHIVE}
+LDADD=	-larchive
+
+LINKS=	${BINDIR}/shar
+MLINKS=	shar.1
+
+.include <bsd.prog.mk>
diff --git a/contrib/shar/shar.1 b/contrib/shar/shar.1
new file mode 100644
index 000000000000..e3152f299ebe
--- /dev/null
+++ b/contrib/shar/shar.1
@@ -0,0 +1,128 @@
+.\" Copyright (c) 1990, 1993
+.\"	The Regents of the University of California.  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.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)shar.1	8.1 (Berkeley) 6/6/93
+.\" $FreeBSD$
+.\"
+.Dd April 17, 2008
+.Dt SHAR 1
+.Os
+.Sh NAME
+.Nm shar
+.Nd create a shell archive of files
+.Sh SYNOPSIS
+.Nm
+.Op Fl br
+.Op Fl o Ar archive-file
+.Ar
+.Sh DESCRIPTION
+The
+.Nm
+command writes a
+.Xr sh 1
+shell script which will recreate the file hierarchy specified by the command
+line operands.
+.Pp
+The
+.Nm
+command is normally used for distributing files by
+.Xr ftp 1
+or
+.Xr mail 1 .
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl b
+Use an alternative binary format.  Content of files will be uuencoded.
+This option should be used to archive binary files correctly.
+In this mode also file permissions will be stored to the archive.
+uudecode(1) is needed to extract archives created with this option.
+.It Fl o Ar archive-file
+Redirect output to
+.Ar archive-file .
+.It Fl r
+If
+.Ar file
+given on command line is a directory the entire subtree will be archived.
+Symbolic links given on command line are followed.  Other symbolic links will
+be archived as such.
+.El
+.Sh EXAMPLES
+To create a shell archive of the program
+.Xr ls 1
+and mail it to Rick:
+.Bd -literal -offset indent
+cd ls
+shar -r . \&| mail -s "ls source" rick
+.Ed
+.Pp
+To recreate the program directory:
+.Bd -literal -offset indent
+mkdir ls
+cd ls
+\&...
+<delete header lines and examine mailed archive>
+\&...
+sh archive
+.Ed
+.Sh SEE ALSO
+.Xr compress 1 ,
+.Xr mail 1 ,
+.Xr tar 1 ,
+.Xr uuencode 1 ,
+.Xr uuencode 5
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.4 .
+This is a re-implementation based on the libarchive(3) library.
+.Sh BUGS
+The
+.Nm
+command makes no provisions for hard links.
+.Pp
+Files containing magic characters or files without a newline ('\\n') as the
+last character are not handled correctly with the default format.  Use the -b
+option for binary files.
+.Pp
+It is easy to insert trojan horses into
+.Nm
+files.
+It is strongly recommended that all shell archive files be examined
+before running them through
+.Xr sh 1 .
+Archives produced using this implementation of
+.Nm
+may be easily examined with the command:
+.Bd -literal -offset indent
+egrep -v '^[X#]' shar.file
+.Ed
diff --git a/contrib/shar/shar.c b/contrib/shar/shar.c
new file mode 100644
index 000000000000..6d5c206e2a51
--- /dev/null
+++ b/contrib/shar/shar.c
@@ -0,0 +1,314 @@
+/*-
+ * Copyright (c) 2008 Jaakko Heinonen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifdef __FBSDID
+__FBSDID("$FreeBSD$");
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <archive.h>
+#include <archive_entry.h>
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "tree.h"
+
+/* command line options */
+static int	b_opt;	/* use alternative shar binary format */
+static int	r_opt;	/* recurse into subdirectories */
+static char	*o_arg;	/* output file name */
+
+static void
+usage(void)
+{
+	fprintf(stderr, "Usage: shar [-br] [-o filename] file ...\n");
+	exit(EX_USAGE);
+}
+
+/*
+ * Initialize archive structure and create a shar archive.
+ */
+static struct archive *
+shar_create(void)
+{
+	struct archive *a;
+
+	if ((a = archive_write_new()) == NULL)
+		errx(EXIT_FAILURE, "%s", archive_error_string(a));
+
+	if (b_opt)
+		archive_write_set_format_shar_dump(a);
+	else
+		archive_write_set_format_shar(a);
+	archive_write_set_compression_none(a);
+
+	if (archive_write_open_filename(a, o_arg) != ARCHIVE_OK)
+		errx(EX_CANTCREAT, "%s", archive_error_string(a));
+
+	return (a);
+}
+
+/* buffer for file data */
+static char buffer[32768];
+
+/*
+ * Write file data to an archive entry.
+ */
+static int
+shar_write_entry_data(struct archive *a, const int fd)
+{
+	ssize_t bytes_read, bytes_written;
+
+	assert(a != NULL);
+	assert(fd >= 0);
+
+	bytes_read = read(fd, buffer, sizeof(buffer));
+	while (bytes_read != 0) {
+		if (bytes_read < 0) {
+			archive_set_error(a, errno, "Read failed");
+			return (ARCHIVE_WARN);
+		}
+		bytes_written = archive_write_data(a, buffer, bytes_read);
+		if (bytes_written < 0)
+			return (ARCHIVE_WARN);
+		bytes_read = read(fd, buffer, sizeof(buffer));
+	}
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Write a file to the archive. We have special handling for symbolic links.
+ */
+static int
+shar_write_entry(struct archive *a, const char *pathname, const char *accpath,
+    const struct stat *st)
+{
+	struct archive_entry *entry;
+	int fd = -1;
+	int ret = ARCHIVE_OK;
+
+	assert(a != NULL);
+	assert(pathname != NULL);
+	assert(accpath != NULL);
+	assert(st != NULL);
+
+	entry = archive_entry_new();
+
+	if (S_ISREG(st->st_mode) && st->st_size > 0) {
+		/* regular file */
+		if ((fd = open(accpath, O_RDONLY)) == -1) {
+			warn("%s", accpath);
+			ret = ARCHIVE_WARN;
+			goto out;
+		}
+	} else if (S_ISLNK(st->st_mode)) {
+		/* symbolic link */
+		char lnkbuff[PATH_MAX + 1];
+		int lnklen;
+		if ((lnklen = readlink(accpath, lnkbuff, PATH_MAX)) == -1) {
+			warn("%s", accpath);
+			ret = ARCHIVE_WARN;
+			goto out;
+		}
+		lnkbuff[lnklen] = '\0';
+		archive_entry_set_symlink(entry, lnkbuff);
+	}
+	archive_entry_copy_stat(entry, st);
+	archive_entry_set_pathname(entry, pathname);
+	if (!S_ISREG(st->st_mode) || st->st_size == 0)
+		archive_entry_set_size(entry, 0);
+	if (archive_write_header(a, entry) != ARCHIVE_OK) {
+		warnx("%s: %s", pathname, archive_error_string(a));
+		ret = ARCHIVE_WARN;
+		goto out;
+	}
+	if (fd >= 0) {
+		if ((ret = shar_write_entry_data(a, fd)) != ARCHIVE_OK)
+			warnx("%s: %s", accpath, archive_error_string(a));
+	}
+out:
+	archive_entry_free(entry);
+	if (fd >= 0)
+		close(fd);
+
+	return (ret);
+}
+
+/*
+ * Write singe path to the archive. The path can be a regular file, directory
+ * or device. Symbolic links are followed.
+ */
+static int
+shar_write_path(struct archive *a, const char *pathname)
+{
+	struct stat st;
+
+	assert(a != NULL);
+	assert(pathname != NULL);
+
+	if ((stat(pathname, &st)) == -1) {
+		warn("%s", pathname);
+		return (ARCHIVE_WARN);
+	}
+
+	return (shar_write_entry(a, pathname, pathname, &st));
+}
+
+/*
+ * Write tree to the archive. If pathname is a symbolic link it will be
+ * followed. Other symbolic links are stored as such to the archive.
+ */
+static int
+shar_write_tree(struct archive *a, const char *pathname)
+{
+	struct tree *t;
+	const struct stat *lst, *st;
+	int error = 0;
+	int tree_ret;
+	int first;
+
+	assert(a != NULL);
+	assert(pathname != NULL);
+
+	t = tree_open(pathname);
+	for (first = 1; (tree_ret = tree_next(t)); first = 0) {
+		if (tree_ret == TREE_ERROR_DIR) {
+			warnx("%s: %s", tree_current_path(t),
+			    strerror(tree_errno(t)));
+			error = 1;
+			continue;
+		} else if (tree_ret != TREE_REGULAR)
+			continue;
+		if ((lst = tree_current_lstat(t)) == NULL) {
+			warn("%s", tree_current_path(t));
+			error = 1;
+			continue;
+		}
+		/*
+		 * If the symlink was given on command line then
+		 * follow it rather than write it as symlink.
+		 */
+		if (first && S_ISLNK(lst->st_mode)) {
+			if ((st = tree_current_stat(t)) == NULL) {
+				warn("%s", tree_current_path(t));
+				error = 1;
+				continue;
+			}
+		} else
+			st = lst;
+
+		if (shar_write_entry(a, tree_current_path(t),
+		    tree_current_access_path(t), st) != ARCHIVE_OK)
+			error = 1;
+
+		tree_descend(t);
+	}
+
+	tree_close(t);
+
+	return ((error != 0) ? ARCHIVE_WARN : ARCHIVE_OK);
+}
+
+/*
+ * Create a shar archive and write files/trees into it.
+ */
+static int
+shar_write(char **fn, size_t nfn)
+{
+	struct archive *a;
+	size_t i;
+	int error = 0;
+
+	assert(fn != NULL);
+	assert(nfn > 0);
+
+	a = shar_create();
+
+	for (i = 0; i < nfn; i++) {
+		if (r_opt) {
+			if (shar_write_tree(a, fn[i]) !=  ARCHIVE_OK)
+				error = 1;
+		} else {
+			if (shar_write_path(a, fn[i]) != ARCHIVE_OK)
+				error = 1;
+		}
+	}
+
+	if (archive_write_free(a) != ARCHIVE_OK)
+		errx(EXIT_FAILURE, "%s", archive_error_string(a));
+
+	if (error != 0)
+		warnx("Error exit delayed from previous errors.");
+
+	return (error);
+}
+
+int
+main(int argc, char **argv)
+{
+	int opt;
+
+	while ((opt = getopt(argc, argv, "bro:")) != -1) {
+		switch (opt) {
+		case 'b':
+			b_opt = 1;
+			break;
+		case 'o':
+			o_arg = optarg;
+			break;
+		case 'r':
+			r_opt = 1;
+			break;
+		default:
+			usage();
+			/* NOTREACHED */
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	if(argc < 1)
+		usage();
+
+	if (shar_write(argv, argc) != 0)
+		exit(EXIT_FAILURE);
+	else
+		exit(EXIT_SUCCESS);
+	/* NOTREACHED */
+}
+
diff --git a/contrib/shar/tree.c b/contrib/shar/tree.c
new file mode 100644
index 000000000000..d5a04abf5f4b
--- /dev/null
+++ b/contrib/shar/tree.c
@@ -0,0 +1,542 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * 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 "tree_config.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.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
+
+#include "tree.h"
+
+/*
+ * TODO:
+ *    1) Loop checking.
+ *    3) Arbitrary logical traversals by closing/reopening intermediate fds.
+ */
+
+struct tree_entry {
+	struct tree_entry *next;
+	struct tree_entry *parent;
+	char *name;
+	size_t dirname_length;
+	dev_t dev;
+	ino_t ino;
+	int fd;
+	int flags;
+};
+
+/* Definitions for tree_entry.flags bitmap. */
+#define	isDir 1 /* This entry is a regular directory. */
+#define	isDirLink 2 /* This entry is a symbolic link to a directory. */
+#define	needsPreVisit 4 /* This entry needs to be previsited. */
+#define	needsPostVisit 8 /* This entry needs to be postvisited. */
+
+/*
+ * Local data for this package.
+ */
+struct tree {
+	struct tree_entry	*stack;
+	struct tree_entry	*current;
+	DIR	*d;
+	int	 initialDirFd;
+	int	 flags;
+	int	 visit_type;
+	int	 tree_errno; /* Error code from last failed operation. */
+
+	char	*buff;
+	const char	*basename;
+	size_t	 buff_length;
+	size_t	 path_length;
+	size_t	 dirname_length;
+
+	int	 depth;
+	int	 openCount;
+	int	 maxOpenCount;
+
+	struct stat	lst;
+	struct stat	st;
+};
+
+/* Definitions for tree.flags bitmap. */
+#define needsReturn 8  /* Marks first entry as not having been returned yet. */
+#define hasStat 16  /* The st entry is set. */
+#define hasLstat 32 /* The lst entry is set. */
+
+
+#ifdef HAVE_DIRENT_D_NAMLEN
+/* BSD extension; avoids need for a strlen() call. */
+#define D_NAMELEN(dp)	(dp)->d_namlen
+#else
+#define D_NAMELEN(dp)	(strlen((dp)->d_name))
+#endif
+
+#if 0
+#include <stdio.h>
+void
+tree_dump(struct tree *t, FILE *out)
+{
+	struct tree_entry *te;
+
+	fprintf(out, "\tdepth: %d\n", t->depth);
+	fprintf(out, "\tbuff: %s\n", t->buff);
+	fprintf(out, "\tpwd: "); fflush(stdout); system("pwd");
+	fprintf(out, "\taccess: %s\n", t->basename);
+	fprintf(out, "\tstack:\n");
+	for (te = t->stack; te != NULL; te = te->next) {
+		fprintf(out, "\t\tte->name: %s%s%s\n", te->name,
+		    te->flags & needsPreVisit ? "" : " *",
+		    t->current == te ? " (current)" : "");
+	}
+}
+#endif
+
+/*
+ * Add a directory path to the current stack.
+ */
+static void
+tree_push(struct tree *t, const char *path)
+{
+	struct tree_entry *te;
+
+	te = malloc(sizeof(*te));
+	memset(te, 0, sizeof(*te));
+	te->next = t->stack;
+	t->stack = te;
+	te->fd = -1;
+	te->name = strdup(path);
+	te->flags = needsPreVisit | needsPostVisit;
+	te->dirname_length = t->dirname_length;
+}
+
+/*
+ * Append a name to the current path.
+ */
+static void
+tree_append(struct tree *t, const char *name, size_t name_length)
+{
+	char *p;
+
+	if (t->buff != NULL)
+		t->buff[t->dirname_length] = '\0';
+	/* Strip trailing '/' from name, unless entire name is "/". */
+	while (name_length > 1 && name[name_length - 1] == '/')
+		name_length--;
+
+	/* Resize pathname buffer as needed. */
+	while (name_length + 1 + t->dirname_length >= t->buff_length) {
+		t->buff_length *= 2;
+		if (t->buff_length < 1024)
+			t->buff_length = 1024;
+		t->buff = realloc(t->buff, t->buff_length);
+	}
+	p = t->buff + t->dirname_length;
+	t->path_length = t->dirname_length + name_length;
+	/* Add a separating '/' if it's needed. */
+	if (t->dirname_length > 0 && p[-1] != '/') {
+		*p++ = '/';
+		t->path_length ++;
+	}
+	strncpy(p, name, name_length);
+	p[name_length] = '\0';
+	t->basename = p;
+}
+
+/*
+ * Open a directory tree for traversal.
+ */
+struct tree *
+tree_open(const char *path)
+{
+	struct tree *t;
+
+	t = malloc(sizeof(*t));
+	memset(t, 0, sizeof(*t));
+	tree_append(t, path, strlen(path));
+	t->initialDirFd = open(".", O_RDONLY);
+	/*
+	 * During most of the traversal, items are set up and then
+	 * returned immediately from tree_next().  That doesn't work
+	 * for the very first entry, so we set a flag for this special
+	 * case.
+	 */
+	t->flags = needsReturn;
+	return (t);
+}
+
+/*
+ * We've finished a directory; ascend back to the parent.
+ */
+static void
+tree_ascend(struct tree *t)
+{
+	struct tree_entry *te;
+
+	te = t->stack;
+	t->depth--;
+	if (te->flags & isDirLink) {
+		fchdir(te->fd);
+		close(te->fd);
+		t->openCount--;
+	} else {
+		chdir("..");
+	}
+}
+
+/*
+ * Pop the working stack.
+ */
+static void
+tree_pop(struct tree *t)
+{
+	struct tree_entry *te;
+
+	t->buff[t->dirname_length] = '\0';
+	if (t->stack == t->current && t->current != NULL)
+		t->current = t->current->parent;
+	te = t->stack;
+	t->stack = te->next;
+	t->dirname_length = te->dirname_length;
+	t->basename = t->buff + t->dirname_length;
+	/* Special case: starting dir doesn't skip leading '/'. */
+	if (t->dirname_length > 0)
+		t->basename++;
+	free(te->name);
+	free(te);
+}
+
+/*
+ * Get the next item in the tree traversal.
+ */
+int
+tree_next(struct tree *t)
+{
+	struct dirent *de = NULL;
+
+	/* Handle the startup case by returning the initial entry. */
+	if (t->flags & needsReturn) {
+		t->flags &= ~needsReturn;
+		return (t->visit_type = TREE_REGULAR);
+	}
+
+	while (t->stack != NULL) {
+		/* If there's an open dir, get the next entry from there. */
+		while (t->d != NULL) {
+			de = readdir(t->d);
+			if (de == NULL) {
+				closedir(t->d);
+				t->d = NULL;
+			} else if (de->d_name[0] == '.'
+			    && de->d_name[1] == '\0') {
+				/* Skip '.' */
+			} else if (de->d_name[0] == '.'
+			    && de->d_name[1] == '.'
+			    && de->d_name[2] == '\0') {
+				/* Skip '..' */
+			} else {
+				/*
+				 * Append the path to the current path
+				 * and return it.
+				 */
+				tree_append(t, de->d_name, D_NAMELEN(de));
+				t->flags &= ~hasLstat;
+				t->flags &= ~hasStat;
+				return (t->visit_type = TREE_REGULAR);
+			}
+		}
+
+		/* If the current dir needs to be visited, set it up. */
+		if (t->stack->flags & needsPreVisit) {
+			t->current = t->stack;
+			tree_append(t, t->stack->name, strlen(t->stack->name));
+			t->stack->flags &= ~needsPreVisit;
+			/* If it is a link, set up fd for the ascent. */
+			if (t->stack->flags & isDirLink) {
+				t->stack->fd = open(".", O_RDONLY);
+				t->openCount++;
+				if (t->openCount > t->maxOpenCount)
+					t->maxOpenCount = t->openCount;
+			}
+			t->dirname_length = t->path_length;
+			if (chdir(t->stack->name) != 0) {
+				/* chdir() failed; return error */
+				tree_pop(t);
+				t->tree_errno = errno;
+				return (t->visit_type = TREE_ERROR_DIR);
+			}
+			t->depth++;
+			t->d = opendir(".");
+			if (t->d == NULL) {
+				tree_ascend(t); /* Undo "chdir" */
+				tree_pop(t);
+				t->tree_errno = errno;
+				return (t->visit_type = TREE_ERROR_DIR);
+			}
+			t->flags &= ~hasLstat;
+			t->flags &= ~hasStat;
+			t->basename = ".";
+			return (t->visit_type = TREE_POSTDESCENT);
+		}
+
+		/* We've done everything necessary for the top stack entry. */
+		if (t->stack->flags & needsPostVisit) {
+			tree_ascend(t);
+			tree_pop(t);
+			t->flags &= ~hasLstat;
+			t->flags &= ~hasStat;
+			return (t->visit_type = TREE_POSTASCENT);
+		}
+	}
+	return (t->visit_type = 0);
+}
+
+/*
+ * Return error code.
+ */
+int
+tree_errno(struct tree *t)
+{
+	return (t->tree_errno);
+}
+
+/*
+ * Called by the client to mark the directory just returned from
+ * tree_next() as needing to be visited.
+ */
+void
+tree_descend(struct tree *t)
+{
+	if (t->visit_type != TREE_REGULAR)
+		return;
+
+	if (tree_current_is_physical_dir(t)) {
+		tree_push(t, t->basename);
+		t->stack->flags |= isDir;
+	} else if (tree_current_is_dir(t)) {
+		tree_push(t, t->basename);
+		t->stack->flags |= isDirLink;
+	}
+}
+
+/*
+ * Get the stat() data for the entry just returned from tree_next().
+ */
+const struct stat *
+tree_current_stat(struct tree *t)
+{
+	if (!(t->flags & hasStat)) {
+		if (stat(t->basename, &t->st) != 0)
+			return NULL;
+		t->flags |= hasStat;
+	}
+	return (&t->st);
+}
+
+/*
+ * Get the lstat() data for the entry just returned from tree_next().
+ */
+const struct stat *
+tree_current_lstat(struct tree *t)
+{
+	if (!(t->flags & hasLstat)) {
+		if (lstat(t->basename, &t->lst) != 0)
+			return NULL;
+		t->flags |= hasLstat;
+	}
+	return (&t->lst);
+}
+
+/*
+ * Test whether current entry is a dir or link to a dir.
+ */
+int
+tree_current_is_dir(struct tree *t)
+{
+	const struct stat *st;
+
+	/*
+	 * If we already have lstat() info, then try some
+	 * cheap tests to determine if this is a dir.
+	 */
+	if (t->flags & hasLstat) {
+		/* If lstat() says it's a dir, it must be a dir. */
+		if (S_ISDIR(tree_current_lstat(t)->st_mode))
+			return 1;
+		/* Not a dir; might be a link to a dir. */
+		/* If it's not a link, then it's not a link to a dir. */
+		if (!S_ISLNK(tree_current_lstat(t)->st_mode))
+			return 0;
+		/*
+		 * It's a link, but we don't know what it's a link to,
+		 * so we'll have to use stat().
+		 */
+	}
+
+	st = tree_current_stat(t);
+	/* If we can't stat it, it's not a dir. */
+	if (st == NULL)
+		return 0;
+	/* Use the definitive test.  Hopefully this is cached. */
+	return (S_ISDIR(st->st_mode));
+}
+
+/*
+ * Test whether current entry is a physical directory.  Usually, we
+ * already have at least one of stat() or lstat() in memory, so we
+ * use tricks to try to avoid an extra trip to the disk.
+ */
+int
+tree_current_is_physical_dir(struct tree *t)
+{
+	const struct stat *st;
+
+	/*
+	 * If stat() says it isn't a dir, then it's not a dir.
+	 * If stat() data is cached, this check is free, so do it first.
+	 */
+	if ((t->flags & hasStat)
+	    && (!S_ISDIR(tree_current_stat(t)->st_mode)))
+		return 0;
+
+	/*
+	 * Either stat() said it was a dir (in which case, we have
+	 * to determine whether it's really a link to a dir) or
+	 * stat() info wasn't available.  So we use lstat(), which
+	 * hopefully is already cached.
+	 */
+
+	st = tree_current_lstat(t);
+	/* If we can't stat it, it's not a dir. */
+	if (st == NULL)
+		return 0;
+	/* Use the definitive test.  Hopefully this is cached. */
+	return (S_ISDIR(st->st_mode));
+}
+
+/*
+ * Test whether current entry is a symbolic link.
+ */
+int
+tree_current_is_physical_link(struct tree *t)
+{
+	const struct stat *st = tree_current_lstat(t);
+	if (st == NULL)
+		return 0;
+	return (S_ISLNK(st->st_mode));
+}
+
+/*
+ * Return the access path for the entry just returned from tree_next().
+ */
+const char *
+tree_current_access_path(struct tree *t)
+{
+	return (t->basename);
+}
+
+/*
+ * Return the full path for the entry just returned from tree_next().
+ */
+const char *
+tree_current_path(struct tree *t)
+{
+	return (t->buff);
+}
+
+/*
+ * Return the length of the path for the entry just returned from tree_next().
+ */
+size_t
+tree_current_pathlen(struct tree *t)
+{
+	return (t->path_length);
+}
+
+/*
+ * Return the nesting depth of the entry just returned from tree_next().
+ */
+int
+tree_current_depth(struct tree *t)
+{
+	return (t->depth);
+}
+
+/*
+ * Terminate the traversal and release any resources.
+ */
+void
+tree_close(struct tree *t)
+{
+	/* Release anything remaining in the stack. */
+	while (t->stack != NULL)
+		tree_pop(t);
+	if (t->buff)
+		free(t->buff);
+	/* chdir() back to where we started. */
+	if (t->initialDirFd >= 0) {
+		fchdir(t->initialDirFd);
+		close(t->initialDirFd);
+		t->initialDirFd = -1;
+	}
+	free(t);
+}
diff --git a/contrib/shar/tree.h b/contrib/shar/tree.h
new file mode 100644
index 000000000000..ff38f5346c1c
--- /dev/null
+++ b/contrib/shar/tree.h
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*-
+ * A set of routines for traversing directory trees.
+ * Similar in concept to the fts library, but with a few
+ * important differences:
+ *    * Uses less memory.  In particular, fts stores an entire directory
+ *      in memory at a time.  This package only keeps enough subdirectory
+ *      information in memory to track the traversal.  Information
+ *      about non-directories is discarded as soon as possible.
+ *    * Supports very deep logical traversals.  The fts package
+ *      uses "non-chdir" approach for logical traversals.  This
+ *      package does use a chdir approach for logical traversals
+ *      and can therefore handle pathnames much longer than
+ *      PATH_MAX.
+ *    * Supports deep physical traversals "out of the box."
+ *      Due to the memory optimizations above, there's no need to
+ *      limit dir names to 32k.
+ */
+
+#include <sys/stat.h>
+#include <stdio.h>
+
+struct tree;
+
+/* Initiate/terminate a tree traversal. */
+struct tree *tree_open(const char * /* pathname */);
+void tree_close(struct tree *);
+
+/*
+ * tree_next() returns Zero if there is no next entry, non-zero if there is.
+ * Note that directories are potentially visited three times.  The first
+ * time as "regular" file.  If tree_descend() is invoked at that time,
+ * the directory is added to a work list and will be visited two more
+ * times:  once just after descending into the directory and again
+ * just after ascending back to the parent.
+ *
+ * TREE_ERROR is returned if the descent failed (because the
+ * directory couldn't be opened, for instance).  This is returned
+ * instead of TREE_PREVISIT/TREE_POSTVISIT.
+ */
+#define	TREE_REGULAR	1
+#define	TREE_POSTDESCENT	2
+#define	TREE_POSTASCENT	3
+#define	TREE_ERROR_DIR	-1
+int tree_next(struct tree *);
+
+int tree_errno(struct tree *);
+
+/*
+ * Request that current entry be visited.  If you invoke it on every
+ * directory, you'll get a physical traversal.  This is ignored if the
+ * current entry isn't a directory or a link to a directory.  So, if
+ * you invoke this on every returned path, you'll get a full logical
+ * traversal.
+ */
+void tree_descend(struct tree *);
+
+/*
+ * Return information about the current entry.
+ */
+
+int tree_current_depth(struct tree *);
+/*
+ * The current full pathname, length of the full pathname,
+ * and a name that can be used to access the file.
+ * Because tree does use chdir extensively, the access path is
+ * almost never the same as the full current path.
+ */
+const char *tree_current_path(struct tree *);
+size_t tree_current_pathlen(struct tree *);
+const char *tree_current_access_path(struct tree *);
+/*
+ * Request the lstat() or stat() data for the current path.  Since the
+ * tree package needs to do some of this anyway, and caches the
+ * results, you should take advantage of it here if you need it rather
+ * than make a redundant stat() or lstat() call of your own.
+ */
+const struct stat *tree_current_stat(struct tree *);
+const struct stat *tree_current_lstat(struct tree *);
+/* The following tests may use mechanisms much faster than stat()/lstat(). */
+/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
+int tree_current_is_physical_dir(struct tree *);
+/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
+int tree_current_is_physical_link(struct tree *);
+/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
+int tree_current_is_dir(struct tree *);
+
+/* For testing/debugging: Dump the internal status to the given filehandle. */
+void tree_dump(struct tree *, FILE *);
diff --git a/contrib/shar/tree_config.h b/contrib/shar/tree_config.h
new file mode 100644
index 000000000000..8dfd90baf685
--- /dev/null
+++ b/contrib/shar/tree_config.h
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef TREE_CONFIG_H_INCLUDED
+#define	TREE_CONFIG_H_INCLUDED
+
+#if defined(PLATFORM_CONFIG_H)
+/*
+ * Use hand-built config.h in environments that need it.
+ */
+#include PLATFORM_CONFIG_H
+#elif defined(HAVE_CONFIG_H)
+/*
+ * Most POSIX platforms use the 'configure' script to build config.h
+ */
+#include "../config.h"
+#elif defined(__FreeBSD__)
+/*
+ * Built-in definitions for FreeBSD.
+ */
+#define	HAVE_DIRENT_D_NAMLEN 1
+#define	HAVE_DIRENT_H 1
+#define	HAVE_ERRNO_H 1
+#define	HAVE_FCNTL_H 1
+#define	HAVE_LIBARCHIVE 1
+#define	HAVE_STDLIB_H 1
+#define	HAVE_STRING_H 1
+#define	HAVE_SYS_STAT_H 1
+#define	HAVE_UNISTD_H 1
+#else
+/*
+ * Warn if there's no platform configuration.
+ */
+#error Oops: No config.h and no built-in configuration in bsdtar_platform.h.
+#endif /* !HAVE_CONFIG_H */
+
+/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>  /* For __FBSDID */
+#else
+/* Just leaving this macro replacement empty leads to a dangling semicolon. */
+#define	__FBSDID(a)     struct _undefined_hack
+#endif
+
+#ifdef HAVE_LIBARCHIVE
+/* If we're using the platform libarchive, include system headers. */
+#include <archive.h>
+#include <archive_entry.h>
+#else
+/* Otherwise, include user headers. */
+#include "archive.h"
+#include "archive_entry.h"
+#endif
+
+#endif /* !TREE_CONFIG_H_INCLUDED */
diff --git a/contrib/untar.c b/contrib/untar.c
new file mode 100644
index 000000000000..c4cc2bf9bea2
--- /dev/null
+++ b/contrib/untar.c
@@ -0,0 +1,225 @@
+/*
+ * "untar" is an extremely simple tar extractor:
+ *  * A single C source file, so it should be easy to compile
+ *    and run on any system with a C compiler.
+ *  * Extremely portable standard C.  The only non-ANSI function
+ *    used is mkdir().
+ *  * Reads basic ustar tar archives.
+ *  * Does not require libarchive or any other special library.
+ *
+ * To compile: cc -o untar untar.c
+ *
+ * Usage:  untar <archive>
+ *
+ * In particular, this program should be sufficient to extract the
+ * distribution for libarchive, allowing people to bootstrap
+ * libarchive on systems that do not already have a tar program.
+ *
+ * To unpack libarchive-x.y.z.tar.gz:
+ *    * gunzip libarchive-x.y.z.tar.gz
+ *    * untar libarchive-x.y.z.tar
+ *
+ * Written by Tim Kientzle, March 2009.
+ *
+ * Released into the public domain.
+ */
+
+/* These are all highly standard and portable headers. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* This is for mkdir(); this may need to be changed for some platforms. */
+#include <sys/stat.h>  /* For mkdir() */
+
+/* Parse an octal number, ignoring leading and trailing nonsense. */
+static int
+parseoct(const char *p, size_t n)
+{
+	int i = 0;
+
+	while ((*p < '0' || *p > '7') && n > 0) {
+		++p;
+		--n;
+	}
+	while (*p >= '0' && *p <= '7' && n > 0) {
+		i *= 8;
+		i += *p - '0';
+		++p;
+		--n;
+	}
+	return (i);
+}
+
+/* Returns true if this is 512 zero bytes. */
+static int
+is_end_of_archive(const char *p)
+{
+	int n;
+	for (n = 511; n >= 0; --n)
+		if (p[n] != '\0')
+			return (0);
+	return (1);
+}
+
+/* Create a directory, including parent directories as necessary. */
+static void
+create_dir(char *pathname, int mode)
+{
+	char *p;
+	int r;
+
+	/* Strip trailing '/' */
+	if (pathname[strlen(pathname) - 1] == '/')
+		pathname[strlen(pathname) - 1] = '\0';
+
+	/* Try creating the directory. */
+	r = mkdir(pathname, mode);
+
+	if (r != 0) {
+		/* On failure, try creating parent directory. */
+		p = strrchr(pathname, '/');
+		if (p != NULL) {
+			*p = '\0';
+			create_dir(pathname, 0755);
+			*p = '/';
+			r = mkdir(pathname, mode);
+		}
+	}
+	if (r != 0)
+		fprintf(stderr, "Could not create directory %s\n", pathname);
+}
+
+/* Create a file, including parent directory as necessary. */
+static FILE *
+create_file(char *pathname, int mode)
+{
+	FILE *f;
+	f = fopen(pathname, "w+");
+	if (f == NULL) {
+		/* Try creating parent dir and then creating file. */
+		char *p = strrchr(pathname, '/');
+		if (p != NULL) {
+			*p = '\0';
+			create_dir(pathname, 0755);
+			*p = '/';
+			f = fopen(pathname, "w+");
+		}
+	}
+	return (f);
+}
+
+/* Verify the tar checksum. */
+static int
+verify_checksum(const char *p)
+{
+	int n, u = 0;
+	for (n = 0; n < 512; ++n) {
+		if (n < 148 || n > 155)
+			/* Standard tar checksum adds unsigned bytes. */
+			u += ((unsigned char *)p)[n];
+		else
+			u += 0x20;
+
+	}
+	return (u == parseoct(p + 148, 8));
+}
+
+/* Extract a tar archive. */
+static void
+untar(FILE *a, const char *path)
+{
+	char buff[512];
+	FILE *f = NULL;
+	size_t bytes_read;
+	int filesize;
+
+	printf("Extracting from %s\n", path);
+	for (;;) {
+		bytes_read = fread(buff, 1, 512, a);
+		if (bytes_read < 512) {
+			fprintf(stderr,
+			    "Short read on %s: expected 512, got %d\n",
+			    path, (int)bytes_read);
+			return;
+		}
+		if (is_end_of_archive(buff)) {
+			printf("End of %s\n", path);
+			return;
+		}
+		if (!verify_checksum(buff)) {
+			fprintf(stderr, "Checksum failure\n");
+			return;
+		}
+		filesize = parseoct(buff + 124, 12);
+		switch (buff[156]) {
+		case '1':
+			printf(" Ignoring hardlink %s\n", buff);
+			break;
+		case '2':
+			printf(" Ignoring symlink %s\n", buff);
+			break;
+		case '3':
+			printf(" Ignoring character device %s\n", buff);
+				break;
+		case '4':
+			printf(" Ignoring block device %s\n", buff);
+			break;
+		case '5':
+			printf(" Extracting dir %s\n", buff);
+			create_dir(buff, parseoct(buff + 100, 8));
+			filesize = 0;
+			break;
+		case '6':
+			printf(" Ignoring FIFO %s\n", buff);
+			break;
+		default:
+			printf(" Extracting file %s\n", buff);
+			f = create_file(buff, parseoct(buff + 100, 8));
+			break;
+		}
+		while (filesize > 0) {
+			bytes_read = fread(buff, 1, 512, a);
+			if (bytes_read < 512) {
+				fprintf(stderr,
+				    "Short read on %s: Expected 512, got %d\n",
+				    path, (int)bytes_read);
+				return;
+			}
+			if (filesize < 512)
+				bytes_read = filesize;
+			if (f != NULL) {
+				if (fwrite(buff, 1, bytes_read, f)
+				    != bytes_read)
+				{
+					fprintf(stderr, "Failed write\n");
+					fclose(f);
+					f = NULL;
+				}
+			}
+			filesize -= bytes_read;
+		}
+		if (f != NULL) {
+			fclose(f);
+			f = NULL;
+		}
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	FILE *a;
+
+	++argv; /* Skip program name */
+	for ( ;*argv != NULL; ++argv) {
+		a = fopen(*argv, "r");
+		if (a == NULL)
+			fprintf(stderr, "Unable to open %s\n", *argv);
+		else {
+			untar(a, *argv);
+			fclose(a);
+		}
+	}
+	return (0);
+}
diff --git a/cpio/CMakeLists.txt b/cpio/CMakeLists.txt
new file mode 100644
index 000000000000..cc4aa14cb54b
--- /dev/null
+++ b/cpio/CMakeLists.txt
@@ -0,0 +1,47 @@
+############################################
+#
+# How to build bsdcpio
+#
+############################################
+IF(ENABLE_CPIO)
+
+  SET(bsdcpio_SOURCES
+    cmdline.c
+    cpio.c
+    cpio.h
+    cpio_platform.h
+    ../libarchive_fe/err.c
+    ../libarchive_fe/err.h
+    ../libarchive_fe/lafe_platform.h
+    ../libarchive_fe/line_reader.c
+    ../libarchive_fe/line_reader.h
+  )
+  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
+  IF(WIN32 AND NOT CYGWIN)
+    LIST(APPEND bsdcpio_SOURCES cpio_windows.c)
+    LIST(APPEND bsdcpio_SOURCES cpio_windows.h)
+  ENDIF(WIN32 AND NOT CYGWIN)
+
+  # bsdcpio documentation
+  SET(bsdcpio_MANS bsdcpio.1)
+
+  # How to build bsdcpio
+  ADD_EXECUTABLE(bsdcpio ${bsdcpio_SOURCES})
+  IF(ENABLE_CPIO_SHARED)
+    TARGET_LINK_LIBRARIES(bsdcpio archive ${ADDITIONAL_LIBS})
+  ELSE(ENABLE_CPIO_SHARED)
+    TARGET_LINK_LIBRARIES(bsdcpio archive_static ${ADDITIONAL_LIBS})
+    SET_TARGET_PROPERTIES(bsdcpio PROPERTIES COMPILE_DEFINITIONS
+    				  LIBARCHIVE_STATIC)
+  ENDIF(ENABLE_CPIO_SHARED)
+  # Full path to the compiled executable (used by test suite)
+  GET_TARGET_PROPERTY(BSDCPIO bsdcpio LOCATION)
+
+  # Installation rules
+  INSTALL(TARGETS bsdcpio RUNTIME DESTINATION bin)
+  INSTALL_MAN(${bsdcpio_MANS})
+
+ENDIF(ENABLE_CPIO)
+
+# Test suite
+add_subdirectory(test)
diff --git a/cpio/config_freebsd.h b/cpio/config_freebsd.h
new file mode 100644
index 000000000000..ec4e4416e37f
--- /dev/null
+++ b/cpio/config_freebsd.h
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* A hand-tooled configuration for FreeBSD. */
+
+#include <sys/param.h>  /* __FreeBSD_version */
+
+#define	HAVE_DIRENT_H 1
+#define	HAVE_ERRNO_H 1
+#define	HAVE_FCNTL_H 1
+#define	HAVE_FUTIMES 1
+#define	HAVE_GRP_H 1
+#define	HAVE_LIBARCHIVE 1
+#define	HAVE_LINK 1
+#define	HAVE_LSTAT 1
+#define	HAVE_LUTIMES 1
+#define	HAVE_PWD_H 1
+#define	HAVE_READLINK 1
+#define	HAVE_STDARG_H 1
+#define	HAVE_STDLIB_H 1
+#define	HAVE_STRING_H 1
+#define	HAVE_SYMLINK 1
+#define	HAVE_SYS_CDEFS_H 1
+#define	HAVE_SYS_STAT_H 1
+#define	HAVE_SYS_TIME_H 1
+#define	HAVE_TIME_H 1
+#define	HAVE_UINTMAX_T 1
+#define	HAVE_UNISTD_H 1
+#define	HAVE_UNSIGNED_LONG_LONG 1
+#define	HAVE_UTIME_H 1
+#define	HAVE_UTIMES 1
+
diff --git a/cpio/cpio_windows.c b/cpio/cpio_windows.c
new file mode 100644
index 000000000000..63f6df0397d2
--- /dev/null
+++ b/cpio/cpio_windows.c
@@ -0,0 +1,338 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include "cpio_platform.h"
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
+#include <stddef.h>
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#include <sys/stat.h>
+#include <process.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <windows.h>
+#include <sddl.h>
+
+#include "cpio.h"
+#include "err.h"
+
+#define EPOC_TIME	(116444736000000000ULL)
+
+static void cpio_dosmaperr(unsigned long);
+
+/*
+ * Prepend "\\?\" to the path name and convert it to unicode to permit
+ * an extended-length path for a maximum total path length of 32767
+ * characters.
+ * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ */
+static wchar_t *
+permissive_name(const char *name)
+{
+	wchar_t *wn, *wnp;
+	wchar_t *ws, *wsp;
+	DWORD l, len, slen, alloclen;
+	int unc;
+
+	len = (DWORD)strlen(name);
+	wn = malloc((len + 1) * sizeof(wchar_t));
+	if (wn == NULL)
+		return (NULL);
+	l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len);
+	if (l == 0) {
+		free(wn);
+		return (NULL);
+	}
+	wn[l] = L'\0';
+
+	/* Get a full path names */
+	l = GetFullPathNameW(wn, 0, NULL, NULL);
+	if (l == 0) {
+		free(wn);
+		return (NULL);
+	}
+	wnp = malloc(l * sizeof(wchar_t));
+	if (wnp == NULL) {
+		free(wn);
+		return (NULL);
+	}
+	len = GetFullPathNameW(wn, l, wnp, NULL);
+	free(wn);
+	wn = wnp;
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+	    wnp[2] == L'?' && wnp[3] == L'\\')
+		/* We have already permissive names. */
+		return (wn);
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+		wnp[2] == L'.' && wnp[3] == L'\\') {
+		/* Device names */
+		if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+		     (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+		    wnp[5] == L':' && wnp[6] == L'\\')
+			wnp[2] = L'?';/* Not device names. */
+		return (wn);
+	}
+
+	unc = 0;
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+		wchar_t *p = &wnp[2];
+
+		/* Skip server-name letters. */
+		while (*p != L'\\' && *p != L'\0')
+			++p;
+		if (*p == L'\\') {
+			wchar_t *rp = ++p;
+			/* Skip share-name letters. */
+			while (*p != L'\\' && *p != L'\0')
+				++p;
+			if (*p == L'\\' && p != rp) {
+				/* Now, match patterns such as
+				 * "\\server-name\share-name\" */
+				wnp += 2;
+				len -= 2;
+				unc = 1;
+			}
+		}
+	}
+
+	alloclen = slen = 4 + (unc * 4) + len + 1;
+	ws = wsp = malloc(slen * sizeof(wchar_t));
+	if (ws == NULL) {
+		free(wn);
+		return (NULL);
+	}
+	/* prepend "\\?\" */
+	wcsncpy(wsp, L"\\\\?\\", 4);
+	wsp += 4;
+	slen -= 4;
+	if (unc) {
+		/* append "UNC\" ---> "\\?\UNC\" */
+		wcsncpy(wsp, L"UNC\\", 4);
+		wsp += 4;
+		slen -= 4;
+	}
+	wcsncpy(wsp, wnp, slen);
+	free(wn);
+	ws[alloclen - 1] = L'\0';
+	return (ws);
+}
+
+static HANDLE
+cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+    LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
+    DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
+{
+	wchar_t *wpath;
+	HANDLE handle;
+
+	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+	    hTemplateFile);
+	if (handle != INVALID_HANDLE_VALUE)
+		return (handle);
+	if (GetLastError() != ERROR_PATH_NOT_FOUND)
+		return (handle);
+	wpath = permissive_name(path);
+	if (wpath == NULL)
+		return (handle);
+	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+	    hTemplateFile);
+	free(wpath);
+	return (handle);
+}
+
+#define WINTIME(sec, usec)	((Int32x32To64(sec, 10000000) + EPOC_TIME) + (usec * 10))
+static int
+__hutimes(HANDLE handle, const struct __timeval *times)
+{
+	ULARGE_INTEGER wintm;
+	FILETIME fatime, fmtime;
+
+	wintm.QuadPart = WINTIME(times[0].tv_sec, times[0].tv_usec);
+	fatime.dwLowDateTime = wintm.LowPart;
+	fatime.dwHighDateTime = wintm.HighPart;
+	wintm.QuadPart = WINTIME(times[1].tv_sec, times[1].tv_usec);
+	fmtime.dwLowDateTime = wintm.LowPart;
+	fmtime.dwHighDateTime = wintm.HighPart;
+	if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) {
+		errno = EINVAL;
+		return (-1);
+	}
+	return (0);
+}
+
+int
+futimes(int fd, const struct __timeval *times)
+{
+
+	return (__hutimes((HANDLE)_get_osfhandle(fd), times));
+}
+
+int
+utimes(const char *name, const struct __timeval *times)
+{
+	int ret;
+	HANDLE handle;
+
+	handle = cpio_CreateFile(name, GENERIC_READ | GENERIC_WRITE,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+	    FILE_FLAG_BACKUP_SEMANTICS, NULL);
+	if (handle == INVALID_HANDLE_VALUE) {
+		cpio_dosmaperr(GetLastError());
+		return (-1);
+	}
+	ret = __hutimes(handle, times);
+	CloseHandle(handle);
+	return (ret);
+}
+
+/*
+ * The following function was modified from PostgreSQL sources and is
+ * subject to the copyright below.
+ */
+/*-------------------------------------------------------------------------
+ *
+ * win32error.c
+ *	  Map win32 error codes to errno values
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+static const struct {
+	DWORD		winerr;
+	int		doserr;
+} doserrors[] =
+{
+	{	ERROR_INVALID_FUNCTION, EINVAL	},
+	{	ERROR_FILE_NOT_FOUND, ENOENT	},
+	{	ERROR_PATH_NOT_FOUND, ENOENT	},
+	{	ERROR_TOO_MANY_OPEN_FILES, EMFILE	},
+	{	ERROR_ACCESS_DENIED, EACCES	},
+	{	ERROR_INVALID_HANDLE, EBADF	},
+	{	ERROR_ARENA_TRASHED, ENOMEM	},
+	{	ERROR_NOT_ENOUGH_MEMORY, ENOMEM	},
+	{	ERROR_INVALID_BLOCK, ENOMEM	},
+	{	ERROR_BAD_ENVIRONMENT, E2BIG	},
+	{	ERROR_BAD_FORMAT, ENOEXEC	},
+	{	ERROR_INVALID_ACCESS, EINVAL	},
+	{	ERROR_INVALID_DATA, EINVAL	},
+	{	ERROR_INVALID_DRIVE, ENOENT	},
+	{	ERROR_CURRENT_DIRECTORY, EACCES	},
+	{	ERROR_NOT_SAME_DEVICE, EXDEV	},
+	{	ERROR_NO_MORE_FILES, ENOENT	},
+	{	ERROR_LOCK_VIOLATION, EACCES	},
+	{	ERROR_SHARING_VIOLATION, EACCES	},
+	{	ERROR_BAD_NETPATH, ENOENT	},
+	{	ERROR_NETWORK_ACCESS_DENIED, EACCES	},
+	{	ERROR_BAD_NET_NAME, ENOENT	},
+	{	ERROR_FILE_EXISTS, EEXIST	},
+	{	ERROR_CANNOT_MAKE, EACCES	},
+	{	ERROR_FAIL_I24, EACCES	},
+	{	ERROR_INVALID_PARAMETER, EINVAL	},
+	{	ERROR_NO_PROC_SLOTS, EAGAIN	},
+	{	ERROR_DRIVE_LOCKED, EACCES	},
+	{	ERROR_BROKEN_PIPE, EPIPE	},
+	{	ERROR_DISK_FULL, ENOSPC	},
+	{	ERROR_INVALID_TARGET_HANDLE, EBADF	},
+	{	ERROR_INVALID_HANDLE, EINVAL	},
+	{	ERROR_WAIT_NO_CHILDREN, ECHILD	},
+	{	ERROR_CHILD_NOT_COMPLETE, ECHILD	},
+	{	ERROR_DIRECT_ACCESS_HANDLE, EBADF	},
+	{	ERROR_NEGATIVE_SEEK, EINVAL	},
+	{	ERROR_SEEK_ON_DEVICE, EACCES	},
+	{	ERROR_DIR_NOT_EMPTY, ENOTEMPTY	},
+	{	ERROR_NOT_LOCKED, EACCES	},
+	{	ERROR_BAD_PATHNAME, ENOENT	},
+	{	ERROR_MAX_THRDS_REACHED, EAGAIN	},
+	{	ERROR_LOCK_FAILED, EACCES	},
+	{	ERROR_ALREADY_EXISTS, EEXIST	},
+	{	ERROR_FILENAME_EXCED_RANGE, ENOENT	},
+	{	ERROR_NESTING_NOT_ALLOWED, EAGAIN	},
+	{	ERROR_NOT_ENOUGH_QUOTA, ENOMEM	}
+};
+
+static void
+cpio_dosmaperr(unsigned long e)
+{
+	int			i;
+
+	if (e == 0)	{
+		errno = 0;
+		return;
+	}
+
+	for (i = 0; i < (int)sizeof(doserrors); i++) {
+		if (doserrors[i].winerr == e) {
+			errno = doserrors[i].doserr;
+			return;
+		}
+	}
+
+	/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+	errno = EINVAL;
+	return;
+}
+#endif
diff --git a/cpio/cpio_windows.h b/cpio/cpio_windows.h
new file mode 100644
index 000000000000..105bf69991de
--- /dev/null
+++ b/cpio/cpio_windows.h
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef CPIO_WINDOWS_H
+#define CPIO_WINDOWS_H 1
+
+#include <io.h>
+#include <string.h>
+
+#define getgrgid(id)	NULL
+#define getgrnam(name)	NULL
+#define getpwnam(name)	NULL
+#define getpwuid(id)	NULL
+
+#ifdef _MSC_VER
+#define snprintf	sprintf_s
+#define strdup		_strdup
+#define open	_open
+#define read	_read
+#define close	_close
+#endif
+
+struct passwd {
+	char	*pw_name;
+	uid_t	 pw_uid;
+	gid_t	 pw_gid;
+};
+
+struct group {
+	char	*gr_name;
+	gid_t	 gr_gid;
+};
+
+struct _timeval64i32 {
+	time_t		tv_sec;
+	long		tv_usec;
+};
+#define __timeval _timeval64i32
+
+extern int futimes(int fd, const struct __timeval *times);
+#ifndef HAVE_FUTIMES
+#define HAVE_FUTIMES 1
+#endif
+extern int utimes(const char *name, const struct __timeval *times);
+#ifndef HAVE_UTIMES
+#define HAVE_UTIMES 1
+#endif
+
+#endif /* CPIO_WINDOWS_H */
diff --git a/cpio/test/CMakeLists.txt b/cpio/test/CMakeLists.txt
new file mode 100644
index 000000000000..09ca2c7d96b3
--- /dev/null
+++ b/cpio/test/CMakeLists.txt
@@ -0,0 +1,93 @@
+############################################
+#
+# How to build bsdcpio_test
+#
+############################################
+IF(ENABLE_CPIO AND ENABLE_TEST)
+  SET(bsdcpio_test_SOURCES
+    ../cmdline.c
+    ../../libarchive_fe/err.c
+    ../../test_utils/test_utils.c
+    main.c
+    test.h
+    test_0.c
+    test_basic.c
+    test_cmdline.c
+    test_extract_cpio_Z
+    test_extract_cpio_bz2
+    test_extract_cpio_grz
+    test_extract_cpio_gz
+    test_extract_cpio_lrz
+    test_extract_cpio_lz
+    test_extract_cpio_lzma
+    test_extract_cpio_lzo
+    test_extract_cpio_xz
+    test_format_newc.c
+    test_gcpio_compat.c
+    test_option_0.c
+    test_option_B_upper.c
+    test_option_C_upper.c
+    test_option_J_upper.c
+    test_option_L_upper.c
+    test_option_Z_upper.c
+    test_option_a.c
+    test_option_b64encode.c
+    test_option_c.c
+    test_option_d.c
+    test_option_f.c
+    test_option_grzip.c
+    test_option_help.c
+    test_option_l.c
+    test_option_lrzip.c
+    test_option_lzma.c
+    test_option_lzop.c
+    test_option_m.c
+    test_option_t.c
+    test_option_u.c
+    test_option_uuencode.c
+    test_option_version.c
+    test_option_xz.c
+    test_option_y.c
+    test_option_z.c
+    test_owner_parse.c
+    test_passthrough_dotdot.c
+    test_passthrough_reverse.c
+  )
+
+  #
+  # Register target
+  #
+  ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
+  SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)
+
+  #
+  # Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
+  #
+  GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
+    ${CMAKE_CURRENT_LIST_FILE} ${bsdcpio_test_SOURCES})
+  SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
+    ${CMAKE_CURRENT_BINARY_DIR})
+
+  # list.h has a line DEFINE_TEST(testname) for every
+  # test.  We can use that to define the tests for cmake by
+  # defining a DEFINE_TEST macro and reading list.h in.
+  MACRO (DEFINE_TEST _testname)
+    ADD_TEST(
+      NAME bsdcpio_${_testname}
+      COMMAND bsdcpio_test -vv
+                           -p $<TARGET_FILE:bsdcpio>
+                           -r ${CMAKE_CURRENT_SOURCE_DIR}
+                           ${_testname})
+  ENDMACRO (DEFINE_TEST _testname)
+
+  INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
+  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
+
+  # Experimental new test handling
+  ADD_CUSTOM_TARGET(run_bsdcpio_test
+	COMMAND	bsdcpio_test -p ${BSDCPIO} -r ${CMAKE_CURRENT_SOURCE_DIR})
+  ADD_DEPENDENCIES(run_bsdcpio_test bsdcpio)
+  ADD_DEPENDENCIES(run_all_tests run_bsdcpio_test)
+ENDIF(ENABLE_CPIO AND ENABLE_TEST)
+
diff --git a/doc/html/.ignore_me b/doc/html/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/html/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/man/.ignore_me b/doc/man/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/man/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/mdoc2man.awk b/doc/mdoc2man.awk
new file mode 100755
index 000000000000..726f628c0d3f
--- /dev/null
+++ b/doc/mdoc2man.awk
@@ -0,0 +1,391 @@
+#!/usr/bin/awk
+#
+# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Dramatically overhauled by Tim Kientzle.  This version almost
+# handles library-style pages with Fn, Ft, etc commands.  Still
+# a lot of problems...
+
+BEGIN {
+  displaylines = 0
+  trailer = ""
+  out = ""
+  sep = ""
+  nextsep = " "
+}
+
+# Add a word with appropriate preceding whitespace
+# Maintain a short queue of the expected upcoming word separators.
+function add(str) {
+  out=out sep str
+  sep = nextsep
+  nextsep = " "
+}
+
+# Add a word with no following whitespace
+# Use for opening punctuation such as '('
+function addopen(str) {
+  add(str)
+  sep = ""
+}
+
+# Add a word with no preceding whitespace
+# Use for closing punctuation such as ')' or '.'
+function addclose(str) {
+  sep = ""
+  add(str)
+}
+
+# Add a word with no space before or after
+# Use for separating punctuation such as '='
+function addpunct(str) {
+  sep = ""
+  add(str)
+  sep = ""
+}
+
+# Emit the current line so far
+function endline() {
+  addclose(trailer)
+  trailer = ""
+  if(length(out) > 0) {
+    print out
+    out=""
+  }
+  if(displaylines > 0) {
+    displaylines = displaylines - 1
+    if (displaylines == 0)
+      dispend()
+  }
+  # First word on next line has no preceding whitespace
+  sep = ""
+}
+
+function linecmd(cmd) {
+  endline()
+  add(cmd)
+  endline()
+}
+
+function breakline() {
+  linecmd(".br")
+}
+
+# Start an indented display
+function dispstart() {
+  linecmd(".RS 4")
+}
+
+# End an indented display
+function dispend() {
+  linecmd(".RE")
+}
+
+# Collect rest of input line
+function wtail() {
+  retval=""
+  while(w<nwords) {
+    if(length(retval))
+      retval=retval " "
+    retval=retval words[++w]
+  }
+  return retval
+}
+
+function splitwords(l, dest, n, o, w) {
+  n = 1
+  delete dest
+  while (length(l) > 0) {
+    sub("^[ \t]*", "", l)
+    if (match(l, "^\"")) {
+      l = substr(l, 2)
+      o = index(l, "\"")
+      if (o > 0) {
+	w = substr(l, 1, o-1)
+	l = substr(l, o+1)
+	dest[n++] = w
+      } else {
+	dest[n++] = l
+	l = ""
+      }
+    } else {
+      o = match(l, "[ \t]")
+      if (o > 0) {
+	w = substr(l, 1, o-1)
+	l = substr(l, o+1)
+	dest[n++] = w
+      } else {
+	dest[n++] = l
+	l = ""
+      }
+    }
+  }
+  return n-1
+}
+
+! /^\./ {
+  out = $0
+  endline()
+  next
+}
+
+/^\.\\"/ { next }
+
+{
+  sub("^\\.","")
+  nwords=splitwords($0, words)
+  # TODO: Instead of iterating 'w' over the array, have a separate
+  # function that returns 'next word' and use that.  This will allow
+  # proper handling of double-quoted arguments as well.
+  for(w=1;w<=nwords;w++) {
+    if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted
+      dispstart()
+      displaylines = 1
+    } else if(match(words[w],"^Dl$")) { # Display literal
+      dispstart()
+      displaylines = 1
+    } else if(match(words[w],"^Bd$")) { # Begin display
+      if(match(words[w+1],"-literal")) {
+        dispstart()
+	linecmd(".nf")
+	displaylines=10000
+	w=nwords
+      }
+    } else if(match(words[w],"^Ed$")) { # End display
+      displaylines = 0
+      dispend()
+    } else if(match(words[w],"^Ns$")) { # Suppress space after next word
+      nextsep = ""
+    } else if(match(words[w],"^No$")) { # Normal text
+      add(words[++w])
+    } else if(match(words[w],"^Dq$")) { # Quote
+      addopen("``")
+      add(words[++w])
+      while(w<nwords&&!match(words[w+1],"^[\\.,]"))
+	add(words[++w])
+      addclose("''")
+    } else if(match(words[w],"^Do$")) {
+      addopen("``")
+    } else if(match(words[w],"^Dc$")) {
+      addclose("''")
+    } else if(match(words[w],"^Oo$")) {
+      addopen("[")
+    } else if(match(words[w],"^Oc$")) {
+      addclose("]")
+    } else if(match(words[w],"^Ao$")) {
+      addopen("<")
+    } else if(match(words[w],"^Ac$")) {
+      addclose(">")
+    } else if(match(words[w],"^Dd$")) {
+      date=wtail()
+      next
+    } else if(match(words[w],"^Dt$")) {
+      id=wtail()
+      next
+    } else if(match(words[w],"^Ox$")) {
+      add("OpenBSD")
+    } else if(match(words[w],"^Fx$")) {
+      add("FreeBSD")
+    } else if(match(words[w],"^Nx$")) {
+      add("NetBSD")
+    } else if(match(words[w],"^St$")) {
+      if (match(words[w+1], "^-p1003.1$")) {
+         w++
+         add("IEEE Std 1003.1 (``POSIX.1'')")
+      } else if(match(words[w+1], "^-p1003.1-96$")) {
+         w++
+         add("ISO/IEC 9945-1:1996 (``POSIX.1'')")
+      } else if(match(words[w+1], "^-p1003.1-88$")) {
+         w++
+         add("IEEE Std 1003.1-1988 (``POSIX.1'')")
+      } else if(match(words[w+1], "^-p1003.1-2001$")) {
+         w++
+         add("IEEE Std 1003.1-2001 (``POSIX.1'')")
+      } else if(match(words[w+1], "^-susv2$")) {
+         w++
+         add("Version 2 of the Single UNIX Specification (``SUSv2'')")
+      }
+    } else if(match(words[w],"^Ex$")) {
+      if (match(words[w+1], "^-std$")) {
+         w++
+         add("The \\fB" name "\\fP utility exits 0 on success, and >0 if an error occurs.")
+      }
+    } else if(match(words[w],"^Os$")) {
+      add(".TH " id " \"" date "\" \"" wtail() "\"")
+    } else if(match(words[w],"^Sh$")) {
+      section=wtail()
+      add(".SH " section)
+      linecmd(".ad l")
+    } else if(match(words[w],"^Xr$")) {
+      add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
+    } else if(match(words[w],"^Nm$")) {
+      if(match(section,"SYNOPSIS"))
+        breakline()
+      if(w >= nwords)
+	n=name
+      else if (match(words[w+1], "^[A-Z][a-z]$"))
+	n=name
+      else if (match(words[w+1], "^[.,;:]$"))
+	n=name
+      else {
+        n=words[++w]
+        if(!length(name))
+          name=n
+      }
+      if(!length(n))
+        n=name
+      add("\\fB\\%" n "\\fP")
+    } else if(match(words[w],"^Nd$")) {
+      add("\\- " wtail())
+    } else if(match(words[w],"^Fl$")) {
+      add("\\fB\\-" words[++w] "\\fP")
+    } else if(match(words[w],"^Ar$")) {
+      addopen("\\fI")
+      if(w==nwords)
+	add("file ...\\fP")
+      else
+	add(words[++w] "\\fP")
+    } else if(match(words[w],"^Cm$")) {
+      add("\\fB" words[++w] "\\fP")
+    } else if(match(words[w],"^Op$")) {
+      addopen("[")
+      option=1
+      trailer="]" trailer
+    } else if(match(words[w],"^Pp$")) {
+      linecmd(".PP")
+    } else if(match(words[w],"^An$")) {
+      endline()
+    } else if(match(words[w],"^Ss$")) {
+      add(".SS")
+    } else if(match(words[w],"^Ft$")) {
+      if (match(section, "SYNOPSIS")) {
+	breakline()
+      }
+      add("\\fI" wtail() "\\fP")
+      if (match(section, "SYNOPSIS")) {
+	breakline()
+      }
+    } else if(match(words[w],"^Fn$")) {
+      ++w
+      F = "\\fB\\%" words[w] "\\fP("
+      Fsep = ""
+      while(w<nwords) {
+	++w
+	if (match(words[w], "^[.,:]$")) {
+	  --w
+	  break
+	}
+	gsub(" ", "\\ ", words[w])
+	F = F Fsep "\\fI\\%"  words[w] "\\fP"
+	Fsep = ", "
+      }
+      add(F ")")
+      if (match(section, "SYNOPSIS")) {
+	addclose(";")
+      }
+    } else if(match(words[w],"^Fo$")) {
+      w++
+      F = "\\fB\\%" words[w] "\\fP("
+      Fsep = ""
+    } else if(match(words[w],"^Fa$")) {
+      w++
+      gsub(" ", "\\ ", words[w])
+      F = F Fsep "\\fI\\%"  words[w] "\\fP"
+      Fsep = ", "
+    } else if(match(words[w],"^Fc$")) {
+      add(F ")")
+      if (match(section, "SYNOPSIS")) {
+	addclose(";")
+      }
+    } else if(match(words[w],"^Va$")) {
+      w++
+      add("\\fI" words[w] "\\fP")
+    } else if(match(words[w],"^In$")) {
+      w++
+      add("\\fB#include <" words[w] ">\\fP")
+    } else if(match(words[w],"^Pa$")) {
+      addopen("\\fI")
+      w++
+      if(match(words[w],"^\\."))
+	add("\\&")
+      add(words[w] "\\fP")
+    } else if(match(words[w],"^Dv$")) {
+      add(".BR")
+    } else if(match(words[w],"^Em|Ev$")) {
+      add(".IR")
+    } else if(match(words[w],"^Pq$")) {
+      addopen("(")
+      trailer=")" trailer
+    } else if(match(words[w],"^Aq$")) {
+      addopen("\\%<")
+      trailer=">" trailer
+    } else if(match(words[w],"^Brq$")) {
+      addopen("{")
+      trailer="}" trailer
+    } else if(match(words[w],"^S[xy]$")) {
+      add(".B " wtail())
+    } else if(match(words[w],"^Ic$")) {
+      add("\\fB")
+      trailer="\\fP" trailer
+    } else if(match(words[w],"^Bl$")) {
+      oldoptlist=optlist
+      linecmd(".RS 5")
+      if(match(words[w+1],"-bullet"))
+	optlist=1
+      else if(match(words[w+1],"-enum")) {
+	optlist=2
+	enum=0
+      } else if(match(words[w+1],"-tag"))
+	optlist=3
+      else if(match(words[w+1],"-item"))
+	optlist=4
+      else if(match(words[w+1],"-bullet"))
+	optlist=1
+      w=nwords
+    } else if(match(words[w],"^El$")) {
+      linecmd(".RE")
+      optlist=oldoptlist
+    } else if(match(words[w],"^It$")&&optlist) {
+      if(optlist==1)
+	add(".IP \\(bu")
+      else if(optlist==2)
+	add(".IP " ++enum ".")
+      else if(optlist==3) {
+	add(".TP")
+        endline()
+	if(match(words[w+1],"^Pa$|^Ev$")) {
+	  add(".B")
+	  w++
+	}
+      } else if(optlist==4)
+	add(".IP")
+    } else if(match(words[w],"^Xo$")) {
+      # TODO: Figure out how to handle this
+    } else if(match(words[w],"^Xc$")) {
+      # TODO: Figure out how to handle this
+    } else if(match(words[w],"^[=]$")) {
+      addpunct(words[w])
+    } else if(match(words[w],"^[[{(]$")) {
+      addopen(words[w])
+    } else if(match(words[w],"^[\\])}.,;:]$")) {
+      addclose(words[w])
+    } else {
+      add(words[w])
+    }
+  }
+  if(match(out,"^\\.[^a-zA-Z]"))
+    sub("^\\.","",out)
+  endline()
+}
diff --git a/doc/mdoc2wiki.awk b/doc/mdoc2wiki.awk
new file mode 100755
index 000000000000..5fee29c32952
--- /dev/null
+++ b/doc/mdoc2wiki.awk
@@ -0,0 +1,451 @@
+#!/usr/bin/awk
+#
+# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Dramatically overhauled by Tim Kientzle.  This version almost
+# handles library-style pages with Fn, Ft, etc commands.  Still
+# a lot of problems...
+
+BEGIN {
+  displaylines = 0
+  listdepth = 0
+  trailer = ""
+  out = ""
+  sep = ""
+  nextsep = " "
+  spaces = "                    "
+
+  NORMAL_STATE = 0
+  PRETAG_STATE = 1
+  STATE = NORMAL_STATE
+}
+
+# Add a word with appropriate preceding whitespace
+# Maintain a short queue of the expected upcoming word separators.
+function add(str) {
+  out=out sep str
+  sep = nextsep
+  nextsep = " "
+}
+
+# Add a word with no following whitespace
+# Use for opening punctuation such as '('
+function addopen(str) {
+  add(str)
+  sep = ""
+}
+
+# Add a word with no preceding whitespace
+# Use for closing punctuation such as ')' or '.'
+function addclose(str) {
+  sep = ""
+  add(str)
+}
+
+# Add a word with no space before or after
+# Use for separating punctuation such as '='
+function addpunct(str) {
+  sep = ""
+  add(str)
+  sep = ""
+}
+
+# Emit the current line so far
+function endline() {
+  addclose(trailer)
+  trailer = ""
+  if(length(out) > 0) {
+    if (STATE == PRETAG_STATE) {
+      print out
+    } else {
+      print out " "
+    }
+    out=""
+  }
+  if(displaylines > 0) {
+    displaylines = displaylines - 1
+    if (displaylines == 0)
+      dispend()
+  }
+  # First word on next line has no preceding whitespace
+  sep = ""
+}
+
+function linecmd(cmd) {
+  endline()
+  add(cmd)
+  endline()
+}
+
+function breakline() {
+  linecmd("<br>")
+}
+
+# Start an indented display
+function dispstart() {
+  linecmd("```text")
+}
+
+# End an indented display
+function dispend() {
+  linecmd("```")
+}
+
+# Collect rest of input line
+function wtail() {
+  retval=""
+  while(w<nwords) {
+    if(length(retval))
+      retval=retval " "
+    retval=retval words[++w]
+  }
+  return retval
+}
+
+function splitwords(l, dest, n, o, w) {
+  n = 1
+  delete dest
+  while (length(l) > 0) {
+    sub("^[ \t]*", "", l)
+    if (match(l, "^\"")) {
+      l = substr(l, 2)
+      o = index(l, "\"")
+      if (o > 0) {
+	w = substr(l, 1, o-1)
+	l = substr(l, o+1)
+	dest[n++] = w
+      } else {
+	dest[n++] = l
+	l = ""
+      }
+    } else {
+      o = match(l, "[ \t]")
+      if (o > 0) {
+	w = substr(l, 1, o-1)
+	l = substr(l, o+1)
+	dest[n++] = w
+      } else {
+	dest[n++] = l
+	l = ""
+      }
+    }
+  }
+  return n-1
+}
+
+! /^\./ {
+  out = $0
+  endline()
+  next
+}
+
+/^\.\\"/ { next }
+
+{
+  sub("^\\.","")
+  nwords=splitwords($0, words)
+  # TODO: Instead of iterating 'w' over the array, have a separate
+  # function that returns 'next word' and use that.  This will allow
+  # proper handling of double-quoted arguments as well.
+  for(w=1;w<=nwords;w++) {
+    if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted
+      dispstart()
+      displaylines = 1
+    } else if(match(words[w],"^Dl$")) { # Display literal
+      dispstart()
+      displaylines = 1
+    } else if(match(words[w],"^Bd$")) { # Begin display
+      STATE = PRETAG_STATE
+      if(match(words[w+1],"-literal")) {
+        dispstart()
+	displaylines=10000
+	w=nwords
+      }
+    } else if(match(words[w],"^Ed$")) { # End display
+      displaylines = 0
+      dispend()
+      STATE = NORMAL_STATE
+    } else if(match(words[w],"^Ns$")) { # Suppress space before next word
+      sep=""
+    } else if(match(words[w],"^No$")) { # Normal text
+      add(words[++w])
+    } else if(match(words[w],"^Dq$")) { # Quote
+      addopen("\"")
+      add(words[++w])
+      while(w<nwords&&!match(words[w+1],"^[\\.,]"))
+	add(words[++w])
+      addclose("\"")
+    } else if(match(words[w],"^Do$")) {
+      addopen("\"")
+    } else if(match(words[w],"^Dc$")) {
+      addclose("\"")
+    } else if(match(words[w],"^Oo$")) {
+      addopen("<nowiki>[</nowiki>")
+    } else if(match(words[w],"^Oc$")) {
+      addclose("<nowiki>]</nowiki>")
+    } else if(match(words[w],"^Ao$")) {
+      addopen("&lt;")
+    } else if(match(words[w],"^Ac$")) {
+      addclose("&gt;")
+    } else if(match(words[w],"^Dd$")) {
+      date=wtail()
+      next
+    } else if(match(words[w],"^Dt$")) {
+      id=words[++w] "(" words[++w] ")"
+      next
+    } else if(match(words[w],"^Ox$")) {
+      add("OpenBSD")
+    } else if(match(words[w],"^Fx$")) {
+      add("FreeBSD")
+    } else if(match(words[w],"^Bx$")) {
+      add("BSD")
+    } else if(match(words[w],"^Nx$")) {
+      add("NetBSD")
+    } else if(match(words[w],"^St$")) {
+      if (match(words[w+1], "^-p1003.1$")) {
+         w++
+         add("<nowiki>IEEE Std 1003.1 (``POSIX.1'')</nowiki>")
+      } else if(match(words[w+1], "^-p1003.1-96$")) {
+         w++
+         add("<nowiki>ISO/IEC 9945-1:1996 (``POSIX.1'')</nowiki>")
+      } else if(match(words[w+1], "^-p1003.1-88$")) {
+         w++
+         add("<nowiki>IEEE Std 1003.1-1988 (``POSIX.1'')</nowiki>")
+      } else if(match(words[w+1], "^-p1003.1-2001$")) {
+         w++
+         add("<nowiki>IEEE Std 1003.1-2001 (``POSIX.1'')</nowiki>")
+      } else if(match(words[w+1], "^-susv2$")) {
+         w++
+         add("<nowiki>Version 2 of the Single UNIX Specification (``SUSv2'')</nowiki>")
+      }
+    } else if(match(words[w],"^Ex$")) {
+      if (match(words[w+1], "^-std$")) {
+         w++
+         add("The '''" name "''' utility exits 0 on success, and &gt;0 if an error occurs.")
+      }
+    } else if(match(words[w],"^Os$")) {
+      add(id " manual page")
+    } else if(match(words[w],"^Sh$")) {
+      section=wtail()
+      linecmd("== " section " ==")
+    } else if(match(words[w],"^Xr$")) {
+      add("'''" words[++w] "'''(" words[++w] ")" words[++w])
+    } else if(match(words[w],"^Nm$")) {
+      if(match(section,"SYNOPSIS"))
+        breakline()
+      if(w >= nwords)
+	n=name
+      else if (match(words[w+1], "^[A-Z][a-z]$"))
+	n=name
+      else if (match(words[w+1], "^[.,;:]$"))
+	n=name
+      else {
+        n=words[++w]
+        if(!length(name))
+          name=n
+      }
+      if(!length(n))
+        n=name
+      if (displaylines == 0)
+	add("'''" n "'''")
+      else
+	add(n)
+    } else if(match(words[w],"^Nd$")) {
+      add("- " wtail())
+    } else if(match(words[w],"^Fl$")) {
+      addopen("-")
+    } else if(match(words[w],"^Ar$")) {
+      if(w==nwords)
+	add("''file ...''")
+      else {
+	++w
+	gsub("<", "&lt;", words[w])
+	add("''" words[w] "''")
+      }
+    } else if(match(words[w],"^Cm$")) {
+      ++w
+      if (displaylines == 0) {
+	add("'''" words[w] "'''")
+      } else
+	add(words[w])
+    } else if(match(words[w],"^Op$")) {
+      addopen("<nowiki>[</nowiki>")
+      option=1
+      trailer="<nowiki>]</nowiki>" trailer
+    } else if(match(words[w],"^Pp$")) {
+      ++w
+      endline()
+      print ""
+    } else if(match(words[w],"^An$")) {
+      if (match(words[w+1],"-nosplit"))
+	++w
+      endline()
+    } else if(match(words[w],"^Ss$")) {
+      add("===")
+      trailer="==="
+    } else if(match(words[w],"^Ft$")) {
+      if (match(section, "SYNOPSIS")) {
+	breakline()
+      }
+      l = wtail()
+      add("'''" l "'''")
+      if (match(section, "SYNOPSIS")) {
+	breakline()
+      }
+    } else if(match(words[w],"^Fn$")) {
+      ++w
+      F = "'''" words[w] "'''("
+      Fsep = ""
+      while(w<nwords) {
+	++w
+	if (match(words[w], "^[.,:]$")) {
+	  --w
+	  break
+	}
+	F = F Fsep "''"  words[w] "''"
+	Fsep = ", "
+      }
+      add(F ")")
+      if (match(section, "SYNOPSIS")) {
+	addclose(";")
+      }
+    } else if(match(words[w],"^Fo$")) {
+      w++
+      F = "'''" words[w] "'''("
+      Fsep = ""
+    } else if(match(words[w],"^Fa$")) {
+      w++
+      F = F Fsep "''"  words[w] "''"
+      Fsep = ", "
+    } else if(match(words[w],"^Fc$")) {
+      add(F ")")
+      if (match(section, "SYNOPSIS")) {
+	addclose(";")
+      }
+    } else if(match(words[w],"^Va$")) {
+      w++
+      add("''" words[w] "''")
+    } else if(match(words[w],"^In$")) {
+      w++
+      add("'''<nowiki>#include <" words[w] "></nowiki>'''")
+    } else if(match(words[w],"^Pa$")) {
+      w++
+#      if(match(words[w],"^\\."))
+#	add("\\&")
+      if (displaylines == 0)
+	add("''" words[w] "''")
+      else
+	add(words[w])
+    } else if(match(words[w],"^Dv$")) {
+      linecmd()
+    } else if(match(words[w],"^Em|Ev$")) {
+      add(".IR")
+    } else if(match(words[w],"^Pq$")) {
+      addopen("(")
+      trailer=")" trailer
+    } else if(match(words[w],"^Aq$")) {
+      addopen(" &lt;")
+      trailer="&gt;" trailer
+    } else if(match(words[w],"^Brq$")) {
+      addopen("<nowiki>{</nowiki>")
+      trailer="<nowiki>}</nowiki>" trailer
+    } else if(match(words[w],"^S[xy]$")) {
+      add(".B " wtail())
+    } else if(match(words[w],"^Tn$")) {
+      n=wtail()
+      add("'''" n "'''")
+    } else if(match(words[w],"^Ic$")) {
+      add("''")
+      trailer="''" trailer
+    } else if(match(words[w],"^Bl$")) {
+      ++listdepth
+      listnext[listdepth]=""
+      if(match(words[w+1],"-bullet")) {
+	optlist[listdepth]=1
+	addopen("<ul>")
+	listclose[listdepth]="</ul>"
+      } else if(match(words[w+1],"-enum")) {
+	optlist[listdepth]=2
+	enum=0
+	addopen("<ol>")
+	listclose[listdepth]="</ol>"
+      } else if(match(words[w+1],"-tag")) {
+	optlist[listdepth]=3
+	addopen("<dl>")
+	listclose[listdepth]="</dl>"
+      } else if(match(words[w+1],"-item")) {
+	optlist[listdepth]=4
+	addopen("<ul>")
+	listclose[listdepth]="</ul>"
+      }
+      w=nwords
+    } else if(match(words[w],"^El$")) {
+      addclose(listnext[listdepth])
+      addclose(listclose[listdepth])
+      listclose[listdepth]=""
+      listdepth--
+    } else if(match(words[w],"^It$")) {
+      addclose(listnext[listdepth])
+      if(optlist[listdepth]==1) {
+	addpunct("<li>")
+	listnext[listdepth] = "</li>"
+      } else if(optlist[listdepth]==2) {
+	addpunct("<li>")
+	listnext[listdepth] = "</li>"
+      } else if(optlist[listdepth]==3) {
+	addpunct("<dt>")
+	listnext[listdepth] = "</dt>"
+	if(match(words[w+1],"^Xo$")) {
+	  # Suppress trailer
+	  w++
+	} else if(match(words[w+1],"^Pa$|^Ev$")) {
+	  addopen("'''")
+	  w++
+	  add(words[++w] "'''")
+	} else {
+	  trailer = listnext[listdepth] "<dd>" trailer
+	  listnext[listdepth] = "</dd>"
+	}
+      } else if(optlist[listdepth]==4) {
+	addpunct("<li>")
+	listnext[listdepth] = "</li>"
+      }
+    } else if(match(words[w], "^Vt$")) {
+      w++
+      add("''" words[w] "''")
+    } else if(match(words[w],"^Xo$")) {
+      # TODO: Figure out how to handle this
+    } else if(match(words[w],"^Xc$")) {
+      # TODO: Figure out how to handle this
+      if (optlist[listdepth] == 3) {
+	addclose(listnext[listdepth])
+	addopen("<dd>")
+	listnext[listdepth] = "</dd>"
+      }
+    } else if(match(words[w],"^[=]$")) {
+      addpunct(words[w])
+    } else if(match(words[w],"^[[{(]$")) {
+      addopen(words[w])
+    } else if(match(words[w],"^[\\])}.,;:]$")) {
+      addclose(words[w])
+    } else {
+      sub("\\\\&", "", words[w])
+      add(words[w])
+    }
+  }
+  if(match(out,"^\\.[^a-zA-Z]"))
+    sub("^\\.","",out)
+  endline()
+}
diff --git a/doc/pdf/.ignore_me b/doc/pdf/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/pdf/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/text/.ignore_me b/doc/text/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/text/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/update.sh b/doc/update.sh
new file mode 100755
index 000000000000..1038da133f77
--- /dev/null
+++ b/doc/update.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+set -e
+
+#
+# Simple script to repopulate the 'doc' tree from
+# the mdoc man pages stored in each project.
+#
+
+# Collect list of man pages, relative to my subdirs
+test -d man || mkdir man
+cd man
+MANPAGES=`for d in libarchive tar cpio;do ls ../../$d/*.[135];done | grep -v '\.so\.'`
+cd ..
+
+# Build Makefile in 'man' directory
+cd man
+chmod +w .
+rm -f *.[135] Makefile
+echo > Makefile
+echo "default: all" >>Makefile
+echo >>Makefile
+all="all:"
+for f in $MANPAGES; do
+    outname="`basename $f`"
+    echo >> Makefile
+    echo $outname: ../mdoc2man.awk $f >> Makefile
+    echo "	awk -f ../mdoc2man.awk < $f > $outname" >> Makefile
+    all="$all $outname"
+done
+echo $all >>Makefile
+cd ..
+
+# Rebuild Makefile in 'text' directory
+test -d text || mkdir text
+cd text
+chmod +w .
+rm -f *.txt Makefile
+echo > Makefile
+echo "default: all" >>Makefile
+echo >>Makefile
+all="all:"
+for f in $MANPAGES; do
+    outname="`basename $f`.txt"
+    echo >> Makefile
+    echo $outname: $f >> Makefile
+    echo "	nroff -mdoc $f | col -b > $outname" >> Makefile
+    all="$all $outname"
+done
+echo $all >>Makefile
+cd ..
+
+# Rebuild Makefile in 'pdf' directory
+test -d pdf || mkdir pdf
+cd pdf
+chmod +w .
+rm -f *.pdf Makefile
+echo > Makefile
+echo "default: all" >>Makefile
+echo >>Makefile
+all="all:"
+for f in $MANPAGES; do
+    outname="`basename $f`.pdf"
+    echo >> Makefile
+    echo $outname: $f >> Makefile
+    echo "	groff -mdoc -T ps $f | ps2pdf - - > $outname" >> Makefile
+    all="$all $outname"
+done
+echo $all >>Makefile
+cd ..
+
+# Build Makefile in 'html' directory
+test -d html || mkdir html
+cd html
+chmod +w .
+rm -f *.html Makefile
+echo > Makefile
+echo "default: all" >>Makefile
+echo >>Makefile
+all="all:"
+for f in $MANPAGES; do
+    outname="`basename $f`.html"
+    echo >> Makefile
+    echo $outname: $f >> Makefile
+    echo "	groff -mdoc -T html $f > $outname" >> Makefile
+    all="$all $outname"
+done
+echo $all >>Makefile
+cd ..
+
+# Build Makefile in 'wiki' directory
+test -d wiki || mkdir wiki
+cd wiki
+chmod +w .
+rm -f *.wiki Makefile
+echo > Makefile
+echo "default: all" >>Makefile
+echo >>Makefile
+all="all:"
+for f in $MANPAGES; do
+    outname="`basename $f | awk '{ac=split($0,a,"[_.-]");o="ManPage";for(w=0;w<=ac;++w){o=o toupper(substr(a[w],1,1)) substr(a[w],2)};print o}'`.wiki"
+    echo >> Makefile
+    echo $outname: ../mdoc2wiki.awk $f >> Makefile
+    echo "	awk -f ../mdoc2wiki.awk < $f > $outname" >> Makefile
+    all="$all $outname"
+done
+echo $all >>Makefile
+cd ..
+
+# Convert all of the manpages to -man format
+(cd man && make)
+# Format all of the manpages to text
+(cd text && make)
+# Format all of the manpages to PDF
+(cd pdf && make)
+# Format all of the manpages to HTML
+(cd html && make)
+# Format all of the manpages to wiki syntax
+(cd wiki && make)
diff --git a/doc/wiki/.ignore_me b/doc/wiki/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/wiki/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/examples/minitar/Makefile b/examples/minitar/Makefile
new file mode 100644
index 000000000000..1ec4593df66b
--- /dev/null
+++ b/examples/minitar/Makefile
@@ -0,0 +1,26 @@
+
+#
+# Adjust the following to control which options minitar gets
+# built with.  See comments in minitar.c for details.
+#
+CFLAGS=				\
+	-DNO_BZIP2_CREATE	\
+	-I../../libarchive	\
+	-g
+
+# How to link against libarchive.
+LIBARCHIVE=	../../libarchive/libarchive.a
+
+all: minitar
+
+minitar: minitar.o
+	cc -g -o minitar minitar.o $(LIBARCHIVE) -lz -lbz2
+	strip minitar
+	ls -l minitar
+
+minitar.o: minitar.c
+
+clean::
+	rm -f *.o
+	rm -f minitar
+	rm -f *~
diff --git a/examples/minitar/README b/examples/minitar/README
new file mode 100644
index 000000000000..83f646cdb313
--- /dev/null
+++ b/examples/minitar/README
@@ -0,0 +1,12 @@
+"minitar" is a minimal example of a program that uses libarchive to
+read/write various archive formats.  It's a more ambitious version of
+'untar.c' that includes compile-time options to enable/disable various
+features, including non-tar formats, archive creation, and automatic
+decompression support.
+
+I use this as a test bed to check for "link pollution," ensuring that
+a program using libarchive does not pull in unnecessary code.
+
+The "minitar" program is also a good starting point for anyone who
+wants to use libarchive for their own purposes, as it demonstrates
+basic usage of the library.
diff --git a/examples/minitar/minitar.c b/examples/minitar/minitar.c
new file mode 100644
index 000000000000..0ff6263ebf84
--- /dev/null
+++ b/examples/minitar/minitar.c
@@ -0,0 +1,458 @@
+/*-
+ * This file is in the public domain.
+ * Do with it as you will.
+ */
+
+/*-
+ * This is a compact "tar" program whose primary goal is small size.
+ * Statically linked, it can be very small indeed.  This serves a number
+ * of goals:
+ *   o a testbed for libarchive (to check for link pollution),
+ *   o a useful tool for space-constrained systems (boot floppies, etc),
+ *   o a place to experiment with new implementation ideas for bsdtar,
+ *   o a small program to demonstrate libarchive usage.
+ *
+ * Use the following macros to suppress features:
+ *   NO_BZIP2 - Implies NO_BZIP2_CREATE and NO_BZIP2_EXTRACT
+ *   NO_BZIP2_CREATE - Suppress bzip2 compression support.
+ *   NO_BZIP2_EXTRACT - Suppress bzip2 auto-detection and decompression.
+ *   NO_COMPRESS - Implies NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT
+ *   NO_COMPRESS_CREATE - Suppress compress(1) compression support
+ *   NO_COMPRESS_EXTRACT - Suppress compress(1) auto-detect and decompression.
+ *   NO_CREATE - Suppress all archive creation support.
+ *   NO_CPIO_EXTRACT - Suppress auto-detect and dearchiving of cpio archives.
+ *   NO_GZIP - Implies NO_GZIP_CREATE and NO_GZIP_EXTRACT
+ *   NO_GZIP_CREATE - Suppress gzip compression support.
+ *   NO_GZIP_EXTRACT - Suppress gzip auto-detection and decompression.
+ *   NO_LOOKUP - Try to avoid getpw/getgr routines, which can be very large
+ *   NO_TAR_EXTRACT - Suppress tar extraction
+ *
+ * With all of the above macros defined (except NO_TAR_EXTRACT), you
+ * get a very small program that can recognize and extract essentially
+ * any uncompressed tar archive.  On FreeBSD 5.1, this minimal program
+ * is under 64k, statically linked, which compares rather favorably to
+ *         main(){printf("hello, world");}
+ * which is over 60k statically linked on the same operating system.
+ * Without any of the above macros, you get a static executable of
+ * about 180k with a lot of very sophisticated modern features.
+ * Obviously, it's trivial to add support for ISO, Zip, mtree,
+ * lzma/xz, etc.  Just fill in the appropriate setup calls.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <archive.h>
+#include <archive_entry.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE.
+ */
+#ifdef NO_CREATE
+#undef NO_BZIP2_CREATE
+#define NO_BZIP2_CREATE
+#undef NO_COMPRESS_CREATE
+#define	NO_COMPRESS_CREATE
+#undef NO_GZIP_CREATE
+#define NO_GZIP_CREATE
+#endif
+
+/*
+ * The combination of NO_BZIP2_CREATE and NO_BZIP2_EXTRACT is
+ * equivalent to NO_BZIP2.
+ */
+#ifdef NO_BZIP2_CREATE
+#ifdef NO_BZIP2_EXTRACT
+#undef NO_BZIP2
+#define NO_BZIP2
+#endif
+#endif
+
+#ifdef NO_BZIP2
+#undef NO_BZIP2_EXTRACT
+#define NO_BZIP2_EXTRACT
+#undef NO_BZIP2_CREATE
+#define NO_BZIP2_CREATE
+#endif
+
+/*
+ * The combination of NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT is
+ * equivalent to NO_COMPRESS.
+ */
+#ifdef NO_COMPRESS_CREATE
+#ifdef NO_COMPRESS_EXTRACT
+#undef NO_COMPRESS
+#define NO_COMPRESS
+#endif
+#endif
+
+#ifdef NO_COMPRESS
+#undef NO_COMPRESS_EXTRACT
+#define NO_COMPRESS_EXTRACT
+#undef NO_COMPRESS_CREATE
+#define NO_COMPRESS_CREATE
+#endif
+
+/*
+ * The combination of NO_GZIP_CREATE and NO_GZIP_EXTRACT is
+ * equivalent to NO_GZIP.
+ */
+#ifdef NO_GZIP_CREATE
+#ifdef NO_GZIP_EXTRACT
+#undef NO_GZIP
+#define NO_GZIP
+#endif
+#endif
+
+#ifdef NO_GZIP
+#undef NO_GZIP_EXTRACT
+#define NO_GZIP_EXTRACT
+#undef NO_GZIP_CREATE
+#define NO_GZIP_CREATE
+#endif
+
+#ifndef NO_CREATE
+static void	create(const char *filename, int compress, const char **argv);
+#endif
+static void	errmsg(const char *);
+static void	extract(const char *filename, int do_extract, int flags);
+static int	copy_data(struct archive *, struct archive *);
+static void	msg(const char *);
+static void	usage(void);
+
+static int verbose = 0;
+
+int
+main(int argc, const char **argv)
+{
+	const char *filename = NULL;
+	int compress, flags, mode, opt;
+
+	(void)argc;
+	mode = 'x';
+	verbose = 0;
+	compress = '\0';
+	flags = ARCHIVE_EXTRACT_TIME;
+
+	/* Among other sins, getopt(3) pulls in printf(3). */
+	while (*++argv != NULL && **argv == '-') {
+		const char *p = *argv + 1;
+
+		while ((opt = *p++) != '\0') {
+			switch (opt) {
+#ifndef NO_CREATE
+			case 'c':
+				mode = opt;
+				break;
+#endif
+			case 'f':
+				if (*p != '\0')
+					filename = p;
+				else
+					filename = *++argv;
+				p += strlen(p);
+				break;
+#ifndef NO_BZIP2_CREATE
+			case 'j':
+				compress = opt;
+				break;
+#endif
+			case 'p':
+				flags |= ARCHIVE_EXTRACT_PERM;
+				flags |= ARCHIVE_EXTRACT_ACL;
+				flags |= ARCHIVE_EXTRACT_FFLAGS;
+				break;
+			case 't':
+				mode = opt;
+				break;
+			case 'v':
+				verbose++;
+				break;
+			case 'x':
+				mode = opt;
+				break;
+#ifndef NO_BZIP2_CREATE
+			case 'y':
+				compress = opt;
+				break;
+#endif
+#ifndef NO_COMPRESS_CREATE
+			case 'Z':
+				compress = opt;
+				break;
+#endif
+#ifndef NO_GZIP_CREATE
+			case 'z':
+				compress = opt;
+				break;
+#endif
+			default:
+				usage();
+			}
+		}
+	}
+
+	switch (mode) {
+#ifndef NO_CREATE
+	case 'c':
+		create(filename, compress, argv);
+		break;
+#endif
+	case 't':
+		extract(filename, 0, flags);
+		break;
+	case 'x':
+		extract(filename, 1, flags);
+		break;
+	}
+
+	return (0);
+}
+
+
+#ifndef NO_CREATE
+static char buff[16384];
+
+static void
+create(const char *filename, int compress, const char **argv)
+{
+	struct archive *a;
+	struct archive *disk;
+	struct archive_entry *entry;
+	ssize_t len;
+	int fd;
+
+	a = archive_write_new();
+	switch (compress) {
+#ifndef NO_BZIP2_CREATE
+	case 'j': case 'y':
+		archive_write_add_filter_bzip2(a);
+		break;
+#endif
+#ifndef NO_COMPRESS_CREATE
+	case 'Z':
+		archive_write_add_filter_compress(a);
+		break;
+#endif
+#ifndef NO_GZIP_CREATE
+	case 'z':
+		archive_write_add_filter_gzip(a);
+		break;
+#endif
+	default:
+		archive_write_add_filter_none(a);
+		break;
+	}
+	archive_write_set_format_ustar(a);
+	if (strcmp(filename, "-") == 0)
+		filename = NULL;
+	archive_write_open_filename(a, filename);
+
+	disk = archive_read_disk_new();
+#ifndef NO_LOOKUP
+	archive_read_disk_set_standard_lookup(disk);
+#endif
+	while (*argv != NULL) {
+		struct archive *disk = archive_read_disk_new();
+		int r;
+
+		r = archive_read_disk_open(disk, *argv);
+		if (r != ARCHIVE_OK) {
+			errmsg(archive_error_string(disk));
+			errmsg("\n");
+			exit(1);
+		}
+
+		for (;;) {
+			int needcr = 0;
+
+			entry = archive_entry_new();
+			r = archive_read_next_header2(disk, entry);
+			if (r == ARCHIVE_EOF)
+				break;
+			if (r != ARCHIVE_OK) {
+				errmsg(archive_error_string(disk));
+				errmsg("\n");
+				exit(1);
+			}
+			archive_read_disk_descend(disk);
+			if (verbose) {
+				msg("a ");
+				msg(archive_entry_pathname(entry));
+				needcr = 1;
+			}
+			r = archive_write_header(a, entry);
+			if (r < ARCHIVE_OK) {
+				errmsg(": ");
+				errmsg(archive_error_string(a));
+				needcr = 1;
+			}
+			if (r == ARCHIVE_FATAL)
+				exit(1);
+			if (r > ARCHIVE_FAILED) {
+#if 0
+				/* Ideally, we would be able to use
+				 * the same code to copy a body from
+				 * an archive_read_disk to an
+				 * archive_write that we use for
+				 * copying data from an archive_read
+				 * to an archive_write_disk.
+				 * Unfortunately, this doesn't quite
+				 * work yet. */
+				copy_data(disk, a);
+#else
+				/* For now, we use a simpler loop to copy data
+				 * into the target archive. */
+				fd = open(archive_entry_sourcepath(entry), O_RDONLY);
+				len = read(fd, buff, sizeof(buff));
+				while (len > 0) {
+					archive_write_data(a, buff, len);
+					len = read(fd, buff, sizeof(buff));
+				}
+				close(fd);
+#endif
+			}
+			archive_entry_free(entry);
+			if (needcr)
+				msg("\n");
+		}
+		archive_read_close(disk);
+		archive_read_free(disk);
+		argv++;
+	}
+	archive_write_close(a);
+	archive_write_free(a);
+}
+#endif
+
+static void
+extract(const char *filename, int do_extract, int flags)
+{
+	struct archive *a;
+	struct archive *ext;
+	struct archive_entry *entry;
+	int r;
+
+	a = archive_read_new();
+	ext = archive_write_disk_new();
+	archive_write_disk_set_options(ext, flags);
+#ifndef NO_BZIP2_EXTRACT
+	archive_read_support_filter_bzip2(a);
+#endif
+#ifndef NO_GZIP_EXTRACT
+	archive_read_support_filter_gzip(a);
+#endif
+#ifndef NO_COMPRESS_EXTRACT
+	archive_read_support_filter_compress(a);
+#endif
+#ifndef NO_TAR_EXTRACT
+	archive_read_support_format_tar(a);
+#endif
+#ifndef NO_CPIO_EXTRACT
+	archive_read_support_format_cpio(a);
+#endif
+#ifndef NO_LOOKUP
+	archive_write_disk_set_standard_lookup(ext);
+#endif
+	if (filename != NULL && strcmp(filename, "-") == 0)
+		filename = NULL;
+	if ((r = archive_read_open_filename(a, filename, 10240))) {
+		errmsg(archive_error_string(a));
+		errmsg("\n");
+		exit(r);
+	}
+	for (;;) {
+		r = archive_read_next_header(a, &entry);
+		if (r == ARCHIVE_EOF)
+			break;
+		if (r != ARCHIVE_OK) {
+			errmsg(archive_error_string(a));
+			errmsg("\n");
+			exit(1);
+		}
+		if (verbose && do_extract)
+			msg("x ");
+		if (verbose || !do_extract)
+			msg(archive_entry_pathname(entry));
+		if (do_extract) {
+			r = archive_write_header(ext, entry);
+			if (r != ARCHIVE_OK)
+				errmsg(archive_error_string(a));
+			else
+				copy_data(a, ext);
+		}
+		if (verbose || !do_extract)
+			msg("\n");
+	}
+	archive_read_close(a);
+	archive_read_free(a);
+	exit(0);
+}
+
+static int
+copy_data(struct archive *ar, struct archive *aw)
+{
+	int r;
+	const void *buff;
+	size_t size;
+	off_t offset;
+
+	for (;;) {
+		r = archive_read_data_block(ar, &buff, &size, &offset);
+		if (r == ARCHIVE_EOF) {
+			errmsg(archive_error_string(ar));
+			return (ARCHIVE_OK);
+		}
+		if (r != ARCHIVE_OK)
+			return (r);
+		r = archive_write_data_block(aw, buff, size, offset);
+		if (r != ARCHIVE_OK) {
+			errmsg(archive_error_string(ar));
+			return (r);
+		}
+	}
+}
+
+static void
+msg(const char *m)
+{
+	write(1, m, strlen(m));
+}
+
+static void
+errmsg(const char *m)
+{
+	write(2, m, strlen(m));
+}
+
+static void
+usage(void)
+{
+/* Many program options depend on compile options. */
+	const char *m = "Usage: minitar [-"
+#ifndef NO_CREATE
+	    "c"
+#endif
+#ifndef	NO_BZIP2
+	    "j"
+#endif
+	    "tvx"
+#ifndef NO_BZIP2
+	    "y"
+#endif
+#ifndef NO_COMPRESS
+	    "Z"
+#endif
+#ifndef NO_GZIP
+	    "z"
+#endif
+	    "] [-f file] [file]\n";
+
+	errmsg(m);
+	exit(1);
+}
diff --git a/examples/tarfilter.c b/examples/tarfilter.c
new file mode 100644
index 000000000000..0d323e1cb2cb
--- /dev/null
+++ b/examples/tarfilter.c
@@ -0,0 +1,113 @@
+/*
+ * This file is in the public domain.
+ *
+ * Feel free to use it as you wish.
+ */
+
+/*
+ * This example program reads an archive from stdin (which can be in
+ * any format recognized by libarchive) and writes certain entries to
+ * an uncompressed ustar archive on stdout.  This is a template for
+ * many kinds of archive manipulation: converting formats, resetting
+ * ownership, inserting entries, removing entries, etc.
+ *
+ * To compile:
+ * gcc -Wall -o tarfilter tarfilter.c -larchive -lz -lbz2
+ */
+
+#include <sys/stat.h>
+#include <archive.h>
+#include <archive_entry.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void
+die(char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+	exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+	char buff[8192];
+	ssize_t len;
+	int r;
+	mode_t m;
+	struct archive *ina;
+	struct archive *outa;
+	struct archive_entry *entry;
+
+	/* Read an archive from stdin, with automatic format detection. */
+	ina = archive_read_new();
+	if (ina == NULL)
+		die("Couldn't create archive reader.");
+	if (archive_read_support_filter_all(ina) != ARCHIVE_OK)
+		die("Couldn't enable decompression");
+	if (archive_read_support_format_all(ina) != ARCHIVE_OK)
+		die("Couldn't enable read formats");
+	if (archive_read_open_fd(ina, 0, 10240) != ARCHIVE_OK)
+		die("Couldn't open input archive");
+
+	/* Write an uncompressed ustar archive to stdout. */
+	outa = archive_write_new();
+	if (outa == NULL)
+		die("Couldn't create archive writer.");
+	if (archive_write_set_compression_none(outa) != ARCHIVE_OK)
+		die("Couldn't enable compression");
+	if (archive_write_set_format_ustar(outa) != ARCHIVE_OK)
+		die("Couldn't set output format");
+	if (archive_write_open_fd(outa, 1) != ARCHIVE_OK)
+		die("Couldn't open output archive");
+
+	/* Examine each entry in the input archive. */
+	while ((r = archive_read_next_header(ina, &entry)) == ARCHIVE_OK) {
+		fprintf(stderr, "%s: ", archive_entry_pathname(entry));
+
+		/* Skip anything that isn't a regular file. */
+		if (!S_ISREG(archive_entry_mode(entry))) {
+			fprintf(stderr, "skipped\n");
+			continue;
+		}
+
+		/* Make everything owned by root/wheel. */
+		archive_entry_set_uid(entry, 0);
+		archive_entry_set_uname(entry, "root");
+		archive_entry_set_gid(entry, 0);
+		archive_entry_set_gname(entry, "wheel");
+
+		/* Make everything permission 0744, strip SUID, etc. */
+		m = archive_entry_mode(entry);
+		archive_entry_set_mode(entry, (m & ~07777) | 0744);
+
+		/* Copy input entries to output archive. */
+		if (archive_write_header(outa, entry) != ARCHIVE_OK)
+			die("Error writing output archive");
+		if (archive_entry_size(entry) > 0) {
+			len = archive_read_data(ina, buff, sizeof(buff));
+			while (len > 0) {
+				if (archive_write_data(outa, buff, len) != len)
+					die("Error writing output archive");
+				len = archive_read_data(ina, buff, sizeof(buff));
+			}
+			if (len < 0)
+				die("Error reading input archive");
+		}
+		fprintf(stderr, "copied\n");
+	}
+	if (r != ARCHIVE_EOF)
+		die("Error reading archive");
+	/* Close the archives.  */
+	if (archive_read_free(ina) != ARCHIVE_OK)
+		die("Error closing input archive");
+	if (archive_write_free(outa) != ARCHIVE_OK)
+		die("Error closing output archive");
+	return (0);
+}
diff --git a/examples/untar.c b/examples/untar.c
new file mode 100644
index 000000000000..b22d8361a012
--- /dev/null
+++ b/examples/untar.c
@@ -0,0 +1,266 @@
+/*
+ * This file is in the public domain.
+ * Use it as you wish.
+ */
+
+/*
+ * This is a compact tar extraction program using libarchive whose
+ * primary goal is small executable size.  Statically linked, it can
+ * be very small, depending in large part on how cleanly factored your
+ * system libraries are.  Note that this uses the standard libarchive,
+ * without any special recompilation.  The only functional concession
+ * is that this program uses the uid/gid from the archive instead of
+ * doing uname/gname lookups.  (Add a call to
+ * archive_write_disk_set_standard_lookup() to enable uname/gname
+ * lookups, but be aware that this can add 500k or more to a static
+ * executable, depending on the system libraries, since user/group
+ * lookups frequently pull in password, YP/LDAP, networking, and DNS
+ * resolver libraries.)
+ *
+ * To build:
+ * $ gcc -static -Wall -o untar untar.c -larchive
+ * $ strip untar
+ *
+ * NOTE: On some systems, you may need to add additional flags
+ * to ensure that untar.c is compiled the same way as libarchive
+ * was compiled.  In particular, Linux users will probably
+ * have to add -D_FILE_OFFSET_BITS=64 to the command line above.
+ *
+ * For fun, statically compile the following simple hello.c program
+ * using the same flags as for untar and compare the size:
+ *
+ * #include <stdio.h>
+ * int main(int argc, char **argv) {
+ *    printf("hello, world\n");
+ *    return(0);
+ * }
+ *
+ * You may be even more surprised by the compiled size of true.c listed here:
+ *
+ * int main(int argc, char **argv) {
+ *    return (0);
+ * }
+ *
+ * On a slightly customized FreeBSD 5 system that I used around
+ * 2005, hello above compiled to 89k compared to untar of 69k.  So at
+ * that time, libarchive's tar reader and extract-to-disk routines
+ * compiled to less code than printf().
+ *
+ * On my FreeBSD development system today (August, 2009):
+ *  hello: 195024 bytes
+ *  true: 194912 bytes
+ *  untar: 259924 bytes
+ */
+
+#include <sys/types.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/stat.h>
+
+#include <archive.h>
+#include <archive_entry.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void	errmsg(const char *);
+static void	extract(const char *filename, int do_extract, int flags);
+static void	fail(const char *, const char *, int);
+static int	copy_data(struct archive *, struct archive *);
+static void	msg(const char *);
+static void	usage(void);
+static void	warn(const char *, const char *);
+
+static int verbose = 0;
+
+int
+main(int argc, const char **argv)
+{
+	const char *filename = NULL;
+	int compress, flags, mode, opt;
+
+	(void)argc;
+	mode = 'x';
+	verbose = 0;
+	compress = '\0';
+	flags = ARCHIVE_EXTRACT_TIME;
+
+	/* Among other sins, getopt(3) pulls in printf(3). */
+	while (*++argv != NULL && **argv == '-') {
+		const char *p = *argv + 1;
+
+		while ((opt = *p++) != '\0') {
+			switch (opt) {
+			case 'f':
+				if (*p != '\0')
+					filename = p;
+				else
+					filename = *++argv;
+				p += strlen(p);
+				break;
+			case 'p':
+				flags |= ARCHIVE_EXTRACT_PERM;
+				flags |= ARCHIVE_EXTRACT_ACL;
+				flags |= ARCHIVE_EXTRACT_FFLAGS;
+				break;
+			case 't':
+				mode = opt;
+				break;
+			case 'v':
+				verbose++;
+				break;
+			case 'x':
+				mode = opt;
+				break;
+			default:
+				usage();
+			}
+		}
+	}
+
+	switch (mode) {
+	case 't':
+		extract(filename, 0, flags);
+		break;
+	case 'x':
+		extract(filename, 1, flags);
+		break;
+	}
+
+	return (0);
+}
+
+
+static void
+extract(const char *filename, int do_extract, int flags)
+{
+	struct archive *a;
+	struct archive *ext;
+	struct archive_entry *entry;
+	int r;
+
+	a = archive_read_new();
+	ext = archive_write_disk_new();
+	archive_write_disk_set_options(ext, flags);
+	/*
+	 * Note: archive_write_disk_set_standard_lookup() is useful
+	 * here, but it requires library routines that can add 500k or
+	 * more to a static executable.
+	 */
+	archive_read_support_format_tar(a);
+	/*
+	 * On my system, enabling other archive formats adds 20k-30k
+	 * each.  Enabling gzip decompression adds about 20k.
+	 * Enabling bzip2 is more expensive because the libbz2 library
+	 * isn't very well factored.
+	 */
+	if (filename != NULL && strcmp(filename, "-") == 0)
+		filename = NULL;
+	if ((r = archive_read_open_filename(a, filename, 10240)))
+		fail("archive_read_open_filename()",
+		    archive_error_string(a), r);
+	for (;;) {
+		r = archive_read_next_header(a, &entry);
+		if (r == ARCHIVE_EOF)
+			break;
+		if (r != ARCHIVE_OK)
+			fail("archive_read_next_header()",
+			    archive_error_string(a), 1);
+		if (verbose && do_extract)
+			msg("x ");
+		if (verbose || !do_extract)
+			msg(archive_entry_pathname(entry));
+		if (do_extract) {
+			r = archive_write_header(ext, entry);
+			if (r != ARCHIVE_OK)
+				warn("archive_write_header()",
+				    archive_error_string(ext));
+			else {
+				copy_data(a, ext);
+				r = archive_write_finish_entry(ext);
+				if (r != ARCHIVE_OK)
+					fail("archive_write_finish_entry()",
+					    archive_error_string(ext), 1);
+			}
+
+		}
+		if (verbose || !do_extract)
+			msg("\n");
+	}
+	archive_read_close(a);
+	archive_read_free(a);
+	exit(0);
+}
+
+static int
+copy_data(struct archive *ar, struct archive *aw)
+{
+	int r;
+	const void *buff;
+	size_t size;
+#if ARCHIVE_VERSION >= 3000000
+	int64_t offset;
+#else
+	off_t offset;
+#endif
+
+	for (;;) {
+		r = archive_read_data_block(ar, &buff, &size, &offset);
+		if (r == ARCHIVE_EOF)
+			return (ARCHIVE_OK);
+		if (r != ARCHIVE_OK)
+			return (r);
+		r = archive_write_data_block(aw, buff, size, offset);
+		if (r != ARCHIVE_OK) {
+			warn("archive_write_data_block()",
+			    archive_error_string(aw));
+			return (r);
+		}
+	}
+}
+
+/*
+ * These reporting functions use low-level I/O; on some systems, this
+ * is a significant code reduction.  Of course, on many server and
+ * desktop operating systems, malloc() and even crt rely on printf(),
+ * which in turn pulls in most of the rest of stdio, so this is not an
+ * optimization at all there.  (If you're going to pay 100k or more
+ * for printf() anyway, you may as well use it!)
+ */
+static void
+msg(const char *m)
+{
+	write(1, m, strlen(m));
+}
+
+static void
+errmsg(const char *m)
+{
+	write(2, m, strlen(m));
+}
+
+static void
+warn(const char *f, const char *m)
+{
+	errmsg(f);
+	errmsg(" failed: ");
+	errmsg(m);
+	errmsg("\n");
+}
+
+static void
+fail(const char *f, const char *m, int r)
+{
+	warn(f, m);
+	exit(r);
+}
+
+static void
+usage(void)
+{
+	const char *m = "Usage: untar [-tvx] [-f file] [file]\n";
+	errmsg(m);
+	exit(1);
+}
diff --git a/libarchive/CMakeLists.txt b/libarchive/CMakeLists.txt
new file mode 100644
index 000000000000..ecb0409bd9d8
--- /dev/null
+++ b/libarchive/CMakeLists.txt
@@ -0,0 +1,193 @@
+
+############################################
+#
+# How to build libarchive
+#
+############################################
+
+# Public headers
+SET(include_HEADERS
+  archive.h
+  archive_entry.h
+)
+
+# Sources and private headers
+SET(libarchive_SOURCES
+  archive_acl.c
+  archive_check_magic.c
+  archive_cmdline.c
+  archive_cmdline_private.h
+  archive_crc32.h
+  archive_crypto.c
+  archive_crypto_private.h
+  archive_endian.h
+  archive_entry.c
+  archive_entry.h
+  archive_entry_copy_stat.c
+  archive_entry_link_resolver.c
+  archive_entry_locale.h
+  archive_entry_private.h
+  archive_entry_sparse.c
+  archive_entry_stat.c
+  archive_entry_strmode.c
+  archive_entry_xattr.c
+  archive_getdate.c
+  archive_match.c
+  archive_options.c
+  archive_options_private.h
+  archive_pathmatch.c
+  archive_pathmatch.h
+  archive_platform.h
+  archive_ppmd_private.h
+  archive_ppmd7.c
+  archive_ppmd7_private.h
+  archive_private.h
+  archive_rb.c
+  archive_rb.h
+  archive_read.c
+  archive_read_append_filter.c
+  archive_read_data_into_fd.c
+  archive_read_disk_entry_from_file.c
+  archive_read_disk_posix.c
+  archive_read_disk_private.h
+  archive_read_disk_set_standard_lookup.c
+  archive_read_extract.c
+  archive_read_open_fd.c
+  archive_read_open_file.c
+  archive_read_open_filename.c
+  archive_read_open_memory.c
+  archive_read_private.h
+  archive_read_set_format.c
+  archive_read_set_options.c
+  archive_read_support_filter_all.c
+  archive_read_support_filter_bzip2.c
+  archive_read_support_filter_compress.c
+  archive_read_support_filter_gzip.c
+  archive_read_support_filter_grzip.c
+  archive_read_support_filter_lrzip.c
+  archive_read_support_filter_lzop.c
+  archive_read_support_filter_none.c
+  archive_read_support_filter_program.c
+  archive_read_support_filter_rpm.c
+  archive_read_support_filter_uu.c
+  archive_read_support_filter_xz.c
+  archive_read_support_format_7zip.c
+  archive_read_support_format_all.c
+  archive_read_support_format_ar.c
+  archive_read_support_format_by_code.c
+  archive_read_support_format_cab.c
+  archive_read_support_format_cpio.c
+  archive_read_support_format_empty.c
+  archive_read_support_format_iso9660.c
+  archive_read_support_format_lha.c
+  archive_read_support_format_mtree.c
+  archive_read_support_format_rar.c
+  archive_read_support_format_raw.c
+  archive_read_support_format_tar.c
+  archive_read_support_format_xar.c
+  archive_read_support_format_zip.c
+  archive_string.c
+  archive_string.h
+  archive_string_composition.h
+  archive_string_sprintf.c
+  archive_util.c
+  archive_virtual.c
+  archive_write.c
+  archive_write_disk_acl.c
+  archive_write_disk_posix.c
+  archive_write_disk_private.h
+  archive_write_disk_set_standard_lookup.c
+  archive_write_private.h
+  archive_write_open_fd.c
+  archive_write_open_file.c
+  archive_write_open_filename.c
+  archive_write_open_memory.c
+  archive_write_add_filter.c
+  archive_write_add_filter_b64encode.c
+  archive_write_add_filter_by_name.c
+  archive_write_add_filter_bzip2.c
+  archive_write_add_filter_compress.c
+  archive_write_add_filter_grzip.c
+  archive_write_add_filter_gzip.c
+  archive_write_add_filter_lrzip.c
+  archive_write_add_filter_lzop.c
+  archive_write_add_filter_none.c
+  archive_write_add_filter_program.c
+  archive_write_add_filter_uuencode.c
+  archive_write_add_filter_xz.c
+  archive_write_set_format.c
+  archive_write_set_format_7zip.c
+  archive_write_set_format_ar.c
+  archive_write_set_format_by_name.c
+  archive_write_set_format_cpio.c
+  archive_write_set_format_cpio_newc.c
+  archive_write_set_format_gnutar.c
+  archive_write_set_format_iso9660.c
+  archive_write_set_format_mtree.c
+  archive_write_set_format_pax.c
+  archive_write_set_format_shar.c
+  archive_write_set_format_ustar.c
+  archive_write_set_format_v7tar.c
+  archive_write_set_format_xar.c
+  archive_write_set_format_zip.c
+  archive_write_set_options.c
+  filter_fork_posix.c
+  filter_fork.h
+)
+
+# Man pages
+SET(libarchive_MANS
+  archive_entry.3
+  archive_entry_acl.3
+  archive_entry_linkify.3
+  archive_entry_paths.3
+  archive_entry_perms.3
+  archive_entry_stat.3
+  archive_entry_time.3
+  archive_read.3
+  archive_read_disk.3
+  archive_read_set_options.3
+  archive_util.3
+  archive_write.3
+  archive_write_disk.3
+  archive_write_set_options.3
+  cpio.5
+  libarchive.3
+  libarchive_internals.3
+  libarchive-formats.5
+  mtree.5
+  tar.5
+)
+
+IF(WIN32 AND NOT CYGWIN)
+  LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c)
+  LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c)
+  LIST(APPEND libarchive_SOURCES archive_windows.c)
+  LIST(APPEND libarchive_SOURCES archive_windows.h)
+  LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c)
+  LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
+ENDIF(WIN32 AND NOT CYGWIN)
+
+# Libarchive is a shared library
+ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
+TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
+SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+
+# archive_static is a static library
+ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
+SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
+  LIBARCHIVE_STATIC)
+# On Posix systems, libarchive.so and libarchive.a can co-exist.
+IF(NOT WIN32 OR CYGWIN)
+  SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
+ENDIF(NOT WIN32 OR CYGWIN)
+
+# How to install the libraries
+INSTALL(TARGETS archive archive_static
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib
+        ARCHIVE DESTINATION lib)
+INSTALL_MAN(${libarchive_MANS})
+INSTALL(FILES ${include_HEADERS} DESTINATION include)
+
+add_subdirectory(test)
diff --git a/libarchive/archive_entry_copy_bhfi.c b/libarchive/archive_entry_copy_bhfi.c
new file mode 100644
index 000000000000..77bf38e450f2
--- /dev/null
+++ b/libarchive/archive_entry_copy_bhfi.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_private.h"
+#include "archive_entry.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+__inline static void
+fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
+{
+	ULARGE_INTEGER utc;
+
+	utc.HighPart = filetime->dwHighDateTime;
+	utc.LowPart  = filetime->dwLowDateTime;
+	if (utc.QuadPart >= EPOC_TIME) {
+		utc.QuadPart -= EPOC_TIME;
+		*t = (time_t)(utc.QuadPart / 10000000);	/* milli seconds base */
+		*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
+	} else {
+		*t = 0;
+		*ns = 0;
+	}
+}
+
+void
+archive_entry_copy_bhfi(struct archive_entry *entry,
+			BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+	time_t secs;
+	long nsecs;
+
+	fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
+	archive_entry_set_atime(entry, secs, nsecs);
+	fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
+	archive_entry_set_mtime(entry, secs, nsecs);
+	fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
+	archive_entry_set_birthtime(entry, secs, nsecs);
+	archive_entry_set_ctime(entry, secs, nsecs);
+	archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
+	archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
+		+ bhfi->nFileIndexLow);
+	archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
+	archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
+		+ bhfi->nFileSizeLow);
+	/* archive_entry_set_mode(entry, st->st_mode); */
+}
+#endif
diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c
new file mode 100644
index 000000000000..9c5420d80e77
--- /dev/null
+++ b/libarchive/archive_read_disk_windows.c
@@ -0,0 +1,2296 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010-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
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <winioctl.h>
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY	0
+#endif
+#ifndef IO_REPARSE_TAG_SYMLINK
+/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
+#define	IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#endif
+
+/*-
+ * 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).
+ */
+
+struct restore_time {
+	const wchar_t		*full_path;
+	FILETIME		 lastWriteTime;
+	FILETIME		 lastAccessTime;
+	mode_t			 filetype;
+};
+
+struct tree_entry {
+	int			 depth;
+	struct tree_entry	*next;
+	struct tree_entry	*parent;
+	size_t			 full_path_dir_length;
+	struct archive_wstring	 name;
+	struct archive_wstring	 full_path;
+	size_t			 dirname_length;
+	int64_t			 dev;
+	int64_t			 ino;
+	int			 flags;
+	int			 filesystem_id;
+	/* How to restore time of a directory. */
+	struct restore_time	 restore_time;
+};
+
+struct filesystem {
+	int64_t		dev;
+	int		synthetic;
+	int		remote;
+	DWORD		bytesPerSector;
+};
+
+/* 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.
+ */
+
+#define MAX_OVERLAPPED	8
+#define BUFFER_SIZE	(1024 * 8)
+#define DIRECT_IO	0/* Disabled */
+#define ASYNC_IO	1/* Enabled */
+
+/*
+ * Local data for this package.
+ */
+struct tree {
+	struct tree_entry	*stack;
+	struct tree_entry	*current;
+	HANDLE d;
+	WIN32_FIND_DATAW	_findData;
+	WIN32_FIND_DATAW	*findData;
+	int			 flags;
+	int			 visit_type;
+	/* Error code from last failed operation. */
+	int			 tree_errno;
+
+	/* A full path with "\\?\" prefix. */
+	struct archive_wstring	 full_path;
+	size_t			 full_path_dir_length;
+	/* Dynamically-sized buffer for holding path */
+	struct archive_wstring	 path;
+
+	/* Last path element */
+	const wchar_t		*basename;
+	/* Leading dir length */
+	size_t			 dirname_length;
+
+	int	 depth;
+
+	BY_HANDLE_FILE_INFORMATION	lst;
+	BY_HANDLE_FILE_INFORMATION	st;
+	int			 descend;
+	/* How to restore time of a file. */
+	struct restore_time	restore_time;
+
+	struct entry_sparse {
+		int64_t		 length;
+		int64_t		 offset;
+	}			*sparse_list, *current_sparse;
+	int			 sparse_count;
+	int			 sparse_list_size;
+
+	char			 initial_symlink_mode;
+	char			 symlink_mode;
+	struct filesystem	*current_filesystem;
+	struct filesystem	*filesystem_table;
+	int			 initial_filesystem_id;
+	int			 current_filesystem_id;
+	int			 max_filesystem_id;
+	int			 allocated_filesytem;
+
+	HANDLE			 entry_fh;
+	int			 entry_eof;
+	int64_t			 entry_remaining_bytes;
+	int64_t			 entry_total;
+
+	int			 ol_idx_doing;
+	int			 ol_idx_done;
+	int			 ol_num_doing;
+	int			 ol_num_done;
+	int64_t			 ol_remaining_bytes;
+	int64_t			 ol_total;
+	struct la_overlapped {
+		OVERLAPPED	 ol;
+		struct archive * _a;
+		unsigned char	*buff;
+		size_t		 buff_size;
+		int64_t		 offset;
+		size_t		 bytes_expected;
+		size_t		 bytes_transferred;
+	}			 ol[MAX_OVERLAPPED];
+	int			 direct_io;
+	int			 async_io;
+};
+
+#define bhfi_dev(bhfi)	((bhfi)->dwVolumeSerialNumber)
+/* Treat FileIndex as i-node. We should remove a sequence number
+ * which is high-16-bits of nFileIndexHigh. */
+#define bhfi_ino(bhfi)	\
+	((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+    + (bhfi)->nFileIndexLow)
+
+/* Definitions for tree.flags bitmap. */
+#define	hasStat		16 /* The st entry is valid. */
+#define	hasLstat	32 /* The lst entry is valid. */
+#define	needsRestoreTimes 128
+
+static int
+tree_dir_next_windows(struct tree *t, const wchar_t *pattern);
+
+/* Initiate/terminate a tree traversal. */
+static struct tree *tree_open(const wchar_t *, int, int);
+static struct tree *tree_reopen(struct tree *, const wchar_t *, int);
+static void tree_close(struct tree *);
+static void tree_free(struct tree *);
+static void tree_push(struct tree *, const wchar_t *, const wchar_t *,
+		int, int64_t, int64_t, struct restore_time *);
+
+/*
+ * tree_next() returns Zero if there is no next entry, non-zero if
+ * there is.  Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit.  If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
+ *
+ * TREE_ERROR_DIR is returned if the descent failed (because the
+ * directory couldn't be opened, for instance).  This is returned
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT.  TREE_ERROR_DIR is not a
+ * fatal error, but it does imply that the relevant subtree won't be
+ * visited.  TREE_ERROR_FATAL is returned for an error that left the
+ * traversal completely hosed.  Right now, this is only returned for
+ * chdir() failures during ascent.
+ */
+#define	TREE_REGULAR		1
+#define	TREE_POSTDESCENT	2
+#define	TREE_POSTASCENT		3
+#define	TREE_ERROR_DIR		-1
+#define	TREE_ERROR_FATAL	-2
+
+static int tree_next(struct tree *);
+
+/*
+ * Return information about the current entry.
+ */
+
+/*
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file.  Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ */
+static const wchar_t *tree_current_path(struct tree *);
+static const wchar_t *tree_current_access_path(struct tree *);
+
+/*
+ * Request the lstat() or stat() data for the current path.  Since the
+ * tree package needs to do some of this anyway, and caches the
+ * results, you should take advantage of it here if you need it rather
+ * than make a redundant stat() or lstat() call of your own.
+ */
+static const BY_HANDLE_FILE_INFORMATION *tree_current_stat(struct tree *);
+static const BY_HANDLE_FILE_INFORMATION *tree_current_lstat(struct tree *);
+
+/* The following functions use tricks to avoid a certain number of
+ * stat()/lstat() calls. */
+/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_dir(struct tree *);
+/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_link(struct tree *);
+/* Instead of archive_entry_copy_stat for BY_HANDLE_FILE_INFORMATION */
+static void tree_archive_entry_copy_bhfi(struct archive_entry *,
+		    struct tree *, const BY_HANDLE_FILE_INFORMATION *);
+/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
+static int tree_current_is_dir(struct tree *);
+static int update_current_filesystem(struct archive_read_disk *a,
+		    int64_t dev);
+static int setup_current_filesystem(struct archive_read_disk *);
+static int tree_target_is_same_as_parent(struct tree *,
+		    const BY_HANDLE_FILE_INFORMATION *);
+
+static int	_archive_read_disk_open_w(struct archive *, const wchar_t *);
+static int	_archive_read_free(struct archive *);
+static int	_archive_read_close(struct archive *);
+static int	_archive_read_data_block(struct archive *,
+		    const void **, size_t *, int64_t *);
+static int	_archive_read_next_header2(struct archive *,
+		    struct archive_entry *);
+static const char *trivial_lookup_gname(void *, int64_t gid);
+static const char *trivial_lookup_uname(void *, int64_t uid);
+static int	setup_sparse(struct archive_read_disk *, struct archive_entry *);
+static int	close_and_restore_time(HANDLE, struct tree *,
+		    struct restore_time *);
+static int	setup_sparse_from_disk(struct archive_read_disk *,
+		    struct archive_entry *, HANDLE);
+
+
+
+static struct archive_vtable *
+archive_read_disk_vtable(void)
+{
+	static struct archive_vtable av;
+	static int inited = 0;
+
+	if (!inited) {
+		av.archive_free = _archive_read_free;
+		av.archive_close = _archive_read_close;
+		av.archive_read_data_block = _archive_read_data_block;
+		av.archive_read_next_header2 = _archive_read_next_header2;
+		inited = 1;
+	}
+	return (&av);
+}
+
+const char *
+archive_read_disk_gname(struct archive *_a, int64_t gid)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+		ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+		return (NULL);
+	if (a->lookup_gname == NULL)
+		return (NULL);
+	return ((*a->lookup_gname)(a->lookup_gname_data, gid));
+}
+
+const char *
+archive_read_disk_uname(struct archive *_a, int64_t uid)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+		ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+		return (NULL);
+	if (a->lookup_uname == NULL)
+		return (NULL);
+	return ((*a->lookup_uname)(a->lookup_uname_data, uid));
+}
+
+int
+archive_read_disk_set_gname_lookup(struct archive *_a,
+    void *private_data,
+    const char * (*lookup_gname)(void *private, int64_t gid),
+    void (*cleanup_gname)(void *private))
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
+
+	if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+		(a->cleanup_gname)(a->lookup_gname_data);
+
+	a->lookup_gname = lookup_gname;
+	a->cleanup_gname = cleanup_gname;
+	a->lookup_gname_data = private_data;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_uname_lookup(struct archive *_a,
+    void *private_data,
+    const char * (*lookup_uname)(void *private, int64_t uid),
+    void (*cleanup_uname)(void *private))
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
+
+	if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+		(a->cleanup_uname)(a->lookup_uname_data);
+
+	a->lookup_uname = lookup_uname;
+	a->cleanup_uname = cleanup_uname;
+	a->lookup_uname_data = private_data;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Create a new archive_read_disk object and initialize it with global state.
+ */
+struct archive *
+archive_read_disk_new(void)
+{
+	struct archive_read_disk *a;
+
+	a = (struct archive_read_disk *)malloc(sizeof(*a));
+	if (a == NULL)
+		return (NULL);
+	memset(a, 0, sizeof(*a));
+	a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
+	a->archive.state = ARCHIVE_STATE_NEW;
+	a->archive.vtable = archive_read_disk_vtable();
+	a->lookup_uname = trivial_lookup_uname;
+	a->lookup_gname = trivial_lookup_gname;
+	a->enable_copyfile = 1;
+	a->traverse_mount_points = 1;
+	return (&a->archive);
+}
+
+static int
+_archive_read_free(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	int r;
+
+	if (_a == NULL)
+		return (ARCHIVE_OK);
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+
+	if (a->archive.state != ARCHIVE_STATE_CLOSED)
+		r = _archive_read_close(&a->archive);
+	else
+		r = ARCHIVE_OK;
+
+	tree_free(a->tree);
+	if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+		(a->cleanup_gname)(a->lookup_gname_data);
+	if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+		(a->cleanup_uname)(a->lookup_uname_data);
+	archive_string_free(&a->archive.error_string);
+	a->archive.magic = 0;
+	free(a);
+	return (r);
+}
+
+static int
+_archive_read_close(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+
+	if (a->archive.state != ARCHIVE_STATE_FATAL)
+		a->archive.state = ARCHIVE_STATE_CLOSED;
+
+	tree_close(a->tree);
+
+	return (ARCHIVE_OK);
+}
+
+static void
+setup_symlink_mode(struct archive_read_disk *a, char symlink_mode, 
+    int follow_symlinks)
+{
+	a->symlink_mode = symlink_mode;
+	a->follow_symlinks = follow_symlinks;
+	if (a->tree != NULL) {
+		a->tree->initial_symlink_mode = a->symlink_mode;
+		a->tree->symlink_mode = a->symlink_mode;
+	}
+}
+
+int
+archive_read_disk_set_symlink_logical(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
+	setup_symlink_mode(a, 'L', 1);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_physical(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
+	setup_symlink_mode(a, 'P', 0);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_hybrid(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
+	setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_atime_restored(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
+	a->restore_time = 1;
+	if (a->tree != NULL)
+		a->tree->flags |= needsRestoreTimes;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_behavior(struct archive *_a, int flags)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	int r = 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 = archive_read_disk_set_atime_restored(_a);
+	else {
+		a->restore_time = 0;
+		if (a->tree != NULL)
+			a->tree->flags &= ~needsRestoreTimes;
+	}
+	if (flags & ARCHIVE_READDISK_HONOR_NODUMP)
+		a->honor_nodump = 1;
+	else
+		a->honor_nodump = 0;
+	if (flags & ARCHIVE_READDISK_MAC_COPYFILE)
+		a->enable_copyfile = 1;
+	else
+		a->enable_copyfile = 0;
+	if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
+		a->traverse_mount_points = 0;
+	else
+		a->traverse_mount_points = 1;
+	return (r);
+}
+
+/*
+ * Trivial implementations of gname/uname lookup functions.
+ * These are normally overridden by the client, but these stub
+ * versions ensure that we always have something that works.
+ */
+static const char *
+trivial_lookup_gname(void *private_data, int64_t gid)
+{
+	(void)private_data; /* UNUSED */
+	(void)gid; /* UNUSED */
+	return (NULL);
+}
+
+static const char *
+trivial_lookup_uname(void *private_data, int64_t uid)
+{
+	(void)private_data; /* UNUSED */
+	(void)uid; /* UNUSED */
+	return (NULL);
+}
+
+static int64_t
+align_num_per_sector(struct tree *t, int64_t size)
+{
+	int64_t surplus;
+
+	size += t->current_filesystem->bytesPerSector -1;
+	surplus = size % t->current_filesystem->bytesPerSector;
+	size -= surplus;
+	return (size);
+}
+
+static int
+start_next_async_read(struct archive_read_disk *a, struct tree *t)
+{
+	struct la_overlapped *olp;
+	DWORD buffbytes, rbytes;
+
+	if (t->ol_remaining_bytes == 0)
+		return (ARCHIVE_EOF);
+
+	olp = &(t->ol[t->ol_idx_doing]);
+	t->ol_idx_doing = (t->ol_idx_doing + 1) % MAX_OVERLAPPED;
+
+	/* Allocate read buffer. */
+	if (olp->buff == NULL) {
+		void *p;
+		size_t s = (size_t)align_num_per_sector(t, BUFFER_SIZE);
+		p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
+		if (p == NULL) {
+			archive_set_error(&a->archive, ENOMEM,
+			    "Couldn't allocate memory");
+			a->archive.state = ARCHIVE_STATE_FATAL;
+			return (ARCHIVE_FATAL);
+		}
+		olp->buff = p;
+		olp->buff_size = s;
+		olp->_a = &a->archive;
+		olp->ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
+		if (olp->ol.hEvent == NULL) {
+			la_dosmaperr(GetLastError());
+			archive_set_error(&a->archive, errno,
+			    "CreateEvent failed");
+			a->archive.state = ARCHIVE_STATE_FATAL;
+			return (ARCHIVE_FATAL);
+		}
+	} else
+		ResetEvent(olp->ol.hEvent);
+
+	buffbytes = (DWORD)olp->buff_size;
+	if (buffbytes > t->current_sparse->length)
+		buffbytes = (DWORD)t->current_sparse->length;
+
+	/* Skip hole. */
+	if (t->current_sparse->offset > t->ol_total) {
+		t->ol_remaining_bytes -=
+			t->current_sparse->offset - t->ol_total;
+	}
+
+	olp->offset = t->current_sparse->offset;
+	olp->ol.Offset = (DWORD)(olp->offset & 0xffffffff);
+	olp->ol.OffsetHigh = (DWORD)(olp->offset >> 32);
+
+	if (t->ol_remaining_bytes > buffbytes) {
+		olp->bytes_expected = buffbytes;
+		t->ol_remaining_bytes -= buffbytes;
+	} else {
+		olp->bytes_expected = (size_t)t->ol_remaining_bytes;
+		t->ol_remaining_bytes = 0;
+	}
+	olp->bytes_transferred = 0;
+	t->current_sparse->offset += buffbytes;
+	t->current_sparse->length -= buffbytes;
+	t->ol_total = t->current_sparse->offset;
+	if (t->current_sparse->length == 0 && t->ol_remaining_bytes > 0)
+		t->current_sparse++;
+
+	if (!ReadFile(t->entry_fh, olp->buff, buffbytes, &rbytes, &(olp->ol))) {
+		DWORD lasterr;
+
+		lasterr = GetLastError();
+		if (lasterr == ERROR_HANDLE_EOF) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Reading file truncated");
+			a->archive.state = ARCHIVE_STATE_FATAL;
+			return (ARCHIVE_FATAL);
+		} else if (lasterr != ERROR_IO_PENDING) {
+			if (lasterr == ERROR_NO_DATA)
+				errno = EAGAIN;
+			else if (lasterr == ERROR_ACCESS_DENIED)
+				errno = EBADF;
+			else
+				la_dosmaperr(lasterr);
+			archive_set_error(&a->archive, errno, "Read error");
+			a->archive.state = ARCHIVE_STATE_FATAL;
+			return (ARCHIVE_FATAL);
+		}
+	} else
+		olp->bytes_transferred = rbytes;
+	t->ol_num_doing++;
+
+	return (t->ol_remaining_bytes == 0)? ARCHIVE_EOF: ARCHIVE_OK;
+}
+
+static void
+cancel_async(struct tree *t)
+{
+	if (t->ol_num_doing != t->ol_num_done) {
+		CancelIo(t->entry_fh);
+		t->ol_num_doing = t->ol_num_done = 0;
+	}
+}
+
+static int
+_archive_read_data_block(struct archive *_a, const void **buff,
+    size_t *size, int64_t *offset)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	struct tree *t = a->tree;
+	struct la_overlapped *olp;
+	DWORD bytes_transferred;
+	int r = ARCHIVE_FATAL;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+	    "archive_read_data_block");
+
+	if (t->entry_eof || t->entry_remaining_bytes <= 0) {
+		r = ARCHIVE_EOF;
+		goto abort_read_data;
+	}
+
+	/*
+	 * Make a request to read the file in asynchronous.
+	 */
+	if (t->ol_num_doing == 0) {
+		do {
+			r = start_next_async_read(a, t);
+			if (r == ARCHIVE_FATAL)
+				goto abort_read_data;
+			if (!t->async_io)
+				break;
+		} while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED);
+	} else {
+		if (start_next_async_read(a, t) == ARCHIVE_FATAL)
+			goto abort_read_data;
+	}
+
+	olp = &(t->ol[t->ol_idx_done]);
+	t->ol_idx_done = (t->ol_idx_done + 1) % MAX_OVERLAPPED;
+	if (olp->bytes_transferred)
+		bytes_transferred = (DWORD)olp->bytes_transferred;
+	else if (!GetOverlappedResult(t->entry_fh, &(olp->ol),
+	    &bytes_transferred, TRUE)) {
+		la_dosmaperr(GetLastError());
+		archive_set_error(&a->archive, errno,
+		    "GetOverlappedResult failed");
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		r = ARCHIVE_FATAL;
+		goto abort_read_data;
+	}
+	t->ol_num_done++;
+
+	if (bytes_transferred == 0 ||
+	    olp->bytes_expected != bytes_transferred) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Reading file truncated");
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		r = ARCHIVE_FATAL;
+		goto abort_read_data;
+	}
+
+	*buff = olp->buff;
+	*size = bytes_transferred;
+	*offset = olp->offset;
+	if (olp->offset > t->entry_total)
+		t->entry_remaining_bytes -= olp->offset - t->entry_total;
+	t->entry_total = olp->offset + *size;
+	t->entry_remaining_bytes -= *size;
+	if (t->entry_remaining_bytes == 0) {
+		/* Close the current file descriptor */
+		close_and_restore_time(t->entry_fh, t, &t->restore_time);
+		t->entry_fh = INVALID_HANDLE_VALUE;
+		t->entry_eof = 1;
+	}
+	return (ARCHIVE_OK);
+
+abort_read_data:
+	*buff = NULL;
+	*size = 0;
+	*offset = t->entry_total;
+	if (t->entry_fh != INVALID_HANDLE_VALUE) {
+		cancel_async(t);
+		/* Close the current file descriptor */
+		close_and_restore_time(t->entry_fh, t, &t->restore_time);
+		t->entry_fh = INVALID_HANDLE_VALUE;
+	}
+	return (r);
+}
+
+static int
+next_entry(struct archive_read_disk *a, struct tree *t,
+    struct archive_entry *entry)
+{
+	const BY_HANDLE_FILE_INFORMATION *st;
+	const BY_HANDLE_FILE_INFORMATION *lst;
+	const char*name;
+	int descend, r;
+
+	st = NULL;
+	lst = NULL;
+	t->descend = 0;
+	do {
+		switch (tree_next(t)) {
+		case TREE_ERROR_FATAL:
+			archive_set_error(&a->archive, t->tree_errno,
+			    "%ls: Unable to continue traversing directory tree",
+			    tree_current_path(t));
+			a->archive.state = ARCHIVE_STATE_FATAL;
+			return (ARCHIVE_FATAL);
+		case TREE_ERROR_DIR:
+			archive_set_error(&a->archive, t->tree_errno,
+			    "%ls: Couldn't visit directory",
+			    tree_current_path(t));
+			return (ARCHIVE_FAILED);
+		case 0:
+			return (ARCHIVE_EOF);
+		case TREE_POSTDESCENT:
+		case TREE_POSTASCENT:
+			break;
+		case TREE_REGULAR:
+			lst = tree_current_lstat(t);
+			if (lst == NULL) {
+				archive_set_error(&a->archive, t->tree_errno,
+				    "%ls: Cannot stat",
+				    tree_current_path(t));
+				return (ARCHIVE_FAILED);
+			}
+			break;
+		}	
+	} while (lst == NULL);
+
+	archive_entry_copy_pathname_w(entry, tree_current_path(t));
+
+	/*
+	 * Perform path matching.
+	 */
+	if (a->matching) {
+		r = 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.
+	 */
+	switch(t->symlink_mode) {
+	case 'H':
+		/* 'H': After the first item, rest like 'P'. */
+		t->symlink_mode = 'P';
+		/* 'H': First item (from command line) like 'L'. */
+		/* FALLTHROUGH */
+	case 'L':
+		/* 'L': Do descend through a symlink to dir. */
+		descend = tree_current_is_dir(t);
+		/* 'L': Follow symlinks to files. */
+		a->symlink_mode = 'L';
+		a->follow_symlinks = 1;
+		/* 'L': Archive symlinks as targets, if we can. */
+		st = tree_current_stat(t);
+		if (st != NULL && !tree_target_is_same_as_parent(t, st))
+			break;
+		/* If stat fails, we have a broken symlink;
+		 * in that case, don't follow the link. */
+		/* FALLTHROUGH */
+	default:
+		/* 'P': Don't descend through a symlink to dir. */
+		descend = tree_current_is_physical_dir(t);
+		/* 'P': Don't follow symlinks to files. */
+		a->symlink_mode = 'P';
+		a->follow_symlinks = 0;
+		/* 'P': Archive symlinks as symlinks. */
+		st = lst;
+		break;
+	}
+
+	if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) {
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	if (t->initial_filesystem_id == -1)
+		t->initial_filesystem_id = t->current_filesystem_id;
+	if (!a->traverse_mount_points) {
+		if (t->initial_filesystem_id != t->current_filesystem_id)
+			return (ARCHIVE_RETRY);
+	}
+	t->descend = descend;
+
+	tree_archive_entry_copy_bhfi(entry, t, st);
+
+	/* 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.lastWriteTime = st->ftLastWriteTime;
+	t->restore_time.lastAccessTime = st->ftLastAccessTime;
+	t->restore_time.filetype = archive_entry_filetype(entry);
+
+	/*
+	 * Perform time matching.
+	 */
+	if (a->matching) {
+		r = 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);
+		}
+	}
+
+	/* Lookup uname/gname */
+	name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
+	if (name != NULL)
+		archive_entry_copy_uname(entry, name);
+	name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
+	if (name != NULL)
+		archive_entry_copy_gname(entry, name);
+
+	/*
+	 * Perform owner matching.
+	 */
+	if (a->matching) {
+		r = 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);
+	}
+
+	archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
+
+	r = ARCHIVE_OK;
+	if (archive_entry_filetype(entry) == AE_IFREG &&
+	    archive_entry_size(entry) > 0) {
+		DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
+		if (t->async_io)
+			flags |= FILE_FLAG_OVERLAPPED;
+		if (t->direct_io)
+			flags |= FILE_FLAG_NO_BUFFERING;
+		else
+			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
+		t->entry_fh = CreateFileW(tree_current_access_path(t),
+		    GENERIC_READ, 0, NULL, OPEN_EXISTING, flags, NULL);
+		if (t->entry_fh == INVALID_HANDLE_VALUE) {
+			archive_set_error(&a->archive, errno,
+			    "Couldn't open %ls", tree_current_path(a->tree));
+			return (ARCHIVE_FAILED);
+		}
+
+		/* Find sparse data from the disk. */
+		if (archive_entry_hardlink(entry) == NULL &&
+		    (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0)
+			r = setup_sparse_from_disk(a, entry, t->entry_fh);
+	}
+	return (r);
+}
+
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	struct tree *t;
+	int r;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_read_next_header2");
+
+	t = a->tree;
+	if (t->entry_fh != INVALID_HANDLE_VALUE) {
+		cancel_async(t);
+		close_and_restore_time(t->entry_fh, t, &t->restore_time);
+		t->entry_fh = INVALID_HANDLE_VALUE;
+	}
+
+	while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY)
+		archive_entry_clear(entry);
+
+	/*
+	 * EOF and FATAL are persistent at this layer.  By
+	 * modifying the state, we guarantee that future calls to
+	 * read a header or read data will fail.
+	 */
+	switch (r) {
+	case ARCHIVE_EOF:
+		a->archive.state = ARCHIVE_STATE_EOF;
+		break;
+	case ARCHIVE_OK:
+	case ARCHIVE_WARN:
+		t->entry_total = 0;
+		if (archive_entry_filetype(entry) == AE_IFREG) {
+			t->entry_remaining_bytes = archive_entry_size(entry);
+			t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
+			if (!t->entry_eof &&
+			    setup_sparse(a, entry) != ARCHIVE_OK)
+				return (ARCHIVE_FATAL);
+		} else {
+			t->entry_remaining_bytes = 0;
+			t->entry_eof = 1;
+		}
+		t->ol_idx_doing = t->ol_idx_done = 0;
+		t->ol_num_doing = t->ol_num_done = 0;
+		t->ol_remaining_bytes = t->entry_remaining_bytes;
+		t->ol_total = 0;
+		a->archive.state = ARCHIVE_STATE_DATA;
+		break;
+	case ARCHIVE_RETRY:
+		break;
+	case ARCHIVE_FATAL:
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		break;
+	}
+
+	return (r);
+}
+
+static int
+setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
+{
+	struct tree *t = a->tree;
+	int64_t aligned, length, offset;
+	int i;
+
+	t->sparse_count = archive_entry_sparse_reset(entry);
+	if (t->sparse_count+1 > t->sparse_list_size) {
+		free(t->sparse_list);
+		t->sparse_list_size = t->sparse_count + 1;
+		t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
+		    t->sparse_list_size);
+		if (t->sparse_list == NULL) {
+			t->sparse_list_size = 0;
+			archive_set_error(&a->archive, ENOMEM,
+			    "Can't allocate data");
+			a->archive.state = ARCHIVE_STATE_FATAL;
+			return (ARCHIVE_FATAL);
+		}
+	}
+	/*
+	 * Get sparse list and make sure those offsets and lengths are
+	 * aligned by a sector size.
+	 */
+	for (i = 0; i < t->sparse_count; i++) {
+		archive_entry_sparse_next(entry, &offset, &length);
+		aligned = align_num_per_sector(t, offset);
+		if (aligned != offset) {
+			aligned -= t->current_filesystem->bytesPerSector;
+			length += offset - aligned;
+		}
+		t->sparse_list[i].offset = aligned;
+		aligned = align_num_per_sector(t, length);
+		t->sparse_list[i].length = aligned;
+	}
+
+	aligned = align_num_per_sector(t, archive_entry_size(entry));
+	if (i == 0) {
+		t->sparse_list[i].offset = 0;
+		t->sparse_list[i].length = aligned;
+	} else {
+		int j, last = i;
+
+		t->sparse_list[i].offset = aligned;
+		t->sparse_list[i].length = 0;
+		for (i = 0; i < last; i++) {
+			if ((t->sparse_list[i].offset +
+			       t->sparse_list[i].length) <= 
+					t->sparse_list[i+1].offset)
+				continue;
+			/*
+			 * Now sparse_list[i+1] is overlapped by sparse_list[i].
+			 * Merge those two.
+			 */
+			length = t->sparse_list[i+1].offset -
+					t->sparse_list[i].offset;
+			t->sparse_list[i+1].offset = t->sparse_list[i].offset;
+			t->sparse_list[i+1].length += length;
+			/* Remove sparse_list[i]. */
+			for (j = i; j < last; j++) {
+				t->sparse_list[j].offset =
+				    t->sparse_list[j+1].offset;
+				t->sparse_list[j].length =
+				    t->sparse_list[j+1].length;
+			}
+			last--;
+		}
+	}
+	t->current_sparse = t->sparse_list;
+
+	return (ARCHIVE_OK);
+}
+
+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 = (struct archive_read_disk *)_a;
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
+	a->matching = _ma;
+	a->excluded_cb_func = _excluded_func;
+	a->excluded_cb_data = _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 = (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 = _metadata_filter_func;
+	a->metadata_filter_data = _client_data;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_can_descend(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	struct tree *t = a->tree;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_read_disk_can_descend");
+
+	return (t->visit_type == TREE_REGULAR && t->descend);
+}
+
+/*
+ * Called by the client to mark the directory just returned from
+ * tree_next() as needing to be visited.
+ */
+int
+archive_read_disk_descend(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	struct tree *t = a->tree;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_read_disk_descend");
+
+	if (t->visit_type != TREE_REGULAR || !t->descend)
+		return (ARCHIVE_OK);
+
+	if (tree_current_is_physical_dir(t)) {
+		tree_push(t, t->basename, t->full_path.s,
+		    t->current_filesystem_id,
+		    bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)),
+		    &t->restore_time);
+		t->stack->flags |= isDir;
+	} else if (tree_current_is_dir(t)) {
+		tree_push(t, t->basename, t->full_path.s,
+		    t->current_filesystem_id,
+		    bhfi_dev(&(t->st)), bhfi_ino(&(t->st)),
+		    &t->restore_time);
+		t->stack->flags |= isDirLink;
+	}
+	t->descend = 0;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	struct archive_wstring wpath;
+	int ret;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+	    "archive_read_disk_open");
+	archive_clear_error(&a->archive);
+
+	/* Make a wchar_t string from a char string. */
+	archive_string_init(&wpath);
+	if (archive_wstring_append_from_mbs(&wpath, pathname,
+	    strlen(pathname)) != 0) {
+		if (errno == 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 wchar_t string");
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		ret = ARCHIVE_FATAL;
+	} else
+		ret = _archive_read_disk_open_w(_a, wpath.s);
+
+	archive_wstring_free(&wpath);
+	return (ret);
+}
+
+int
+archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+	    ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+	    "archive_read_disk_open_w");
+	archive_clear_error(&a->archive);
+
+	return (_archive_read_disk_open_w(_a, pathname));
+}
+
+static int
+_archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+	if (a->tree != NULL)
+		a->tree = tree_reopen(a->tree, pathname, a->restore_time);
+	else
+		a->tree = tree_open(pathname, a->symlink_mode, a->restore_time);
+	if (a->tree == NULL) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "Can't allocate directory traversal data");
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	a->archive.state = ARCHIVE_STATE_HEADER;
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Return a current filesystem ID which is index of the filesystem entry
+ * you've visited through archive_read_disk.
+ */
+int
+archive_read_disk_current_filesystem(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+	    "archive_read_disk_current_filesystem");
+
+	return (a->tree->current_filesystem_id);
+}
+
+static int
+update_current_filesystem(struct archive_read_disk *a, int64_t dev)
+{
+	struct tree *t = a->tree;
+	int i, fid;
+
+	if (t->current_filesystem != NULL &&
+	    t->current_filesystem->dev == dev)
+		return (ARCHIVE_OK);
+
+	for (i = 0; i < t->max_filesystem_id; i++) {
+		if (t->filesystem_table[i].dev == dev) {
+			/* There is the filesytem ID we've already generated. */
+			t->current_filesystem_id = i;
+			t->current_filesystem = &(t->filesystem_table[i]);
+			return (ARCHIVE_OK);
+		}
+	}
+
+	/*
+	 * There is a new filesytem, we generate a new ID for.
+	 */
+	fid = t->max_filesystem_id++;
+	if (t->max_filesystem_id > t->allocated_filesytem) {
+		size_t s;
+		void *p;
+
+		s = t->max_filesystem_id * 2;
+		p = realloc(t->filesystem_table,
+			s * sizeof(*t->filesystem_table));
+		if (p == NULL) {
+			archive_set_error(&a->archive, ENOMEM,
+			    "Can't allocate tar data");
+			return (ARCHIVE_FATAL);
+		}
+		t->filesystem_table = (struct filesystem *)p;
+		t->allocated_filesytem = (int)s;
+	}
+	t->current_filesystem_id = fid;
+	t->current_filesystem = &(t->filesystem_table[fid]);
+	t->current_filesystem->dev = dev;
+
+	return (setup_current_filesystem(a));
+}
+
+/*
+ * Returns 1 if current filesystem is generated filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+	    "archive_read_disk_current_filesystem");
+
+	return (a->tree->current_filesystem->synthetic);
+}
+
+/*
+ * Returns 1 if current filesystem is remote filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_remote(struct archive *_a)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+	    "archive_read_disk_current_filesystem");
+
+	return (a->tree->current_filesystem->remote);
+}
+
+/*
+ * If symlink is broken, statfs or statvfs will fail.
+ * Use its directory path instead.
+ */
+static wchar_t *
+safe_path_for_statfs(struct tree *t)
+{
+	const wchar_t *path;
+	wchar_t *cp, *p = NULL;
+
+	path = tree_current_access_path(t);
+	if (tree_current_stat(t) == NULL) {
+		p = _wcsdup(path);
+		cp = wcsrchr(p, '/');
+		if (cp != NULL && wcslen(cp) >= 2) {
+			cp[1] = '.';
+			cp[2] = '\0';
+			path = p;
+		}
+	} else
+		p = _wcsdup(path);
+	return (p);
+}
+
+/*
+ * Get conditions of synthetic and remote on Windows
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+	struct tree *t = a->tree;
+	wchar_t vol[256];
+	wchar_t *path;
+
+	t->current_filesystem->synthetic = -1;/* Not supported */
+	path = safe_path_for_statfs(t);
+	if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
+		free(path);
+		t->current_filesystem->remote = -1;
+		t->current_filesystem->bytesPerSector = 0;
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                        "GetVolumePathName failed: %d", (int)GetLastError());
+		return (ARCHIVE_FAILED);
+	}
+	free(path);
+	switch (GetDriveTypeW(vol)) {
+	case DRIVE_UNKNOWN:
+	case DRIVE_NO_ROOT_DIR:
+		t->current_filesystem->remote = -1;
+		break;
+	case DRIVE_REMOTE:
+		t->current_filesystem->remote = 1;
+		break;
+	default:
+		t->current_filesystem->remote = 0;
+		break;
+	}
+
+	if (!GetDiskFreeSpaceW(vol, NULL,
+	    &(t->current_filesystem->bytesPerSector), NULL, NULL)) {
+		t->current_filesystem->bytesPerSector = 0;
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                        "GetDiskFreeSpace failed: %d", (int)GetLastError());
+		return (ARCHIVE_FAILED);
+	}
+
+	return (ARCHIVE_OK);
+}
+
+static int
+close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
+{
+	HANDLE handle;
+	int r = 0;
+
+	if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
+		return (0);
+
+	/* Close a file descritor.
+	 * It will not be used for SetFileTime() because it has been opened
+	 * by a read only mode.
+	 */
+	if (h != INVALID_HANDLE_VALUE)
+		CloseHandle(h);
+	if ((t->flags & needsRestoreTimes) == 0)
+		return (r);
+
+	handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
+		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+	if (handle == INVALID_HANDLE_VALUE) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (SetFileTime(handle, NULL, &rt->lastAccessTime,
+	    &rt->lastWriteTime) == 0) {
+		errno = EINVAL;
+		r = -1;
+	} else
+		r = 0;
+	CloseHandle(handle);
+	return (r);
+}
+
+/*
+ * Add a directory path to the current stack.
+ */
+static void
+tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
+    int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt)
+{
+	struct tree_entry *te;
+
+	te = malloc(sizeof(*te));
+	memset(te, 0, sizeof(*te));
+	te->next = t->stack;
+	te->parent = t->current;
+	if (te->parent)
+		te->depth = te->parent->depth + 1;
+	t->stack = te;
+	archive_string_init(&te->name);
+	archive_wstrcpy(&te->name, path);
+	archive_string_init(&te->full_path);
+	archive_wstrcpy(&te->full_path, full_path);
+	te->flags = needsDescent | needsOpen | needsAscent;
+	te->filesystem_id = filesystem_id;
+	te->dev = dev;
+	te->ino = ino;
+	te->dirname_length = t->dirname_length;
+	te->full_path_dir_length = t->full_path_dir_length;
+	te->restore_time.full_path = te->full_path.s;
+	if (rt != NULL) {
+		te->restore_time.lastWriteTime = rt->lastWriteTime;
+		te->restore_time.lastAccessTime = rt->lastAccessTime;
+		te->restore_time.filetype = rt->filetype;
+	}
+}
+
+/*
+ * Append a name to the current dir path.
+ */
+static void
+tree_append(struct tree *t, const wchar_t *name, size_t name_length)
+{
+	size_t size_needed;
+
+	t->path.s[t->dirname_length] = L'\0';
+	t->path.length = t->dirname_length;
+	/* Strip trailing '/' from name, unless entire name is "/". */
+	while (name_length > 1 && name[name_length - 1] == L'/')
+		name_length--;
+
+	/* Resize pathname buffer as needed. */
+	size_needed = name_length + t->dirname_length + 2;
+	archive_wstring_ensure(&t->path, size_needed);
+	/* Add a separating '/' if it's needed. */
+	if (t->dirname_length > 0 &&
+	    t->path.s[archive_strlen(&t->path)-1] != L'/')
+		archive_wstrappend_wchar(&t->path, L'/');
+	t->basename = t->path.s + archive_strlen(&t->path);
+	archive_wstrncat(&t->path, name, name_length);
+	t->restore_time.full_path = t->basename;
+	if (t->full_path_dir_length > 0) {
+		t->full_path.s[t->full_path_dir_length] = L'\0';
+		t->full_path.length = t->full_path_dir_length;
+		size_needed = name_length + t->full_path_dir_length + 2;
+		archive_wstring_ensure(&t->full_path, size_needed);
+		/* Add a separating '\' if it's needed. */
+		if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
+			archive_wstrappend_wchar(&t->full_path, L'\\');
+		archive_wstrncat(&t->full_path, name, name_length);
+		t->restore_time.full_path = t->full_path.s;
+	}
+}
+
+/*
+ * Open a directory tree for traversal.
+ */
+static struct tree *
+tree_open(const wchar_t *path, int symlink_mode, int restore_time)
+{
+	struct tree *t;
+
+	t = malloc(sizeof(*t));
+	memset(t, 0, sizeof(*t));
+	archive_string_init(&(t->full_path));
+	archive_string_init(&t->path);
+	archive_wstring_ensure(&t->path, 15);
+	t->initial_symlink_mode = symlink_mode;
+	return (tree_reopen(t, path, restore_time));
+}
+
+static struct tree *
+tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
+{
+	struct archive_wstring ws;
+	wchar_t *pathname, *p, *base;
+
+	t->flags = (restore_time)?needsRestoreTimes:0;
+	t->visit_type = 0;
+	t->tree_errno = 0;
+	t->full_path_dir_length = 0;
+	t->dirname_length = 0;
+	t->depth = 0;
+	t->descend = 0;
+	t->current = NULL;
+	t->d = INVALID_HANDLE_VALUE;
+	t->symlink_mode = t->initial_symlink_mode;
+	archive_string_empty(&(t->full_path));
+	archive_string_empty(&t->path);
+	t->entry_fh = INVALID_HANDLE_VALUE;
+	t->entry_eof = 0;
+	t->entry_remaining_bytes = 0;
+	t->initial_filesystem_id = -1;
+
+	/* Get wchar_t strings from char strings. */
+	archive_string_init(&ws);
+	archive_wstrcpy(&ws, path);
+	pathname = ws.s;
+	/* Get a full-path-name. */
+	p = __la_win_permissive_name_w(pathname);
+	if (p == NULL)
+		goto failed;
+	archive_wstrcpy(&(t->full_path), p);
+	free(p);
+
+	/* Convert path separators from '\' to '/' */
+	for (p = pathname; *p != L'\0'; ++p) {
+		if (*p == L'\\')
+			*p = L'/';
+	}
+	base = pathname;
+
+	/* First item is set up a lot like a symlink traversal. */
+	/* printf("Looking for wildcard in %s\n", path); */
+	if ((base[0] == L'/' && base[1] == L'/' &&
+	     base[2] == L'?' && base[3] == L'/' &&
+	     (wcschr(base+4, L'*') || wcschr(base+4, L'?'))) ||
+	    (!(base[0] == L'/' && base[1] == L'/' &&
+	       base[2] == L'?' && base[3] == L'/') &&
+	       (wcschr(base, L'*') || wcschr(base, L'?')))) {
+		// It has a wildcard in it...
+		// Separate the last element.
+		p = wcsrchr(base, L'/');
+		if (p != NULL) {
+			*p = L'\0';
+			tree_append(t, base, p - base);
+			t->dirname_length = archive_strlen(&t->path);
+			base = p + 1;
+		}
+		p = wcsrchr(t->full_path.s, L'\\');
+		if (p != NULL) {
+			*p = L'\0';
+			t->full_path.length = wcslen(t->full_path.s);
+			t->full_path_dir_length = archive_strlen(&t->full_path);
+		}
+	}
+	tree_push(t, base, t->full_path.s, 0, 0, 0, NULL);
+	archive_wstring_free(&ws);
+	t->stack->flags = needsFirstVisit;
+	/*
+	 * Debug flag for Direct IO(No buffering) or Async IO.
+	 * Those dependant on environment variable switches
+	 * will be removed until next release.
+	 */
+	{
+		const char *e;
+		if ((e = getenv("LIBARCHIVE_DIRECT_IO")) != NULL) {
+			if (e[0] == '0')
+				t->direct_io = 0;
+			else
+				t->direct_io = 1;
+			fprintf(stderr, "LIBARCHIVE_DIRECT_IO=%s\n",
+				(t->direct_io)?"Enabled":"Disabled");
+		} else
+			t->direct_io = DIRECT_IO;
+		if ((e = getenv("LIBARCHIVE_ASYNC_IO")) != NULL) {
+			if (e[0] == '0')
+				t->async_io = 0;
+			else
+				t->async_io = 1;
+			fprintf(stderr, "LIBARCHIVE_ASYNC_IO=%s\n",
+			    (t->async_io)?"Enabled":"Disabled");
+		} else
+			t->async_io = ASYNC_IO;
+	}
+	return (t);
+failed:
+	archive_wstring_free(&ws);
+	tree_free(t);
+	return (NULL);
+}
+
+static int
+tree_descent(struct tree *t)
+{
+	t->dirname_length = archive_strlen(&t->path);
+	t->full_path_dir_length = archive_strlen(&t->full_path);
+	t->depth++;
+	return (0);
+}
+
+/*
+ * We've finished a directory; ascend back to the parent.
+ */
+static int
+tree_ascend(struct tree *t)
+{
+	struct tree_entry *te;
+
+	te = t->stack;
+	t->depth--;
+	close_and_restore_time(INVALID_HANDLE_VALUE, t, &te->restore_time);
+	return (0);
+}
+
+/*
+ * Pop the working stack.
+ */
+static void
+tree_pop(struct tree *t)
+{
+	struct tree_entry *te;
+
+	t->full_path.s[t->full_path_dir_length] = L'\0';
+	t->full_path.length = t->full_path_dir_length;
+	t->path.s[t->dirname_length] = L'\0';
+	t->path.length = t->dirname_length;
+	if (t->stack == t->current && t->current != NULL)
+		t->current = t->current->parent;
+	te = t->stack;
+	t->stack = te->next;
+	t->dirname_length = te->dirname_length;
+	t->basename = t->path.s + t->dirname_length;
+	t->full_path_dir_length = te->full_path_dir_length;
+	while (t->basename[0] == L'/')
+		t->basename++;
+	archive_wstring_free(&te->name);
+	archive_wstring_free(&te->full_path);
+	free(te);
+}
+
+/*
+ * Get the next item in the tree traversal.
+ */
+static int
+tree_next(struct tree *t)
+{
+	int r;
+
+	while (t->stack != NULL) {
+		/* If there's an open dir, get the next entry from there. */
+		if (t->d != INVALID_HANDLE_VALUE) {
+			r = tree_dir_next_windows(t, NULL);
+			if (r == 0)
+				continue;
+			return (r);
+		}
+
+		if (t->stack->flags & needsFirstVisit) {
+			wchar_t *d = t->stack->name.s;
+			t->stack->flags &= ~needsFirstVisit;
+			if (!(d[0] == L'/' && d[1] == L'/' &&
+			      d[2] == L'?' && d[3] == L'/') &&
+			    (wcschr(d, L'*') || wcschr(d, L'?'))) {
+				r = tree_dir_next_windows(t, d);
+				if (r == 0)
+					continue;
+				return (r);
+			} else {
+				HANDLE h = FindFirstFileW(d, &t->_findData);
+				if (h == INVALID_HANDLE_VALUE) {
+					la_dosmaperr(GetLastError());
+					t->tree_errno = errno;
+					t->visit_type = TREE_ERROR_DIR;
+					return (t->visit_type);
+				}
+				t->findData = &t->_findData;
+				FindClose(h);
+			}
+			/* Top stack item needs a regular visit. */
+			t->current = t->stack;
+			tree_append(t, t->stack->name.s,
+			    archive_strlen(&(t->stack->name)));
+			//t->dirname_length = t->path_length;
+			//tree_pop(t);
+			t->stack->flags &= ~needsFirstVisit;
+			return (t->visit_type = TREE_REGULAR);
+		} else if (t->stack->flags & needsDescent) {
+			/* Top stack item is dir to descend into. */
+			t->current = t->stack;
+			tree_append(t, t->stack->name.s,
+			    archive_strlen(&(t->stack->name)));
+			t->stack->flags &= ~needsDescent;
+			r = tree_descent(t);
+			if (r != 0) {
+				tree_pop(t);
+				t->visit_type = r;
+			} else
+				t->visit_type = TREE_POSTDESCENT;
+			return (t->visit_type);
+		} else if (t->stack->flags & needsOpen) {
+			t->stack->flags &= ~needsOpen;
+			r = tree_dir_next_windows(t, L"*");
+			if (r == 0)
+				continue;
+			return (r);
+		} else if (t->stack->flags & needsAscent) {
+		        /* Top stack item is dir and we're done with it. */
+			r = tree_ascend(t);
+			tree_pop(t);
+			t->visit_type = r != 0 ? r : TREE_POSTASCENT;
+			return (t->visit_type);
+		} else {
+			/* Top item on stack is dead. */
+			tree_pop(t);
+			t->flags &= ~hasLstat;
+			t->flags &= ~hasStat;
+		}
+	}
+	return (t->visit_type = 0);
+}
+
+static int
+tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
+{
+	const wchar_t *name;
+	size_t namelen;
+	int r;
+
+	for (;;) {
+		if (pattern != NULL) {
+			struct archive_wstring pt;
+
+			archive_string_init(&pt);
+			archive_wstring_ensure(&pt,
+			    archive_strlen(&(t->full_path))
+			      + 2 + wcslen(pattern));
+			archive_wstring_copy(&pt, &(t->full_path));
+			archive_wstrappend_wchar(&pt, L'\\');
+			archive_wstrcat(&pt, pattern);
+			t->d = FindFirstFileW(pt.s, &t->_findData);
+			archive_wstring_free(&pt);
+			if (t->d == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				t->tree_errno = errno;
+				r = tree_ascend(t); /* Undo "chdir" */
+				tree_pop(t);
+				t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
+				return (t->visit_type);
+			}
+			t->findData = &t->_findData;
+			pattern = NULL;
+		} else if (!FindNextFileW(t->d, &t->_findData)) {
+			FindClose(t->d);
+			t->d = INVALID_HANDLE_VALUE;
+			t->findData = NULL;
+			return (0);
+		}
+		name = t->findData->cFileName;
+		namelen = wcslen(name);
+		t->flags &= ~hasLstat;
+		t->flags &= ~hasStat;
+		if (name[0] == L'.' && name[1] == L'\0')
+			continue;
+		if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
+			continue;
+		tree_append(t, name, namelen);
+		return (t->visit_type = TREE_REGULAR);
+	}
+}
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static void
+fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
+{
+	ULARGE_INTEGER utc;
+
+	utc.HighPart = filetime->dwHighDateTime;
+	utc.LowPart  = filetime->dwLowDateTime;
+	if (utc.QuadPart >= EPOC_TIME) {
+		utc.QuadPart -= EPOC_TIME;
+		/* milli seconds base */
+		*t = (time_t)(utc.QuadPart / 10000000);
+		/* nano seconds base */
+		*ns = (long)(utc.QuadPart % 10000000) * 100;
+	} else {
+		*t = 0;
+		*ns = 0;
+	}
+}
+
+static void
+entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
+	const WIN32_FIND_DATAW *findData,
+	const BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+	time_t secs;
+	long nsecs;
+	mode_t mode;
+
+	fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
+	archive_entry_set_atime(entry, secs, nsecs);
+	fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
+	archive_entry_set_mtime(entry, secs, nsecs);
+	fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
+	archive_entry_set_birthtime(entry, secs, nsecs);
+	archive_entry_set_ctime(entry, secs, nsecs);
+	archive_entry_set_dev(entry, bhfi_dev(bhfi));
+	archive_entry_set_ino64(entry, bhfi_ino(bhfi));
+	if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1);
+	else
+		archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
+	archive_entry_set_size(entry,
+	    (((int64_t)bhfi->nFileSizeHigh) << 32)
+	    + bhfi->nFileSizeLow);
+	archive_entry_set_uid(entry, 0);
+	archive_entry_set_gid(entry, 0);
+	archive_entry_set_rdev(entry, 0);
+
+	mode = S_IRUSR | S_IRGRP | S_IROTH;
+	if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+		mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+	if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+	    findData != NULL &&
+	    findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+		mode |= S_IFLNK;
+	else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+	else {
+		const wchar_t *p;
+
+		mode |= S_IFREG;
+		p = wcsrchr(path, L'.');
+		if (p != NULL && wcslen(p) == 4) {
+			switch (p[1]) {
+			case L'B': case L'b':
+				if ((p[2] == L'A' || p[2] == L'a' ) &&
+				    (p[3] == L'T' || p[3] == L't' ))
+					mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+				break;
+			case L'C': case L'c':
+				if (((p[2] == L'M' || p[2] == L'm' ) &&
+				    (p[3] == L'D' || p[3] == L'd' )) ||
+				    ((p[2] == L'M' || p[2] == L'm' ) &&
+				    (p[3] == L'D' || p[3] == L'd' )))
+					mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+				break;
+			case L'E': case L'e':
+				if ((p[2] == L'X' || p[2] == L'x' ) &&
+				    (p[3] == L'E' || p[3] == L'e' ))
+					mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	archive_entry_set_mode(entry, mode);
+}
+
+static void
+tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t,
+	const BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+	entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi);
+}
+
+static int
+tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
+ int sim_lstat)
+{
+	HANDLE h;
+	int r;
+	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+	
+	if (sim_lstat && tree_current_is_physical_link(t))
+		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+	h = CreateFileW(tree_current_access_path(t), 0, 0, NULL,
+	    OPEN_EXISTING, flag, NULL);
+	if (h == INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		t->tree_errno = errno;
+		return (0);
+	}
+	r = GetFileInformationByHandle(h, st);
+	CloseHandle(h);
+	return (r);
+}
+
+/*
+ * Get the stat() data for the entry just returned from tree_next().
+ */
+static const BY_HANDLE_FILE_INFORMATION *
+tree_current_stat(struct tree *t)
+{
+	if (!(t->flags & hasStat)) {
+		if (!tree_current_file_information(t, &t->st, 0))
+			return NULL;
+		t->flags |= hasStat;
+	}
+	return (&t->st);
+}
+
+/*
+ * Get the lstat() data for the entry just returned from tree_next().
+ */
+static const BY_HANDLE_FILE_INFORMATION *
+tree_current_lstat(struct tree *t)
+{
+	if (!(t->flags & hasLstat)) {
+		if (!tree_current_file_information(t, &t->lst, 1))
+			return NULL;
+		t->flags |= hasLstat;
+	}
+	return (&t->lst);
+}
+
+/*
+ * Test whether current entry is a dir or link to a dir.
+ */
+static int
+tree_current_is_dir(struct tree *t)
+{
+	if (t->findData)
+		return (t->findData->dwFileAttributes
+		    & FILE_ATTRIBUTE_DIRECTORY);
+	return (0);
+}
+
+/*
+ * Test whether current entry is a physical directory.  Usually, we
+ * already have at least one of stat() or lstat() in memory, so we
+ * use tricks to try to avoid an extra trip to the disk.
+ */
+static int
+tree_current_is_physical_dir(struct tree *t)
+{
+	if (tree_current_is_physical_link(t))
+		return (0);
+	return (tree_current_is_dir(t));
+}
+
+/*
+ * Test whether current entry is a symbolic link.
+ */
+static int
+tree_current_is_physical_link(struct tree *t)
+{
+	if (t->findData)
+		return ((t->findData->dwFileAttributes
+			        & FILE_ATTRIBUTE_REPARSE_POINT) &&
+			(t->findData->dwReserved0
+			    == IO_REPARSE_TAG_SYMLINK));
+	return (0);
+}
+
+/*
+ * Test whether the same file has been in the tree as its parent.
+ */
+static int
+tree_target_is_same_as_parent(struct tree *t,
+    const BY_HANDLE_FILE_INFORMATION *st)
+{
+	struct tree_entry *te;
+	int64_t dev = bhfi_dev(st);
+	int64_t ino = bhfi_ino(st);
+
+	for (te = t->current->parent; te != NULL; te = te->parent) {
+		if (te->dev == dev && te->ino == ino)
+			return (1);
+	}
+	return (0);
+}
+
+/*
+ * Return the access path for the entry just returned from tree_next().
+ */
+static const wchar_t *
+tree_current_access_path(struct tree *t)
+{
+	return (t->full_path.s);
+}
+
+/*
+ * Return the full path for the entry just returned from tree_next().
+ */
+static const wchar_t *
+tree_current_path(struct tree *t)
+{
+	return (t->path.s);
+}
+
+/*
+ * Terminate the traversal.
+ */
+static void
+tree_close(struct tree *t)
+{
+
+	if (t == NULL)
+		return;
+	if (t->entry_fh != INVALID_HANDLE_VALUE) {
+		cancel_async(t);
+		close_and_restore_time(t->entry_fh, t, &t->restore_time);
+		t->entry_fh = INVALID_HANDLE_VALUE;
+	}
+	/* Close the handle of FindFirstFileW */
+	if (t->d != INVALID_HANDLE_VALUE) {
+		FindClose(t->d);
+		t->d = INVALID_HANDLE_VALUE;
+		t->findData = NULL;
+	}
+	/* Release anything remaining in the stack. */
+	while (t->stack != NULL)
+		tree_pop(t);
+}
+
+/*
+ * Release any resources.
+ */
+static void
+tree_free(struct tree *t)
+{
+	int i;
+
+	if (t == NULL)
+		return;
+	archive_wstring_free(&t->path);
+	archive_wstring_free(&t->full_path);
+	free(t->sparse_list);
+	free(t->filesystem_table);
+	for (i = 0; i < MAX_OVERLAPPED; i++) {
+		if (t->ol[i].buff)
+			VirtualFree(t->ol[i].buff, 0, MEM_RELEASE);
+		CloseHandle(t->ol[i].ol.hEvent);
+	}
+	free(t);
+}
+
+
+/*
+ * Populate the archive_entry with metadata from the disk.
+ */
+int
+archive_read_disk_entry_from_file(struct archive *_a,
+    struct archive_entry *entry, int fd, const struct stat *st)
+{
+	struct archive_read_disk *a = (struct archive_read_disk *)_a;
+	const wchar_t *path;
+	const wchar_t *wname;
+	const char *name;
+	HANDLE h;
+	BY_HANDLE_FILE_INFORMATION bhfi;
+	DWORD fileAttributes = 0;
+	int r;
+
+	archive_clear_error(_a);
+	wname = archive_entry_sourcepath_w(entry);
+	if (wname == NULL)
+		wname = archive_entry_pathname_w(entry);
+	if (wname == NULL) {
+		archive_set_error(&a->archive, EINVAL,
+		    "Can't get a wide character version of the path");
+		return (ARCHIVE_FAILED);
+	}
+	path = __la_win_permissive_name_w(wname);
+
+	if (st == NULL) {
+		/*
+		 * Get metadata through GetFileInformationByHandle().
+		 */
+		if (fd >= 0) {
+			h = (HANDLE)_get_osfhandle(fd);
+			r = GetFileInformationByHandle(h, &bhfi);
+			if (r == 0) {
+				la_dosmaperr(GetLastError());
+				archive_set_error(&a->archive, errno,
+				    "Can't GetFileInformationByHandle");
+				return (ARCHIVE_FAILED);
+			}
+			entry_copy_bhfi(entry, path, NULL, &bhfi);
+		} else {
+			WIN32_FIND_DATAW findData;
+			DWORD flag, desiredAccess;
+	
+			h = FindFirstFileW(path, &findData);
+			if (h == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				archive_set_error(&a->archive, errno,
+				    "Can't FindFirstFileW");
+				return (ARCHIVE_FAILED);
+			}
+			FindClose(h);
+
+			flag = FILE_FLAG_BACKUP_SEMANTICS;
+			if (!a->follow_symlinks &&
+			    (findData.dwFileAttributes
+			      & FILE_ATTRIBUTE_REPARSE_POINT) &&
+				  (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
+				flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+				desiredAccess = 0;
+			} else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+				desiredAccess = 0;
+			} else
+				desiredAccess = GENERIC_READ;
+
+			h = CreateFileW(path, desiredAccess, 0, NULL,
+			    OPEN_EXISTING, flag, NULL);
+			if (h == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				archive_set_error(&a->archive, errno,
+				    "Can't CreateFileW");
+				return (ARCHIVE_FAILED);
+			}
+			r = GetFileInformationByHandle(h, &bhfi);
+			if (r == 0) {
+				la_dosmaperr(GetLastError());
+				archive_set_error(&a->archive, errno,
+				    "Can't GetFileInformationByHandle");
+				CloseHandle(h);
+				return (ARCHIVE_FAILED);
+			}
+			entry_copy_bhfi(entry, path, &findData, &bhfi);
+		}
+		fileAttributes = bhfi.dwFileAttributes;
+	} else {
+		archive_entry_copy_stat(entry, st);
+		h = INVALID_HANDLE_VALUE;
+	}
+
+	/* Lookup uname/gname */
+	name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+	if (name != NULL)
+		archive_entry_copy_uname(entry, name);
+	name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+	if (name != NULL)
+		archive_entry_copy_gname(entry, name);
+
+	/*
+	 * Can this file be sparse file ?
+	 */
+	if (archive_entry_filetype(entry) != AE_IFREG
+	    || archive_entry_size(entry) <= 0
+		|| archive_entry_hardlink(entry) != NULL) {
+		if (h != INVALID_HANDLE_VALUE && fd < 0)
+			CloseHandle(h);
+		return (ARCHIVE_OK);
+	}
+
+	if (h == INVALID_HANDLE_VALUE) {
+		if (fd >= 0) {
+			h = (HANDLE)_get_osfhandle(fd);
+		} else {
+			h = CreateFileW(path, GENERIC_READ, 0, NULL,
+			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+			if (h == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				archive_set_error(&a->archive, errno,
+				    "Can't CreateFileW");
+				return (ARCHIVE_FAILED);
+			}
+		}
+		r = GetFileInformationByHandle(h, &bhfi);
+		if (r == 0) {
+			la_dosmaperr(GetLastError());
+			archive_set_error(&a->archive, errno,
+			    "Can't GetFileInformationByHandle");
+			if (h != INVALID_HANDLE_VALUE && fd < 0)
+				CloseHandle(h);
+			return (ARCHIVE_FAILED);
+		}
+		fileAttributes = bhfi.dwFileAttributes;
+	}
+
+	/* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */
+	if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
+		if (fd < 0)
+			CloseHandle(h);
+		return (ARCHIVE_OK);
+	}
+
+	r = setup_sparse_from_disk(a, entry, h);
+	if (fd < 0)
+		CloseHandle(h);
+
+	return (r);
+}
+
+/*
+ * Windows sparse interface.
+ */
+#if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES)
+#define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF
+typedef struct {
+	LARGE_INTEGER FileOffset;
+	LARGE_INTEGER Length;
+} FILE_ALLOCATED_RANGE_BUFFER;
+#endif
+
+static int
+setup_sparse_from_disk(struct archive_read_disk *a,
+    struct archive_entry *entry, HANDLE handle)
+{
+	FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL;
+	size_t outranges_size;
+	int64_t entry_size = archive_entry_size(entry);
+	int exit_sts = ARCHIVE_OK;
+
+	range.FileOffset.QuadPart = 0;
+	range.Length.QuadPart = entry_size;
+	outranges_size = 2048;
+	outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size);
+	if (outranges == NULL) {
+		archive_set_error(&a->archive, ENOMEM,
+			"Couldn't allocate memory");
+		exit_sts = ARCHIVE_FATAL;
+		goto exit_setup_sparse;
+	}
+
+	for (;;) {
+		DWORD retbytes;
+		BOOL ret;
+
+		for (;;) {
+			ret = DeviceIoControl(handle,
+			    FSCTL_QUERY_ALLOCATED_RANGES,
+			    &range, sizeof(range), outranges,
+			    (DWORD)outranges_size, &retbytes, NULL);
+			if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
+				free(outranges);
+				outranges_size *= 2;
+				outranges = (FILE_ALLOCATED_RANGE_BUFFER *)
+				    malloc(outranges_size);
+				if (outranges == NULL) {
+					archive_set_error(&a->archive, ENOMEM,
+					    "Couldn't allocate memory");
+					exit_sts = ARCHIVE_FATAL;
+					goto exit_setup_sparse;
+				}
+				continue;
+			} else
+				break;
+		}
+		if (ret != 0) {
+			if (retbytes > 0) {
+				DWORD i, n;
+
+				n = retbytes / sizeof(outranges[0]);
+				if (n == 1 &&
+				    outranges[0].FileOffset.QuadPart == 0 &&
+				    outranges[0].Length.QuadPart == entry_size)
+					break;/* This is not sparse. */
+				for (i = 0; i < n; i++)
+					archive_entry_sparse_add_entry(entry,
+					    outranges[i].FileOffset.QuadPart,
+						outranges[i].Length.QuadPart);
+				range.FileOffset.QuadPart =
+				    outranges[n-1].FileOffset.QuadPart
+				    + outranges[n-1].Length.QuadPart;
+				range.Length.QuadPart =
+				    entry_size - range.FileOffset.QuadPart;
+				if (range.Length.QuadPart > 0)
+					continue;
+			} else {
+				/* The remaining data is hole. */
+				archive_entry_sparse_add_entry(entry,
+				    range.FileOffset.QuadPart,
+				    range.Length.QuadPart);
+			}
+			break;
+		} else {
+			la_dosmaperr(GetLastError());
+			archive_set_error(&a->archive, errno,
+			    "DeviceIoControl Failed: %lu", GetLastError());
+			exit_sts = ARCHIVE_FAILED;
+			goto exit_setup_sparse;
+		}
+	}
+exit_setup_sparse:
+	free(outranges);
+
+	return (exit_sts);
+}
+
+#endif
diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c
new file mode 100644
index 000000000000..d3bf758bb39e
--- /dev/null
+++ b/libarchive/archive_windows.c
@@ -0,0 +1,908 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Kees Zeelenberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * A set of compatibility glue for building libarchive on Windows platforms.
+ *
+ * Originally created as "libarchive-nonposix.c" by Kees Zeelenberg
+ * for the GnuWin32 project, trimmed significantly by Tim Kientzle.
+ *
+ * Much of the original file was unnecessary for libarchive, because
+ * many of the features it emulated were not strictly necessary for
+ * libarchive.  I hope for this to shrink further as libarchive
+ * internals are gradually reworked to sit more naturally on both
+ * POSIX and Windows.  Any ideas for this are greatly appreciated.
+ *
+ * The biggest remaining issue is the dev/ino emulation; libarchive
+ * has a couple of public APIs that rely on dev/ino uniquely
+ * identifying a file.  This doesn't match well with Windows.  I'm
+ * considering alternative APIs.
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include "archive_platform.h"
+#include "archive_private.h"
+#include "archive_entry.h"
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#include <sys/stat.h>
+#include <locale.h>
+#include <process.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <windows.h>
+#include <share.h>
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+#if defined(__LA_LSEEK_NEEDED)
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+				   LARGE_INTEGER liDistanceToMove,
+				   PLARGE_INTEGER lpNewFilePointer,
+				   DWORD dwMoveMethod)
+{
+	LARGE_INTEGER li;
+	li.QuadPart = liDistanceToMove.QuadPart;
+	li.LowPart = SetFilePointer(
+		hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+	if(lpNewFilePointer) {
+		lpNewFilePointer->QuadPart = li.QuadPart;
+	}
+	return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+#endif
+
+struct ustat {
+	int64_t		st_atime;
+	uint32_t	st_atime_nsec;
+	int64_t		st_ctime;
+	uint32_t	st_ctime_nsec;
+	int64_t		st_mtime;
+	uint32_t	st_mtime_nsec;
+	gid_t		st_gid;
+	/* 64bits ino */
+	int64_t		st_ino;
+	mode_t		st_mode;
+	uint32_t	st_nlink;
+	uint64_t	st_size;
+	uid_t		st_uid;
+	dev_t		st_dev;
+	dev_t		st_rdev;
+};
+
+/* Transform 64-bits ino into 32-bits by hashing.
+ * You do not forget that really unique number size is 64-bits.
+ */
+#define INOSIZE (8*sizeof(ino_t)) /* 32 */
+static __inline ino_t
+getino(struct ustat *ub)
+{
+	ULARGE_INTEGER ino64;
+	ino64.QuadPart = ub->st_ino;
+	/* I don't know this hashing is correct way */
+	return ((ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE)));
+}
+
+/*
+ * Prepend "\\?\" to the path name and convert it to unicode to permit
+ * an extended-length path for a maximum total path length of 32767
+ * characters.
+ * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ */
+wchar_t *
+__la_win_permissive_name(const char *name)
+{
+	wchar_t *wn;
+	wchar_t *ws;
+	size_t ll;
+
+	ll = strlen(name);
+	wn = malloc((ll + 1) * sizeof(wchar_t));
+	if (wn == NULL)
+		return (NULL);
+	ll = mbstowcs(wn, name, ll);
+	if (ll == (size_t)-1) {
+		free(wn);
+		return (NULL);
+	}
+	wn[ll] = L'\0';
+	ws = __la_win_permissive_name_w(wn);
+	free(wn);
+	return (ws);
+}
+
+wchar_t *
+__la_win_permissive_name_w(const wchar_t *wname)
+{
+	wchar_t *wn, *wnp;
+	wchar_t *ws, *wsp;
+	DWORD l, len, slen;
+	int unc;
+
+	/* Get a full-pathname. */
+	l = GetFullPathNameW(wname, 0, NULL, NULL);
+	if (l == 0)
+		return (NULL);
+	/* NOTE: GetFullPathNameW has a bug that if the length of the file
+	 * name is just 1 then it returns incomplete buffer size. Thus, we
+	 * have to add three to the size to allocate a sufficient buffer
+	 * size for the full-pathname of the file name. */
+	l += 3;
+	wnp = malloc(l * sizeof(wchar_t));
+	if (wnp == NULL)
+		return (NULL);
+	len = GetFullPathNameW(wname, l, wnp, NULL);
+	wn = wnp;
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+	    wnp[2] == L'?' && wnp[3] == L'\\')
+		/* We have already a permissive name. */
+		return (wn);
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+		wnp[2] == L'.' && wnp[3] == L'\\') {
+		/* This is a device name */
+		if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+		     (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+		    wnp[5] == L':' && wnp[6] == L'\\')
+			wnp[2] = L'?';/* Not device name. */
+		return (wn);
+	}
+
+	unc = 0;
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+		wchar_t *p = &wnp[2];
+
+		/* Skip server-name letters. */
+		while (*p != L'\\' && *p != L'\0')
+			++p;
+		if (*p == L'\\') {
+			wchar_t *rp = ++p;
+			/* Skip share-name letters. */
+			while (*p != L'\\' && *p != L'\0')
+				++p;
+			if (*p == L'\\' && p != rp) {
+				/* Now, match patterns such as
+				 * "\\server-name\share-name\" */
+				wnp += 2;
+				len -= 2;
+				unc = 1;
+			}
+		}
+	}
+
+	slen = 4 + (unc * 4) + len + 1;
+	ws = wsp = malloc(slen * sizeof(wchar_t));
+	if (ws == NULL) {
+		free(wn);
+		return (NULL);
+	}
+	/* prepend "\\?\" */
+	wcsncpy(wsp, L"\\\\?\\", 4);
+	wsp += 4;
+	slen -= 4;
+	if (unc) {
+		/* append "UNC\" ---> "\\?\UNC\" */
+		wcsncpy(wsp, L"UNC\\", 4);
+		wsp += 4;
+		slen -= 4;
+	}
+	wcsncpy(wsp, wnp, slen);
+	wsp[slen - 1] = L'\0'; /* Ensure null termination. */
+	free(wn);
+	return (ws);
+}
+
+/*
+ * Create a file handle.
+ * This can exceed MAX_PATH limitation.
+ */
+static HANDLE
+la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+    LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
+    DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
+{
+	wchar_t *wpath;
+	HANDLE handle;
+
+	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+	    hTemplateFile);
+	if (handle != INVALID_HANDLE_VALUE)
+		return (handle);
+	if (GetLastError() != ERROR_PATH_NOT_FOUND)
+		return (handle);
+	wpath = __la_win_permissive_name(path);
+	if (wpath == NULL)
+		return (handle);
+	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+	    hTemplateFile);
+	free(wpath);
+	return (handle);
+}
+
+#if defined(__LA_LSEEK_NEEDED)
+__int64
+__la_lseek(int fd, __int64 offset, int whence)
+{
+	LARGE_INTEGER distance;
+	LARGE_INTEGER newpointer;
+	HANDLE handle;
+
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	handle = (HANDLE)_get_osfhandle(fd);
+	if (GetFileType(handle) != FILE_TYPE_DISK) {
+		errno = EBADF;
+		return (-1);
+	}
+	distance.QuadPart = offset;
+	if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
+		DWORD lasterr;
+
+		lasterr = GetLastError();
+		if (lasterr == ERROR_BROKEN_PIPE)
+			return (0);
+		if (lasterr == ERROR_ACCESS_DENIED)
+			errno = EBADF;
+		else
+			la_dosmaperr(lasterr);
+		return (-1);
+	}
+	return (newpointer.QuadPart);
+}
+#endif
+
+/* This can exceed MAX_PATH limitation. */
+int
+__la_open(const char *path, int flags, ...)
+{
+	va_list ap;
+	wchar_t *ws;
+	int r, pmode;
+	DWORD attr;
+
+	va_start(ap, flags);
+	pmode = va_arg(ap, int);
+	va_end(ap);
+	ws = NULL;
+	if ((flags & ~O_BINARY) == O_RDONLY) {
+		/*
+		 * When we open a directory, _open function returns 
+		 * "Permission denied" error.
+		 */
+		attr = GetFileAttributesA(path);
+		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
+			ws = __la_win_permissive_name(path);
+			if (ws == NULL) {
+				errno = EINVAL;
+				return (-1);
+			}
+			attr = GetFileAttributesW(ws);
+		}
+		if (attr == (DWORD)-1) {
+			la_dosmaperr(GetLastError());
+			free(ws);
+			return (-1);
+		}
+		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+			HANDLE handle;
+
+			if (ws != NULL)
+				handle = CreateFileW(ws, 0, 0, NULL,
+				    OPEN_EXISTING,
+				    FILE_FLAG_BACKUP_SEMANTICS |
+				    FILE_ATTRIBUTE_READONLY,
+					NULL);
+			else
+				handle = CreateFileA(path, 0, 0, NULL,
+				    OPEN_EXISTING,
+				    FILE_FLAG_BACKUP_SEMANTICS |
+				    FILE_ATTRIBUTE_READONLY,
+					NULL);
+			free(ws);
+			if (handle == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				return (-1);
+			}
+			r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
+			return (r);
+		}
+	}
+	if (ws == NULL) {
+#if defined(__BORLANDC__)
+		/* Borland has no mode argument.
+		   TODO: Fix mode of new file.  */
+		r = _open(path, flags);
+#else
+		r = _open(path, flags, pmode);
+#endif
+		if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+			/* Simulate other POSIX system action to pass our test suite. */
+			attr = GetFileAttributesA(path);
+			if (attr == (DWORD)-1)
+				la_dosmaperr(GetLastError());
+			else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+				errno = EISDIR;
+			else
+				errno = EACCES;
+			return (-1);
+		}
+		if (r >= 0 || errno != ENOENT)
+			return (r);
+		ws = __la_win_permissive_name(path);
+		if (ws == NULL) {
+			errno = EINVAL;
+			return (-1);
+		}
+	}
+	r = _wopen(ws, flags, pmode);
+	if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+		/* Simulate other POSIX system action to pass our test suite. */
+		attr = GetFileAttributesW(ws);
+		if (attr == (DWORD)-1)
+			la_dosmaperr(GetLastError());
+		else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+			errno = EISDIR;
+		else
+			errno = EACCES;
+	}
+	free(ws);
+	return (r);
+}
+
+ssize_t
+__la_read(int fd, void *buf, size_t nbytes)
+{
+	HANDLE handle;
+	DWORD bytes_read, lasterr;
+	int r;
+
+#ifdef _WIN64
+	if (nbytes > UINT32_MAX)
+		nbytes = UINT32_MAX;
+#endif
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	/* Do not pass 0 to third parameter of ReadFile(), read bytes.
+	 * This will not return to application side. */
+	if (nbytes == 0)
+		return (0);
+	handle = (HANDLE)_get_osfhandle(fd);
+	r = ReadFile(handle, buf, (uint32_t)nbytes,
+	    &bytes_read, NULL);
+	if (r == 0) {
+		lasterr = GetLastError();
+		if (lasterr == ERROR_NO_DATA) {
+			errno = EAGAIN;
+			return (-1);
+		}
+		if (lasterr == ERROR_BROKEN_PIPE)
+			return (0);
+		if (lasterr == ERROR_ACCESS_DENIED)
+			errno = EBADF;
+		else
+			la_dosmaperr(lasterr);
+		return (-1);
+	}
+	return ((ssize_t)bytes_read);
+}
+
+/* Convert Windows FILETIME to UTC */
+__inline static void
+fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns)
+{
+	ULARGE_INTEGER utc;
+
+	utc.HighPart = filetime->dwHighDateTime;
+	utc.LowPart  = filetime->dwLowDateTime;
+	if (utc.QuadPart >= EPOC_TIME) {
+		utc.QuadPart -= EPOC_TIME;
+		*t = (time_t)(utc.QuadPart / 10000000);	/* milli seconds base */
+		*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
+	} else {
+		*t = 0;
+		*ns = 0;
+	}
+}
+
+/* Stat by handle
+ * Windows' stat() does not accept the path added "\\?\" especially "?"
+ * character.
+ * It means we cannot access the long name path longer than MAX_PATH.
+ * So I've implemented simular Windows' stat() to access the long name path.
+ * And I've added some feature.
+ * 1. set st_ino by nFileIndexHigh and nFileIndexLow of
+ *    BY_HANDLE_FILE_INFORMATION.
+ * 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION.
+ * 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION.
+ */
+static int
+__hstat(HANDLE handle, struct ustat *st)
+{
+	BY_HANDLE_FILE_INFORMATION info;
+	ULARGE_INTEGER ino64;
+	DWORD ftype;
+	mode_t mode;
+	time_t t;
+	long ns;
+
+	switch (ftype = GetFileType(handle)) {
+	case FILE_TYPE_UNKNOWN:
+		errno = EBADF;
+		return (-1);
+	case FILE_TYPE_CHAR:
+	case FILE_TYPE_PIPE:
+		if (ftype == FILE_TYPE_CHAR) {
+			st->st_mode = S_IFCHR;
+			st->st_size = 0;
+		} else {
+			DWORD avail;
+
+			st->st_mode = S_IFIFO;
+			if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
+				st->st_size = avail;
+			else
+				st->st_size = 0;
+		}
+		st->st_atime = 0;
+		st->st_atime_nsec = 0;
+		st->st_mtime = 0;
+		st->st_mtime_nsec = 0;
+		st->st_ctime = 0;
+		st->st_ctime_nsec = 0;
+		st->st_ino = 0;
+		st->st_nlink = 1;
+		st->st_uid = 0;
+		st->st_gid = 0;
+		st->st_rdev = 0;
+		st->st_dev = 0;
+		return (0);
+	case FILE_TYPE_DISK:
+		break;
+	default:
+		/* This ftype is undocumented type. */
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+
+	ZeroMemory(&info, sizeof(info));
+	if (!GetFileInformationByHandle (handle, &info)) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+
+	mode = S_IRUSR | S_IRGRP | S_IROTH;
+	if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+		mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+	if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+	else
+		mode |= S_IFREG;
+	st->st_mode = mode;
+	
+	fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
+	st->st_atime = t; 
+	st->st_atime_nsec = ns;
+	fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
+	st->st_mtime = t;
+	st->st_mtime_nsec = ns;
+	fileTimeToUTC(&info.ftCreationTime, &t, &ns);
+	st->st_ctime = t;
+	st->st_ctime_nsec = ns;
+	st->st_size = 
+	    ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
+		+ (int64_t)(info.nFileSizeLow);
+#ifdef SIMULATE_WIN_STAT
+	st->st_ino = 0;
+	st->st_nlink = 1;
+	st->st_dev = 0;
+#else
+	/* Getting FileIndex as i-node. We should remove a sequence which
+	 * is high-16-bits of nFileIndexHigh. */
+	ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
+	ino64.LowPart  = info.nFileIndexLow;
+	st->st_ino = ino64.QuadPart;
+	st->st_nlink = info.nNumberOfLinks;
+	if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		++st->st_nlink;/* Add parent directory. */
+	st->st_dev = info.dwVolumeSerialNumber;
+#endif
+	st->st_uid = 0;
+	st->st_gid = 0;
+	st->st_rdev = 0;
+	return (0);
+}
+
+static void
+copy_stat(struct stat *st, struct ustat *us)
+{
+	st->st_atime = us->st_atime;
+	st->st_ctime = us->st_ctime;
+	st->st_mtime = us->st_mtime;
+	st->st_gid = us->st_gid;
+	st->st_ino = getino(us);
+	st->st_mode = us->st_mode;
+	st->st_nlink = us->st_nlink;
+	st->st_size = (off_t)us->st_size;
+	st->st_uid = us->st_uid;
+	st->st_dev = us->st_dev;
+	st->st_rdev = us->st_rdev;
+}
+
+/*
+ * TODO: Remove a use of __la_fstat and __la_stat.
+ * We should use GetFileInformationByHandle in place
+ * where We still use the *stat functions.
+ */
+int
+__la_fstat(int fd, struct stat *st)
+{
+	struct ustat u;
+	int ret;
+
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
+	if (ret >= 0) {
+		copy_stat(st, &u);
+		if (u.st_mode & (S_IFCHR | S_IFIFO)) {
+			st->st_dev = fd;
+			st->st_rdev = fd;
+		}
+	}
+	return (ret);
+}
+
+/* This can exceed MAX_PATH limitation. */
+int
+__la_stat(const char *path, struct stat *st)
+{
+	HANDLE handle;
+	struct ustat u;
+	int ret;
+
+	handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
+		FILE_FLAG_BACKUP_SEMANTICS,
+		NULL);
+	if (handle == INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+	ret = __hstat(handle, &u);
+	CloseHandle(handle);
+	if (ret >= 0) {
+		char *p;
+
+		copy_stat(st, &u);
+		p = strrchr(path, '.');
+		if (p != NULL && strlen(p) == 4) {
+			char exttype[4];
+
+			++ p;
+			exttype[0] = toupper(*p++);
+			exttype[1] = toupper(*p++);
+			exttype[2] = toupper(*p++);
+			exttype[3] = '\0';
+			if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
+				!strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
+				st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+		}
+	}
+	return (ret);
+}
+
+/*
+ * This waitpid is limited implementation.
+ */
+pid_t
+__la_waitpid(HANDLE child, int *status, int option)
+{
+	DWORD cs;
+
+	(void)option;/* UNUSED */
+	do {
+		if (GetExitCodeProcess(child, &cs) == 0) {
+			CloseHandle(child);
+			la_dosmaperr(GetLastError());
+			*status = 0;
+			return (-1);
+		}
+	} while (cs == STILL_ACTIVE);
+
+	*status = (int)(cs & 0xff);
+	return (0);
+}
+
+ssize_t
+__la_write(int fd, const void *buf, size_t nbytes)
+{
+	DWORD bytes_written;
+
+#ifdef _WIN64
+	if (nbytes > UINT32_MAX)
+		nbytes = UINT32_MAX;
+#endif
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
+	    &bytes_written, NULL)) {
+		DWORD lasterr;
+
+		lasterr = GetLastError();
+		if (lasterr == ERROR_ACCESS_DENIED)
+			errno = EBADF;
+		else
+			la_dosmaperr(lasterr);
+		return (-1);
+	}
+	return (bytes_written);
+}
+
+/*
+ * Replace the Windows path separator '\' with '/'.
+ */
+static int
+replace_pathseparator(struct archive_wstring *ws, const wchar_t *wp)
+{
+	wchar_t *w;
+	size_t path_length;
+
+	if (wp == NULL)
+		return(0);
+	if (wcschr(wp, L'\\') == NULL)
+		return(0);
+	path_length = wcslen(wp);
+	if (archive_wstring_ensure(ws, path_length) == NULL)
+		return(-1);
+	archive_wstrncpy(ws, wp, path_length);
+	for (w = ws->s; *w; w++) {
+		if (*w == L'\\')
+			*w = L'/';
+	}
+	return(1);
+}
+
+static int
+fix_pathseparator(struct archive_entry *entry)
+{
+	struct archive_wstring ws;
+	const wchar_t *wp;
+	int ret = ARCHIVE_OK;
+
+	archive_string_init(&ws);
+	wp = archive_entry_pathname_w(entry);
+	switch (replace_pathseparator(&ws, wp)) {
+	case 0: /* Not replaced. */
+		break;
+	case 1: /* Replaced. */
+		archive_entry_copy_pathname_w(entry, ws.s);
+		break;
+	default:
+		ret = ARCHIVE_FAILED;
+	}
+	wp = archive_entry_hardlink_w(entry);
+	switch (replace_pathseparator(&ws, wp)) {
+	case 0: /* Not replaced. */
+		break;
+	case 1: /* Replaced. */
+		archive_entry_copy_hardlink_w(entry, ws.s);
+		break;
+	default:
+		ret = ARCHIVE_FAILED;
+	}
+	wp = archive_entry_symlink_w(entry);
+	switch (replace_pathseparator(&ws, wp)) {
+	case 0: /* Not replaced. */
+		break;
+	case 1: /* Replaced. */
+		archive_entry_copy_symlink_w(entry, ws.s);
+		break;
+	default:
+		ret = ARCHIVE_FAILED;
+	}
+	archive_wstring_free(&ws);
+	return(ret);
+}
+
+struct archive_entry *
+__la_win_entry_in_posix_pathseparator(struct archive_entry *entry)
+{
+	struct archive_entry *entry_main;
+	const wchar_t *wp;
+	int has_backslash = 0;
+	int ret;
+
+	wp = archive_entry_pathname_w(entry);
+	if (wp != NULL && wcschr(wp, L'\\') != NULL)
+		has_backslash = 1;
+	if (!has_backslash) {
+		wp = archive_entry_hardlink_w(entry);
+		if (wp != NULL && wcschr(wp, L'\\') != NULL)
+			has_backslash = 1;
+	}
+	if (!has_backslash) {
+		wp = archive_entry_symlink_w(entry);
+		if (wp != NULL && wcschr(wp, L'\\') != NULL)
+			has_backslash = 1;
+	}
+	/*
+	 * If there is no backslach chars, return the original.
+	 */
+	if (!has_backslash)
+		return (entry);
+
+	/* Copy entry so we can modify it as needed. */
+	entry_main = archive_entry_clone(entry);
+	if (entry_main == NULL)
+		return (NULL);
+	/* Replace the Windows path-separator '\' with '/'. */
+	ret = fix_pathseparator(entry_main);
+	if (ret < ARCHIVE_WARN) {
+		archive_entry_free(entry_main);
+		return (NULL);
+	}
+	return (entry_main);
+}
+
+
+/*
+ * The following function was modified from PostgreSQL sources and is
+ * subject to the copyright below.
+ */
+/*-------------------------------------------------------------------------
+ *
+ * win32error.c
+ *	  Map win32 error codes to errno values
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+static const struct {
+	DWORD		winerr;
+	int		doserr;
+} doserrors[] =
+{
+	{	ERROR_INVALID_FUNCTION, EINVAL	},
+	{	ERROR_FILE_NOT_FOUND, ENOENT	},
+	{	ERROR_PATH_NOT_FOUND, ENOENT	},
+	{	ERROR_TOO_MANY_OPEN_FILES, EMFILE	},
+	{	ERROR_ACCESS_DENIED, EACCES	},
+	{	ERROR_INVALID_HANDLE, EBADF	},
+	{	ERROR_ARENA_TRASHED, ENOMEM	},
+	{	ERROR_NOT_ENOUGH_MEMORY, ENOMEM	},
+	{	ERROR_INVALID_BLOCK, ENOMEM	},
+	{	ERROR_BAD_ENVIRONMENT, E2BIG	},
+	{	ERROR_BAD_FORMAT, ENOEXEC	},
+	{	ERROR_INVALID_ACCESS, EINVAL	},
+	{	ERROR_INVALID_DATA, EINVAL	},
+	{	ERROR_INVALID_DRIVE, ENOENT	},
+	{	ERROR_CURRENT_DIRECTORY, EACCES	},
+	{	ERROR_NOT_SAME_DEVICE, EXDEV	},
+	{	ERROR_NO_MORE_FILES, ENOENT	},
+	{	ERROR_LOCK_VIOLATION, EACCES	},
+	{	ERROR_SHARING_VIOLATION, EACCES	},
+	{	ERROR_BAD_NETPATH, ENOENT	},
+	{	ERROR_NETWORK_ACCESS_DENIED, EACCES	},
+	{	ERROR_BAD_NET_NAME, ENOENT	},
+	{	ERROR_FILE_EXISTS, EEXIST	},
+	{	ERROR_CANNOT_MAKE, EACCES	},
+	{	ERROR_FAIL_I24, EACCES	},
+	{	ERROR_INVALID_PARAMETER, EINVAL	},
+	{	ERROR_NO_PROC_SLOTS, EAGAIN	},
+	{	ERROR_DRIVE_LOCKED, EACCES	},
+	{	ERROR_BROKEN_PIPE, EPIPE	},
+	{	ERROR_DISK_FULL, ENOSPC	},
+	{	ERROR_INVALID_TARGET_HANDLE, EBADF	},
+	{	ERROR_INVALID_HANDLE, EINVAL	},
+	{	ERROR_WAIT_NO_CHILDREN, ECHILD	},
+	{	ERROR_CHILD_NOT_COMPLETE, ECHILD	},
+	{	ERROR_DIRECT_ACCESS_HANDLE, EBADF	},
+	{	ERROR_NEGATIVE_SEEK, EINVAL	},
+	{	ERROR_SEEK_ON_DEVICE, EACCES	},
+	{	ERROR_DIR_NOT_EMPTY, ENOTEMPTY	},
+	{	ERROR_NOT_LOCKED, EACCES	},
+	{	ERROR_BAD_PATHNAME, ENOENT	},
+	{	ERROR_MAX_THRDS_REACHED, EAGAIN	},
+	{	ERROR_LOCK_FAILED, EACCES	},
+	{	ERROR_ALREADY_EXISTS, EEXIST	},
+	{	ERROR_FILENAME_EXCED_RANGE, ENOENT	},
+	{	ERROR_NESTING_NOT_ALLOWED, EAGAIN	},
+	{	ERROR_NOT_ENOUGH_QUOTA, ENOMEM	}
+};
+
+void
+__la_dosmaperr(unsigned long e)
+{
+	int			i;
+
+	if (e == 0)
+	{
+		errno = 0;
+		return;
+	}
+
+	for (i = 0; i < (int)sizeof(doserrors); i++)
+	{
+		if (doserrors[i].winerr == e)
+		{
+			errno = doserrors[i].doserr;
+			return;
+		}
+	}
+
+	/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+	errno = EINVAL;
+	return;
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/libarchive/archive_windows.h b/libarchive/archive_windows.h
new file mode 100644
index 000000000000..c6f5bc510513
--- /dev/null
+++ b/libarchive/archive_windows.h
@@ -0,0 +1,306 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2006 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+/*
+ * TODO: A lot of stuff in here isn't actually used by libarchive and
+ * can be trimmed out.  Note that this file is used by libarchive and
+ * libarchive_test but nowhere else.  (But note that it gets compiled
+ * with many different Windows environments, including MinGW, Visual
+ * Studio, and Cygwin.  Significant changes should be tested in all three.)
+ */
+
+/*
+ * TODO: Don't use off_t in here.  Use __int64 instead.  Note that
+ * Visual Studio and the Windows SDK define off_t as 32 bits; Win32's
+ * more modern file handling APIs all use __int64 instead of off_t.
+ */
+
+#ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
+#define	LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
+
+/* Start of configuration for native Win32  */
+#ifndef MINGW_HAS_SECURE_API
+#define MINGW_HAS_SECURE_API 1
+#endif
+
+#include <errno.h>
+#define	set_errno(val)	((errno)=val)
+#include <io.h>
+#include <stdlib.h>   //brings in NULL
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <process.h>
+#include <direct.h>
+#if defined(__MINGW32__) && defined(HAVE_UNISTD_H)
+/* Prevent build error from a type mismatch of ftruncate().
+ * This unistd.h defines it as ftruncate(int, off_t). */
+#include <unistd.h>
+#endif
+#define NOCRYPT
+#include <windows.h>
+//#define	EFTYPE 7
+
+#if defined(__BORLANDC__)
+#pragma warn -8068	/* Constant out of range in comparison. */
+#pragma warn -8072	/* Suspicious pointer arithmetic. */
+#endif
+
+#ifndef NULL
+#ifdef  __cplusplus
+#define	NULL    0
+#else
+#define	NULL    ((void *)0)
+#endif
+#endif
+
+/* Alias the Windows _function to the POSIX equivalent. */
+#define	close		_close
+#define	fcntl(fd, cmd, flg)	/* No operation. */		
+#ifndef fileno
+#define	fileno		_fileno
+#endif
+#ifdef fstat
+#undef fstat
+#endif
+#define	fstat		__la_fstat
+#if !defined(__BORLANDC__)
+#ifdef lseek
+#undef lseek
+#endif
+#define	lseek		_lseeki64
+#else
+#define	lseek		__la_lseek
+#define __LA_LSEEK_NEEDED
+#endif
+#define	lstat		__la_stat
+#define	open		__la_open
+#define	read		__la_read
+#if !defined(__BORLANDC__)
+#define setmode		_setmode
+#endif
+#ifdef stat
+#undef stat
+#endif
+#define	stat(path,stref)		__la_stat(path,stref)
+#if !defined(__BORLANDC__)
+#define	strdup		_strdup
+#endif
+#define	tzset		_tzset
+#if !defined(__BORLANDC__)
+#define	umask		_umask
+#endif
+#define	waitpid		__la_waitpid
+#define	write		__la_write
+
+#ifndef O_RDONLY
+#define	O_RDONLY	_O_RDONLY
+#define	O_WRONLY	_O_WRONLY
+#define	O_TRUNC		_O_TRUNC
+#define	O_CREAT		_O_CREAT
+#define	O_EXCL		_O_EXCL
+#define	O_BINARY	_O_BINARY
+#endif
+
+#ifndef _S_IFIFO
+  #define	_S_IFIFO        0010000   /* pipe */
+#endif
+#ifndef _S_IFCHR
+  #define	_S_IFCHR        0020000   /* character special */
+#endif
+#ifndef _S_IFDIR
+  #define	_S_IFDIR        0040000   /* directory */
+#endif
+#ifndef _S_IFBLK
+  #define	_S_IFBLK        0060000   /* block special */
+#endif
+#ifndef _S_IFLNK
+  #define	_S_IFLNK        0120000   /* symbolic link */
+#endif
+#ifndef _S_IFSOCK
+  #define	_S_IFSOCK       0140000   /* socket */
+#endif
+#ifndef	_S_IFREG
+  #define	_S_IFREG        0100000   /* regular */
+#endif
+#ifndef	_S_IFMT
+  #define	_S_IFMT         0170000   /* file type mask */
+#endif
+
+#ifndef S_IFIFO
+#define	S_IFIFO     _S_IFIFO
+#endif
+//#define	S_IFCHR  _S_IFCHR
+//#define	S_IFDIR  _S_IFDIR
+#ifndef S_IFBLK
+#define	S_IFBLK     _S_IFBLK
+#endif
+#ifndef S_IFLNK
+#define	S_IFLNK     _S_IFLNK
+#endif
+#ifndef S_IFSOCK
+#define	S_IFSOCK    _S_IFSOCK
+#endif
+//#define	S_IFREG  _S_IFREG
+//#define	S_IFMT   _S_IFMT
+
+#ifndef S_ISBLK
+#define	S_ISBLK(m)	(((m) & S_IFMT) == S_IFBLK)	/* block special */
+#define	S_ISFIFO(m)	(((m) & S_IFMT) == S_IFIFO)	/* fifo or socket */
+#define	S_ISCHR(m)	(((m) & S_IFMT) == S_IFCHR)	/* char special */
+#define	S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)	/* directory */
+#define	S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)	/* regular file */
+#endif
+#define	S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
+#define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
+
+#define	_S_ISUID        0004000   /* set user id on execution */
+#define	_S_ISGID        0002000   /* set group id on execution */
+#define	_S_ISVTX        0001000   /* save swapped text even after use */
+
+#define	S_ISUID        _S_ISUID
+#define	S_ISGID        _S_ISGID
+#define	S_ISVTX        _S_ISVTX
+
+#define	_S_IRWXU	     (_S_IREAD | _S_IWRITE | _S_IEXEC)
+#define	_S_IXUSR	     _S_IEXEC  /* read permission, user */
+#define	_S_IWUSR	     _S_IWRITE /* write permission, user */
+#define	_S_IRUSR	     _S_IREAD  /* execute/search permission, user */
+#define	_S_IRWXG        (_S_IRWXU >> 3)
+#define	_S_IXGRP        (_S_IXUSR >> 3) /* read permission, group */
+#define	_S_IWGRP        (_S_IWUSR >> 3) /* write permission, group */
+#define	_S_IRGRP        (_S_IRUSR >> 3) /* execute/search permission, group */
+#define	_S_IRWXO        (_S_IRWXG >> 3) 
+#define	_S_IXOTH        (_S_IXGRP >> 3) /* read permission, other */
+#define	_S_IWOTH        (_S_IWGRP >> 3) /* write permission, other */
+#define	_S_IROTH        (_S_IRGRP  >> 3) /* execute/search permission, other */
+
+#ifndef S_IRWXU
+#define	S_IRWXU	     _S_IRWXU
+#define	S_IXUSR	     _S_IXUSR
+#define	S_IWUSR	     _S_IWUSR
+#define	S_IRUSR	     _S_IRUSR
+#endif
+#define	S_IRWXG        _S_IRWXG
+#define	S_IXGRP        _S_IXGRP
+#define	S_IWGRP        _S_IWGRP
+#define	S_IRGRP        _S_IRGRP
+#define	S_IRWXO        _S_IRWXO
+#define	S_IXOTH        _S_IXOTH
+#define	S_IWOTH        _S_IWOTH
+#define	S_IROTH        _S_IROTH
+
+#define	F_DUPFD	  	0	/* Duplicate file descriptor.  */
+#define	F_GETFD		1	/* Get file descriptor flags.  */
+#define	F_SETFD		2	/* Set file descriptor flags.  */
+#define	F_GETFL		3	/* Get file status flags.  */
+#define	F_SETFL		4	/* Set file status flags.  */
+#define	F_GETOWN		5	/* Get owner (receiver of SIGIO).  */
+#define	F_SETOWN		6	/* Set owner (receiver of SIGIO).  */
+#define	F_GETLK		7	/* Get record locking info.  */
+#define	F_SETLK		8	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW		9	/* Set record locking info (blocking).  */
+
+/* XXX missing */
+#define	F_GETLK64	7	/* Get record locking info.  */
+#define	F_SETLK64	8	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW64	9	/* Set record locking info (blocking).  */
+
+/* File descriptor flags used with F_GETFD and F_SETFD.  */
+#define	FD_CLOEXEC	1	/* Close on exec.  */
+
+//NOT SURE IF O_NONBLOCK is OK here but at least the 0x0004 flag is not used by anything else...
+#define	O_NONBLOCK 0x0004 /* Non-blocking I/O.  */
+//#define	O_NDELAY   O_NONBLOCK
+
+/* Symbolic constants for the access() function */
+#if !defined(F_OK)
+    #define	R_OK    4       /*  Test for read permission    */
+    #define	W_OK    2       /*  Test for write permission   */
+    #define	X_OK    1       /*  Test for execute permission */
+    #define	F_OK    0       /*  Test for existence of file  */
+#endif
+
+
+/* Replacement POSIX function */
+extern int	 __la_fstat(int fd, struct stat *st);
+extern int	 __la_lstat(const char *path, struct stat *st);
+#if defined(__LA_LSEEK_NEEDED)
+extern __int64	 __la_lseek(int fd, __int64 offset, int whence);
+#endif
+extern int	 __la_open(const char *path, int flags, ...);
+extern ssize_t	 __la_read(int fd, void *buf, size_t nbytes);
+extern int	 __la_stat(const char *path, struct stat *st);
+extern pid_t	 __la_waitpid(HANDLE child, int *status, int option);
+extern ssize_t	 __la_write(int fd, const void *buf, size_t nbytes);
+
+#define _stat64i32(path, st)	__la_stat(path, st)
+#define _stat64(path, st)	__la_stat(path, st)
+/* for status returned by la_waitpid */
+#define WIFEXITED(sts)		((sts & 0x100) == 0)
+#define WEXITSTATUS(sts)	(sts & 0x0FF)
+
+extern wchar_t *__la_win_permissive_name(const char *name);
+extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
+extern void __la_dosmaperr(unsigned long e);
+#define la_dosmaperr(e) __la_dosmaperr(e)
+extern struct archive_entry *__la_win_entry_in_posix_pathseparator(
+    struct archive_entry *);
+
+#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__)
+typedef int mbstate_t;
+size_t wcrtomb(char *, wchar_t, mbstate_t *);
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300
+WINBASEAPI BOOL WINAPI GetVolumePathNameW(
+       LPCWSTR lpszFileName,
+       LPWSTR lpszVolumePathName,
+       DWORD cchBufferLength
+       );
+# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
+typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
+       LARGE_INTEGER FileOffset;
+       LARGE_INTEGER Length;
+} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
+#  define FSCTL_SET_SPARSE \
+     CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
+#  define FSCTL_QUERY_ALLOCATED_RANGES \
+     CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51,  METHOD_NEITHER, FILE_READ_DATA)
+# endif
+#endif
+
+#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */
diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
new file mode 100644
index 000000000000..0f0780a8e47e
--- /dev/null
+++ b/libarchive/archive_write_disk_windows.c
@@ -0,0 +1,2502 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <winioctl.h>
+
+/* TODO: Support Mac OS 'quarantine' feature.  This is really just a
+ * standard tag to mark files that have been downloaded as "tainted".
+ * On Mac OS, we should mark the extracted files as tainted if the
+ * archive being read was tainted.  Windows has a similar feature; we
+ * should investigate ways to support this generically. */
+
+#include "archive.h"
+#include "archive_acl_private.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef IO_REPARSE_TAG_SYMLINK
+/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
+#define	IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#endif
+
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+                             LARGE_INTEGER liDistanceToMove,
+                             PLARGE_INTEGER lpNewFilePointer,
+                             DWORD dwMoveMethod)
+{
+	LARGE_INTEGER li;
+	li.QuadPart = liDistanceToMove.QuadPart;
+	li.LowPart = SetFilePointer(
+	    hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+	if(lpNewFilePointer) {
+		lpNewFilePointer->QuadPart = li.QuadPart;
+	}
+	return li.LowPart != (DWORD)-1 || GetLastError() == NO_ERROR;
+}
+
+struct fixup_entry {
+	struct fixup_entry	*next;
+	struct archive_acl	 acl;
+	mode_t			 mode;
+	int64_t			 atime;
+	int64_t                  birthtime;
+	int64_t			 mtime;
+	int64_t			 ctime;
+	unsigned long		 atime_nanos;
+	unsigned long            birthtime_nanos;
+	unsigned long		 mtime_nanos;
+	unsigned long		 ctime_nanos;
+	unsigned long		 fflags_set;
+	int			 fixup; /* bitmask of what needs fixing */
+	wchar_t			*name;
+};
+
+/*
+ * We use a bitmask to track which operations remain to be done for
+ * this file.  In particular, this helps us avoid unnecessary
+ * operations when it's possible to take care of one step as a
+ * side-effect of another.  For example, mkdir() can specify the mode
+ * for the newly-created object but symlink() cannot.  This means we
+ * can skip chmod() if mkdir() succeeded, but we must explicitly
+ * chmod() if we're trying to create a directory that already exists
+ * (mkdir() failed) or if we're restoring a symlink.  Similarly, we
+ * need to verify UID/GID before trying to restore SUID/SGID bits;
+ * that verification can occur explicitly through a stat() call or
+ * implicitly because of a successful chown() call.
+ */
+#define	TODO_MODE_FORCE		0x40000000
+#define	TODO_MODE_BASE		0x20000000
+#define	TODO_SUID		0x10000000
+#define	TODO_SUID_CHECK		0x08000000
+#define	TODO_SGID		0x04000000
+#define	TODO_SGID_CHECK		0x02000000
+#define	TODO_MODE		(TODO_MODE_BASE|TODO_SUID|TODO_SGID)
+#define	TODO_TIMES		ARCHIVE_EXTRACT_TIME
+#define	TODO_OWNER		ARCHIVE_EXTRACT_OWNER
+#define	TODO_FFLAGS		ARCHIVE_EXTRACT_FFLAGS
+#define	TODO_ACLS		ARCHIVE_EXTRACT_ACL
+#define	TODO_XATTR		ARCHIVE_EXTRACT_XATTR
+#define	TODO_MAC_METADATA	ARCHIVE_EXTRACT_MAC_METADATA
+
+struct archive_write_disk {
+	struct archive	archive;
+
+	mode_t			 user_umask;
+	struct fixup_entry	*fixup_list;
+	struct fixup_entry	*current_fixup;
+	int64_t			 user_uid;
+	int			 skip_file_set;
+	int64_t			 skip_file_dev;
+	int64_t			 skip_file_ino;
+	time_t			 start_time;
+
+	int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
+	void  (*cleanup_gid)(void *private);
+	void			*lookup_gid_data;
+	int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
+	void  (*cleanup_uid)(void *private);
+	void			*lookup_uid_data;
+
+	/*
+	 * Full path of last file to satisfy symlink checks.
+	 */
+	struct archive_wstring	path_safe;
+
+	/*
+	 * Cached stat data from disk for the current entry.
+	 * If this is valid, pst points to st.  Otherwise,
+	 * pst is null.
+	 */
+	BY_HANDLE_FILE_INFORMATION		 st;
+	BY_HANDLE_FILE_INFORMATION		*pst;
+
+	/* Information about the object being restored right now. */
+	struct archive_entry	*entry; /* Entry being extracted. */
+	wchar_t			*name; /* Name of entry, possibly edited. */
+	struct archive_wstring	 _name_data; /* backing store for 'name' */
+	/* Tasks remaining for this object. */
+	int			 todo;
+	/* Tasks deferred until end-of-archive. */
+	int			 deferred;
+	/* Options requested by the client. */
+	int			 flags;
+	/* Handle for the file we're restoring. */
+	HANDLE		 fh;
+	/* Current offset for writing data to the file. */
+	int64_t			 offset;
+	/* Last offset actually written to disk. */
+	int64_t			 fd_offset;
+	/* Total bytes actually written to files. */
+	int64_t			 total_bytes_written;
+	/* Maximum size of file, -1 if unknown. */
+	int64_t			 filesize;
+	/* Dir we were in before this restore; only for deep paths. */
+	int			 restore_pwd;
+	/* Mode we should use for this entry; affected by _PERM and umask. */
+	mode_t			 mode;
+	/* UID/GID to use in restoring this entry. */
+	int64_t			 uid;
+	int64_t			 gid;
+};
+
+/*
+ * Default mode for dirs created automatically (will be modified by umask).
+ * Note that POSIX specifies 0777 for implicity-created dirs, "modified
+ * by the process' file creation mask."
+ */
+#define	DEFAULT_DIR_MODE 0777
+/*
+ * Dir modes are restored in two steps:  During the extraction, the permissions
+ * in the archive are modified to match the following limits.  During
+ * the post-extract fixup pass, the permissions from the archive are
+ * applied.
+ */
+#define	MINIMUM_DIR_MODE 0700
+#define	MAXIMUM_DIR_MODE 0775
+
+static int	check_symlinks(struct archive_write_disk *);
+static int	create_filesystem_object(struct archive_write_disk *);
+static struct fixup_entry *current_fixup(struct archive_write_disk *,
+		    const wchar_t *pathname);
+static int	cleanup_pathname(struct archive_write_disk *);
+static int	create_dir(struct archive_write_disk *, wchar_t *);
+static int	create_parent_dir(struct archive_write_disk *, wchar_t *);
+static int	la_chmod(const wchar_t *, mode_t);
+static int	older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
+static int	permissive_name_w(struct archive_write_disk *);
+static int	restore_entry(struct archive_write_disk *);
+static int	set_acls(struct archive_write_disk *, HANDLE h,
+		    const wchar_t *, struct archive_acl *);
+static int	set_xattrs(struct archive_write_disk *);
+static int	set_fflags(struct archive_write_disk *);
+static int	set_ownership(struct archive_write_disk *);
+static int	set_mode(struct archive_write_disk *, int mode);
+static int	set_times(struct archive_write_disk *, HANDLE, int,
+		    const wchar_t *, time_t, long, time_t, long, time_t,
+		    long, time_t, long);
+static int	set_times_from_entry(struct archive_write_disk *);
+static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
+static ssize_t	write_data_block(struct archive_write_disk *,
+		    const char *, size_t);
+
+static struct archive_vtable *archive_write_disk_vtable(void);
+
+static int	_archive_write_disk_close(struct archive *);
+static int	_archive_write_disk_free(struct archive *);
+static int	_archive_write_disk_header(struct archive *,
+		    struct archive_entry *);
+static int64_t	_archive_write_disk_filter_bytes(struct archive *, int);
+static int	_archive_write_disk_finish_entry(struct archive *);
+static ssize_t	_archive_write_disk_data(struct archive *, const void *,
+		    size_t);
+static ssize_t	_archive_write_disk_data_block(struct archive *, const void *,
+		    size_t, int64_t);
+
+#define bhfi_dev(bhfi)	((bhfi)->dwVolumeSerialNumber)
+/* Treat FileIndex as i-node. We should remove a sequence number
+ * which is high-16-bits of nFileIndexHigh. */
+#define bhfi_ino(bhfi)	\
+	((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+    + (bhfi)->nFileIndexLow)
+#define bhfi_size(bhfi)	\
+    ((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
+
+static int
+file_information(struct archive_write_disk *a, wchar_t *path,
+    BY_HANDLE_FILE_INFORMATION *st, mode_t *mode, int sim_lstat)
+{
+	HANDLE h;
+	int r;
+	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+	WIN32_FIND_DATAW	findData;
+
+	if (sim_lstat || mode != NULL) {
+		h = FindFirstFileW(path, &findData);
+		if (h == INVALID_HANDLE_VALUE &&
+		    GetLastError() == ERROR_INVALID_NAME) {
+			wchar_t *full;
+			full = __la_win_permissive_name_w(path);
+			h = FindFirstFileW(full, &findData);
+			free(full);
+		}
+		if (h == INVALID_HANDLE_VALUE) {
+			la_dosmaperr(GetLastError());
+			return (-1);
+		}
+		FindClose(h);
+	}
+
+	/* Is symlink file ? */
+	if (sim_lstat && 
+	    ((findData.dwFileAttributes
+		        & FILE_ATTRIBUTE_REPARSE_POINT) &&
+		(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
+		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+	h = CreateFileW(a->name, 0, 0, NULL,
+	    OPEN_EXISTING, flag, NULL);
+	if (h == INVALID_HANDLE_VALUE &&
+	    GetLastError() == ERROR_INVALID_NAME) {
+		wchar_t *full;
+		full = __la_win_permissive_name_w(path);
+		h = CreateFileW(full, 0, 0, NULL,
+		    OPEN_EXISTING, flag, NULL);
+		free(full);
+	}
+	if (h == INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+	r = GetFileInformationByHandle(h, st);
+	CloseHandle(h);
+	if (r == 0) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+
+	if (mode == NULL)
+		return (0);
+
+	*mode = S_IRUSR | S_IRGRP | S_IROTH;
+	if ((st->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+		*mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+	if ((st->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+	    findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+		*mode |= S_IFLNK;
+	else if (st->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		*mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+	else {
+		const wchar_t *p;
+
+		*mode |= S_IFREG;
+		p = wcsrchr(path, L'.');
+		if (p != NULL && wcslen(p) == 4) {
+			switch (p[1]) {
+			case L'B': case L'b':
+				if ((p[2] == L'A' || p[2] == L'a' ) &&
+				    (p[3] == L'T' || p[3] == L't' ))
+					*mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+				break;
+			case L'C': case L'c':
+				if (((p[2] == L'M' || p[2] == L'm' ) &&
+				    (p[3] == L'D' || p[3] == L'd' )) ||
+				    ((p[2] == L'M' || p[2] == L'm' ) &&
+				    (p[3] == L'D' || p[3] == L'd' )))
+					*mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+				break;
+			case L'E': case L'e':
+				if ((p[2] == L'X' || p[2] == L'x' ) &&
+				    (p[3] == L'E' || p[3] == L'e' ))
+					*mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	return (0);
+}
+
+/* 
+ * Note: The path, for example, "aa/a/../b../c" will be converted to "aa/c"
+ * by GetFullPathNameW() W32 API, which __la_win_permissive_name_w uses.
+ * It means we cannot handle multiple dirs in one archive_entry.
+ * So we have to make the full-pathname in another way, which does not
+ * break "../" path string.
+ */
+static int
+permissive_name_w(struct archive_write_disk *a)
+{
+	wchar_t *wn, *wnp;
+	wchar_t *ws, *wsp;
+	DWORD l;
+
+	wnp = a->name;
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+	    wnp[2] == L'?' && wnp[3] == L'\\')
+		/* We have already a permissive name. */
+		return (0);
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+		wnp[2] == L'.' && wnp[3] == L'\\') {
+		/* This is a device name */
+		if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+		     (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+			 wnp[5] == L':' && wnp[6] == L'\\') {
+			wnp[2] = L'?';/* Not device name. */
+			return (0);
+		}
+	}
+
+	/*
+	 * A full-pathname starting with a drive name like "C:\abc".
+	 */
+	if (((wnp[0] >= L'a' && wnp[0] <= L'z') ||
+	     (wnp[0] >= L'A' && wnp[0] <= L'Z')) &&
+		 wnp[1] == L':' && wnp[2] == L'\\') {
+		wn = _wcsdup(wnp);
+		if (wn == NULL)
+			return (-1);
+		archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
+		a->name = a->_name_data.s;
+		/* Prepend "\\?\" */
+		archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+		archive_wstrcat(&(a->_name_data), wn);
+		free(wn);
+		return (0);
+	}
+
+	/*
+	 * A full-pathname pointig a network drive
+	 * like "\\<server-name>\<share-name>\file". 
+	 */
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+		const wchar_t *p = &wnp[2];
+
+		/* Skip server-name letters. */
+		while (*p != L'\\' && *p != L'\0')
+			++p;
+		if (*p == L'\\') {
+			const wchar_t *rp = ++p;
+			/* Skip share-name letters. */
+			while (*p != L'\\' && *p != L'\0')
+				++p;
+			if (*p == L'\\' && p != rp) {
+				/* Now, match patterns such as
+				 * "\\server-name\share-name\" */
+				wn = _wcsdup(wnp);
+				if (wn == NULL)
+					return (-1);
+				archive_wstring_ensure(&(a->_name_data),
+					8 + wcslen(wn) + 1);
+				a->name = a->_name_data.s;
+				/* Prepend "\\?\UNC\" */
+				archive_wstrncpy(&(a->_name_data),
+					L"\\\\?\\UNC\\", 8);
+				archive_wstrcat(&(a->_name_data), wn+2);
+				free(wn);
+				return (0);
+			}
+		}
+		return (0);
+	}
+
+	/*
+	 * Get current working directory.
+	 */
+	l = GetCurrentDirectoryW(0, NULL);
+	if (l == 0)
+		return (-1);
+	ws = malloc(l * sizeof(wchar_t));
+	l = GetCurrentDirectoryW(l, ws);
+	if (l == 0) {
+		free(ws);
+		return (-1);
+	}
+	wsp = ws;
+
+	/*
+	 * A full-pathname starting without a drive name like "\abc".
+	 */
+	if (wnp[0] == L'\\') {
+		wn = _wcsdup(wnp);
+		if (wn == NULL)
+			return (-1);
+		archive_wstring_ensure(&(a->_name_data),
+			4 + 2 + wcslen(wn) + 1);
+		a->name = a->_name_data.s;
+		/* Prepend "\\?\" and drive name. */
+		archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+		archive_wstrncat(&(a->_name_data), wsp, 2);
+		archive_wstrcat(&(a->_name_data), wn);
+		free(wsp);
+		free(wn);
+		return (0);
+	}
+
+	wn = _wcsdup(wnp);
+	if (wn == NULL)
+		return (-1);
+	archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
+	a->name = a->_name_data.s;
+	/* Prepend "\\?\" and drive name. */
+	archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+	archive_wstrncat(&(a->_name_data), wsp, l);
+	archive_wstrncat(&(a->_name_data), L"\\", 1);
+	archive_wstrcat(&(a->_name_data), wn);
+	a->name = a->_name_data.s;
+	free(wsp);
+	free(wn);
+	return (0);
+}
+
+static int
+la_chmod(const wchar_t *path, mode_t mode)
+{
+	DWORD attr;
+	BOOL r;
+	wchar_t *fullname;
+	int ret = 0;
+
+	fullname = NULL;
+	attr = GetFileAttributesW(path);
+	if (attr == (DWORD)-1 &&
+	    GetLastError() == ERROR_INVALID_NAME) {
+		fullname = __la_win_permissive_name_w(path);
+		attr = GetFileAttributesW(fullname);
+	}
+	if (attr == (DWORD)-1) {
+		la_dosmaperr(GetLastError());
+		ret = -1;
+		goto exit_chmode;
+	}
+	if (mode & _S_IWRITE)
+		attr &= ~FILE_ATTRIBUTE_READONLY;
+	else
+		attr |= FILE_ATTRIBUTE_READONLY;
+	if (fullname != NULL)
+		r = SetFileAttributesW(fullname, attr);
+	else
+		r = SetFileAttributesW(path, attr);
+	if (r == 0) {
+		la_dosmaperr(GetLastError());
+		ret = -1;
+	}
+exit_chmode:
+	free(fullname);
+	return (ret);
+}
+
+static void *
+la_GetFunctionKernel32(const char *name)
+{
+	static HINSTANCE lib;
+	static int set;
+	if (!set) {
+		set = 1;
+		lib = LoadLibrary("kernel32.dll");
+	}
+	if (lib == NULL) {
+		fprintf(stderr, "Can't load kernel32.dll?!\n");
+		exit(1);
+	}
+	return (void *)GetProcAddress(lib, name);
+}
+
+static int
+la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
+{
+	static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
+	static int set;
+	BOOL ret;
+
+	if (!set) {
+		set = 1;
+		f = la_GetFunctionKernel32("CreateHardLinkW");
+	}
+	if (!f)
+		return (0);
+	ret = (*f)(linkname, target, NULL);
+	if (!ret) {
+		/* Under windows 2000, it is necessary to remove
+		 * the "\\?\" prefix. */
+#define IS_UNC(name)	((name[0] == L'U' || name[0] == L'u') &&	\
+			 (name[1] == L'N' || name[1] == L'n') &&	\
+			 (name[2] == L'C' || name[2] == L'c') &&	\
+			 name[3] == L'\\')
+		if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
+			linkname += 4;
+			if (IS_UNC(linkname))
+				linkname += 4;
+		}
+		if (!wcsncmp(target,L"\\\\?\\", 4)) {
+			target += 4;
+			if (IS_UNC(target))
+				target += 4;
+		}
+#undef IS_UNC
+		ret = (*f)(linkname, target, NULL);
+	}
+	return (ret);
+}
+
+static int
+la_ftruncate(HANDLE handle, int64_t length)
+{
+	LARGE_INTEGER distance;
+
+	if (GetFileType(handle) != FILE_TYPE_DISK) {
+		errno = EBADF;
+		return (-1);
+	}
+	distance.QuadPart = length;
+	if (!SetFilePointerEx_perso(handle, distance, NULL, FILE_BEGIN)) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+	if (!SetEndOfFile(handle)) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+	return (0);
+}
+
+static int
+lazy_stat(struct archive_write_disk *a)
+{
+	if (a->pst != NULL) {
+		/* Already have stat() data available. */
+		return (ARCHIVE_OK);
+	}
+	if (a->fh != INVALID_HANDLE_VALUE &&
+	    GetFileInformationByHandle(a->fh, &a->st) == 0) {
+		a->pst = &a->st;
+		return (ARCHIVE_OK);
+	}
+
+	/*
+	 * XXX At this point, symlinks should not be hit, otherwise
+	 * XXX a race occurred.  Do we want to check explicitly for that?
+	 */
+	if (file_information(a, a->name, &a->st, NULL, 1) == 0) {
+		a->pst = &a->st;
+		return (ARCHIVE_OK);
+	}
+	archive_set_error(&a->archive, errno, "Couldn't stat file");
+	return (ARCHIVE_WARN);
+}
+
+static struct archive_vtable *
+archive_write_disk_vtable(void)
+{
+	static struct archive_vtable av;
+	static int inited = 0;
+
+	if (!inited) {
+		av.archive_close = _archive_write_disk_close;
+		av.archive_filter_bytes = _archive_write_disk_filter_bytes;
+		av.archive_free = _archive_write_disk_free;
+		av.archive_write_header = _archive_write_disk_header;
+		av.archive_write_finish_entry
+		    = _archive_write_disk_finish_entry;
+		av.archive_write_data = _archive_write_disk_data;
+		av.archive_write_data_block = _archive_write_disk_data_block;
+		inited = 1;
+	}
+	return (&av);
+}
+
+static int64_t
+_archive_write_disk_filter_bytes(struct archive *_a, int n)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	(void)n; /* UNUSED */
+	if (n == -1 || n == 0)
+		return (a->total_bytes_written);
+	return (-1);
+}
+
+
+int
+archive_write_disk_set_options(struct archive *_a, int flags)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+	a->flags = flags;
+	return (ARCHIVE_OK);
+}
+
+
+/*
+ * Extract this entry to disk.
+ *
+ * TODO: Validate hardlinks.  According to the standards, we're
+ * supposed to check each extracted hardlink and squawk if it refers
+ * to a file that we didn't restore.  I'm not entirely convinced this
+ * is a good idea, but more importantly: Is there any way to validate
+ * hardlinks without keeping a complete list of filenames from the
+ * entire archive?? Ugh.
+ *
+ */
+static int
+_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	struct fixup_entry *fe;
+	int ret, r;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_write_disk_header");
+	archive_clear_error(&a->archive);
+	if (a->archive.state & ARCHIVE_STATE_DATA) {
+		r = _archive_write_disk_finish_entry(&a->archive);
+		if (r == ARCHIVE_FATAL)
+			return (r);
+	}
+
+	/* Set up for this particular entry. */
+	a->pst = NULL;
+	a->current_fixup = NULL;
+	a->deferred = 0;
+	if (a->entry) {
+		archive_entry_free(a->entry);
+		a->entry = NULL;
+	}
+	a->entry = archive_entry_clone(entry);
+	a->fh = INVALID_HANDLE_VALUE;
+	a->fd_offset = 0;
+	a->offset = 0;
+	a->restore_pwd = -1;
+	a->uid = a->user_uid;
+	a->mode = archive_entry_mode(a->entry);
+	if (archive_entry_size_is_set(a->entry))
+		a->filesize = archive_entry_size(a->entry);
+	else
+		a->filesize = -1;
+	archive_wstrcpy(&(a->_name_data), archive_entry_pathname_w(a->entry));
+	a->name = a->_name_data.s;
+	archive_clear_error(&a->archive);
+
+	/*
+	 * Clean up the requested path.  This is necessary for correct
+	 * dir restores; the dir restore logic otherwise gets messed
+	 * up by nonsense like "dir/.".
+	 */
+	ret = cleanup_pathname(a);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	/*
+	 * Generate a full-pathname and use it from here.
+	 */
+	if (permissive_name_w(a) < 0) {
+		errno = EINVAL;
+		return (ARCHIVE_FAILED);
+	}
+
+	/*
+	 * Query the umask so we get predictable mode settings.
+	 * This gets done on every call to _write_header in case the
+	 * user edits their umask during the extraction for some
+	 * reason.
+	 */
+	umask(a->user_umask = umask(0));
+
+	/* Figure out what we need to do for this entry. */
+	a->todo = TODO_MODE_BASE;
+	if (a->flags & ARCHIVE_EXTRACT_PERM) {
+		a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
+		/*
+		 * SGID requires an extra "check" step because we
+		 * cannot easily predict the GID that the system will
+		 * assign.  (Different systems assign GIDs to files
+		 * based on a variety of criteria, including process
+		 * credentials and the gid of the enclosing
+		 * directory.)  We can only restore the SGID bit if
+		 * the file has the right GID, and we only know the
+		 * GID if we either set it (see set_ownership) or if
+		 * we've actually called stat() on the file after it
+		 * was restored.  Since there are several places at
+		 * which we might verify the GID, we need a TODO bit
+		 * to keep track.
+		 */
+		if (a->mode & S_ISGID)
+			a->todo |= TODO_SGID | TODO_SGID_CHECK;
+		/*
+		 * Verifying the SUID is simpler, but can still be
+		 * done in multiple ways, hence the separate "check" bit.
+		 */
+		if (a->mode & S_ISUID)
+			a->todo |= TODO_SUID | TODO_SUID_CHECK;
+	} else {
+		/*
+		 * User didn't request full permissions, so don't
+		 * restore SUID, SGID bits and obey umask.
+		 */
+		a->mode &= ~S_ISUID;
+		a->mode &= ~S_ISGID;
+		a->mode &= ~S_ISVTX;
+		a->mode &= ~a->user_umask;
+	}
+#if 0
+	if (a->flags & ARCHIVE_EXTRACT_OWNER)
+		a->todo |= TODO_OWNER;
+#endif
+	if (a->flags & ARCHIVE_EXTRACT_TIME)
+		a->todo |= TODO_TIMES;
+	if (a->flags & ARCHIVE_EXTRACT_ACL) {
+		if (archive_entry_filetype(a->entry) == AE_IFDIR)
+			a->deferred |= TODO_ACLS;
+		else
+			a->todo |= TODO_ACLS;
+	}
+	if (a->flags & ARCHIVE_EXTRACT_XATTR)
+		a->todo |= TODO_XATTR;
+	if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
+		a->todo |= TODO_FFLAGS;
+	if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
+		ret = check_symlinks(a);
+		if (ret != ARCHIVE_OK)
+			return (ret);
+	}
+
+	ret = restore_entry(a);
+
+	/*
+	 * TODO: There are rumours that some extended attributes must
+	 * be restored before file data is written.  If this is true,
+	 * then we either need to write all extended attributes both
+	 * before and after restoring the data, or find some rule for
+	 * determining which must go first and which last.  Due to the
+	 * many ways people are using xattrs, this may prove to be an
+	 * intractable problem.
+	 */
+
+	/*
+	 * Fixup uses the unedited pathname from archive_entry_pathname(),
+	 * because it is relative to the base dir and the edited path
+	 * might be relative to some intermediate dir as a result of the
+	 * deep restore logic.
+	 */
+	if (a->deferred & TODO_MODE) {
+		fe = current_fixup(a, archive_entry_pathname_w(entry));
+		fe->fixup |= TODO_MODE_BASE;
+		fe->mode = a->mode;
+	}
+
+	if ((a->deferred & TODO_TIMES)
+		&& (archive_entry_mtime_is_set(entry)
+		    || archive_entry_atime_is_set(entry))) {
+		fe = current_fixup(a, archive_entry_pathname_w(entry));
+		fe->mode = a->mode;
+		fe->fixup |= TODO_TIMES;
+		if (archive_entry_atime_is_set(entry)) {
+			fe->atime = archive_entry_atime(entry);
+			fe->atime_nanos = archive_entry_atime_nsec(entry);
+		} else {
+			/* If atime is unset, use start time. */
+			fe->atime = a->start_time;
+			fe->atime_nanos = 0;
+		}
+		if (archive_entry_mtime_is_set(entry)) {
+			fe->mtime = archive_entry_mtime(entry);
+			fe->mtime_nanos = archive_entry_mtime_nsec(entry);
+		} else {
+			/* If mtime is unset, use start time. */
+			fe->mtime = a->start_time;
+			fe->mtime_nanos = 0;
+		}
+		if (archive_entry_birthtime_is_set(entry)) {
+			fe->birthtime = archive_entry_birthtime(entry);
+			fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
+		} else {
+			/* If birthtime is unset, use mtime. */
+			fe->birthtime = fe->mtime;
+			fe->birthtime_nanos = fe->mtime_nanos;
+		}
+	}
+
+	if (a->deferred & TODO_ACLS) {
+		fe = current_fixup(a, archive_entry_pathname_w(entry));
+		archive_acl_copy(&fe->acl, archive_entry_acl(entry));
+	}
+
+	if (a->deferred & TODO_FFLAGS) {
+		fe = current_fixup(a, archive_entry_pathname_w(entry));
+		fe->fixup |= TODO_FFLAGS;
+		/* TODO: Complete this.. defer fflags from below. */
+	}
+
+	/*
+	 * On Windows, A creating sparse file requires a special mark.
+	 */
+	if (a->fh != INVALID_HANDLE_VALUE &&
+	    archive_entry_sparse_count(entry) > 0) {
+		int64_t base = 0, offset, length;
+		int i, cnt = archive_entry_sparse_reset(entry);
+		int sparse = 0;
+
+		for (i = 0; i < cnt; i++) {
+			archive_entry_sparse_next(entry, &offset, &length);
+			if (offset - base >= 4096) {
+				sparse = 1;/* we have a hole. */
+				break;
+			}
+			base = offset + length;
+		}
+		if (sparse) {
+			DWORD dmy;
+			/* Mark this file as sparse. */
+			DeviceIoControl(a->fh, FSCTL_SET_SPARSE,
+			    NULL, 0, NULL, 0, &dmy, NULL);
+		}
+	}
+
+	/* We've created the object and are ready to pour data into it. */
+	if (ret >= ARCHIVE_WARN)
+		a->archive.state = ARCHIVE_STATE_DATA;
+	/*
+	 * If it's not open, tell our client not to try writing.
+	 * In particular, dirs, links, etc, don't get written to.
+	 */
+	if (a->fh == INVALID_HANDLE_VALUE) {
+		archive_entry_set_size(entry, 0);
+		a->filesize = 0;
+	}
+
+	return (ret);
+}
+
+int
+archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
+	a->skip_file_set = 1;
+	a->skip_file_dev = d;
+	a->skip_file_ino = i;
+	return (ARCHIVE_OK);
+}
+
+static ssize_t
+write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
+{
+	OVERLAPPED ol;
+	uint64_t start_size = size;
+	DWORD bytes_written = 0;
+	ssize_t block_size = 0, bytes_to_write;
+
+	if (size == 0)
+		return (ARCHIVE_OK);
+
+	if (a->filesize == 0 || a->fh == INVALID_HANDLE_VALUE) {
+		archive_set_error(&a->archive, 0,
+		    "Attempt to write to an empty file");
+		return (ARCHIVE_WARN);
+	}
+
+	if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
+		/* XXX TODO XXX Is there a more appropriate choice here ? */
+		/* This needn't match the filesystem allocation size. */
+		block_size = 16*1024;
+	}
+
+	/* If this write would run beyond the file size, truncate it. */
+	if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
+		start_size = size = (size_t)(a->filesize - a->offset);
+
+	/* Write the data. */
+	while (size > 0) {
+		if (block_size == 0) {
+			bytes_to_write = size;
+		} else {
+			/* We're sparsifying the file. */
+			const char *p, *end;
+			int64_t block_end;
+
+			/* Skip leading zero bytes. */
+			for (p = buff, end = buff + size; p < end; ++p) {
+				if (*p != '\0')
+					break;
+			}
+			a->offset += p - buff;
+			size -= p - buff;
+			buff = p;
+			if (size == 0)
+				break;
+
+			/* Calculate next block boundary after offset. */
+			block_end
+			    = (a->offset / block_size + 1) * block_size;
+
+			/* If the adjusted write would cross block boundary,
+			 * truncate it to the block boundary. */
+			bytes_to_write = size;
+			if (a->offset + bytes_to_write > block_end)
+				bytes_to_write = (DWORD)(block_end - a->offset);
+		}
+		memset(&ol, 0, sizeof(ol));
+		ol.Offset = (DWORD)(a->offset & 0xFFFFFFFF);
+		ol.OffsetHigh = (DWORD)(a->offset >> 32);
+		if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write,
+		    &bytes_written, &ol)) {
+			DWORD lasterr;
+
+			lasterr = GetLastError();
+			if (lasterr == ERROR_ACCESS_DENIED)
+				errno = EBADF;
+			else
+				la_dosmaperr(lasterr);
+			archive_set_error(&a->archive, errno, "Write failed");
+			return (ARCHIVE_WARN);
+		}
+		buff += bytes_written;
+		size -= bytes_written;
+		a->total_bytes_written += bytes_written;
+		a->offset += bytes_written;
+		a->fd_offset = a->offset;
+	}
+	return ((ssize_t)(start_size - size));
+}
+
+static ssize_t
+_archive_write_disk_data_block(struct archive *_a,
+    const void *buff, size_t size, int64_t offset)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	ssize_t r;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_DATA, "archive_write_data_block");
+
+	a->offset = offset;
+	r = write_data_block(a, buff, size);
+	if (r < ARCHIVE_OK)
+		return (r);
+	if ((size_t)r < size) {
+		archive_set_error(&a->archive, 0,
+		    "Write request too large");
+		return (ARCHIVE_WARN);
+	}
+	return (ARCHIVE_OK);
+}
+
+static ssize_t
+_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_DATA, "archive_write_data");
+
+	return (write_data_block(a, buff, size));
+}
+
+static int
+_archive_write_disk_finish_entry(struct archive *_a)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	int ret = ARCHIVE_OK;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_write_finish_entry");
+	if (a->archive.state & ARCHIVE_STATE_HEADER)
+		return (ARCHIVE_OK);
+	archive_clear_error(&a->archive);
+
+	/* Pad or truncate file to the right size. */
+	if (a->fh == INVALID_HANDLE_VALUE) {
+		/* There's no file. */
+	} else if (a->filesize < 0) {
+		/* File size is unknown, so we can't set the size. */
+	} else if (a->fd_offset == a->filesize) {
+		/* Last write ended at exactly the filesize; we're done. */
+		/* Hopefully, this is the common case. */
+	} else {
+		if (la_ftruncate(a->fh, a->filesize) == -1) {
+			archive_set_error(&a->archive, errno,
+			    "File size could not be restored");
+			return (ARCHIVE_FAILED);
+		}
+	}
+
+	/* Restore metadata. */
+
+	/*
+	 * Look up the "real" UID only if we're going to need it.
+	 * TODO: the TODO_SGID condition can be dropped here, can't it?
+	 */
+	if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
+		a->uid = archive_write_disk_uid(&a->archive,
+		    archive_entry_uname(a->entry),
+		    archive_entry_uid(a->entry));
+	}
+	/* Look up the "real" GID only if we're going to need it. */
+	/* TODO: the TODO_SUID condition can be dropped here, can't it? */
+	if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
+		a->gid = archive_write_disk_gid(&a->archive,
+		    archive_entry_gname(a->entry),
+		    archive_entry_gid(a->entry));
+	 }
+
+	/*
+	 * Restore ownership before set_mode tries to restore suid/sgid
+	 * bits.  If we set the owner, we know what it is and can skip
+	 * a stat() call to examine the ownership of the file on disk.
+	 */
+	if (a->todo & TODO_OWNER)
+		ret = set_ownership(a);
+
+	/*
+	 * set_mode must precede ACLs on systems such as Solaris and
+	 * FreeBSD where setting the mode implicitly clears extended ACLs
+	 */
+	if (a->todo & TODO_MODE) {
+		int r2 = set_mode(a, a->mode);
+		if (r2 < ret) ret = r2;
+	}
+
+	/*
+	 * Security-related extended attributes (such as
+	 * security.capability on Linux) have to be restored last,
+	 * since they're implicitly removed by other file changes.
+	 */
+	if (a->todo & TODO_XATTR) {
+		int r2 = set_xattrs(a);
+		if (r2 < ret) ret = r2;
+	}
+
+	/*
+	 * Some flags prevent file modification; they must be restored after
+	 * file contents are written.
+	 */
+	if (a->todo & TODO_FFLAGS) {
+		int r2 = set_fflags(a);
+		if (r2 < ret) ret = r2;
+	}
+
+	/*
+	 * Time must follow most other metadata;
+	 * otherwise atime will get changed.
+	 */
+	if (a->todo & TODO_TIMES) {
+		int r2 = set_times_from_entry(a);
+		if (r2 < ret) ret = r2;
+	}
+
+	/*
+	 * ACLs must be restored after timestamps because there are
+	 * ACLs that prevent attribute changes (including time).
+	 */
+	if (a->todo & TODO_ACLS) {
+		int r2 = set_acls(a, a->fh,
+				  archive_entry_pathname_w(a->entry),
+				  archive_entry_acl(a->entry));
+		if (r2 < ret) ret = r2;
+	}
+
+	/* If there's an fd, we can close it now. */
+	if (a->fh != INVALID_HANDLE_VALUE) {
+		CloseHandle(a->fh);
+		a->fh = INVALID_HANDLE_VALUE;
+	}
+	/* If there's an entry, we can release it now. */
+	if (a->entry) {
+		archive_entry_free(a->entry);
+		a->entry = NULL;
+	}
+	a->archive.state = ARCHIVE_STATE_HEADER;
+	return (ret);
+}
+
+int
+archive_write_disk_set_group_lookup(struct archive *_a,
+    void *private_data,
+    int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
+    void (*cleanup_gid)(void *private))
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+
+	if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+		(a->cleanup_gid)(a->lookup_gid_data);
+
+	a->lookup_gid = lookup_gid;
+	a->cleanup_gid = cleanup_gid;
+	a->lookup_gid_data = private_data;
+	return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_user_lookup(struct archive *_a,
+    void *private_data,
+    int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
+    void (*cleanup_uid)(void *private))
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+
+	if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+		(a->cleanup_uid)(a->lookup_uid_data);
+
+	a->lookup_uid = lookup_uid;
+	a->cleanup_uid = cleanup_uid;
+	a->lookup_uid_data = private_data;
+	return (ARCHIVE_OK);
+}
+
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+       struct archive_write_disk *a = (struct archive_write_disk *)_a;
+       archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+           ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+       if (a->lookup_gid)
+               return (a->lookup_gid)(a->lookup_gid_data, name, id);
+       return (id);
+}
+ 
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+       struct archive_write_disk *a = (struct archive_write_disk *)_a;
+       archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+           ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+       if (a->lookup_uid)
+               return (a->lookup_uid)(a->lookup_uid_data, name, id);
+       return (id);
+}
+
+/*
+ * Create a new archive_write_disk object and initialize it with global state.
+ */
+struct archive *
+archive_write_disk_new(void)
+{
+	struct archive_write_disk *a;
+
+	a = (struct archive_write_disk *)malloc(sizeof(*a));
+	if (a == NULL)
+		return (NULL);
+	memset(a, 0, sizeof(*a));
+	a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
+	/* We're ready to write a header immediately. */
+	a->archive.state = ARCHIVE_STATE_HEADER;
+	a->archive.vtable = archive_write_disk_vtable();
+	a->start_time = time(NULL);
+	/* Query and restore the umask. */
+	umask(a->user_umask = umask(0));
+	if (archive_wstring_ensure(&a->path_safe, 512) == NULL) {
+		free(a);
+		return (NULL);
+	}
+	return (&a->archive);
+}
+
+static int
+disk_unlink(wchar_t *path)
+{
+	wchar_t *fullname;
+	int r;
+
+	r = _wunlink(path);
+	if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
+		fullname = __la_win_permissive_name_w(path);
+		r = _wunlink(fullname);
+		free(fullname);
+	}
+	return (r);
+}
+
+static int
+disk_rmdir(wchar_t *path)
+{
+	wchar_t *fullname;
+	int r;
+
+	r = _wrmdir(path);
+	if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
+		fullname = __la_win_permissive_name_w(path);
+		r = _wrmdir(fullname);
+		free(fullname);
+	}
+	return (r);
+}
+
+/*
+ * The main restore function.
+ */
+static int
+restore_entry(struct archive_write_disk *a)
+{
+	int ret = ARCHIVE_OK, en;
+
+	if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
+		/*
+		 * TODO: Fix this.  Apparently, there are platforms
+		 * that still allow root to hose the entire filesystem
+		 * by unlinking a dir.  The S_ISDIR() test above
+		 * prevents us from using unlink() here if the new
+		 * object is a dir, but that doesn't mean the old
+		 * object isn't a dir.
+		 */
+		if (disk_unlink(a->name) == 0) {
+			/* We removed it, reset cached stat. */
+			a->pst = NULL;
+		} else if (errno == ENOENT) {
+			/* File didn't exist, that's just as good. */
+		} else if (disk_rmdir(a->name) == 0) {
+			/* It was a dir, but now it's gone. */
+			a->pst = NULL;
+		} else {
+			/* We tried, but couldn't get rid of it. */
+			archive_set_error(&a->archive, errno,
+			    "Could not unlink");
+			return(ARCHIVE_FAILED);
+		}
+	}
+
+	/* Try creating it first; if this fails, we'll try to recover. */
+	en = create_filesystem_object(a);
+
+	if ((en == ENOTDIR || en == ENOENT)
+	    && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
+		wchar_t *full;
+		/* If the parent dir doesn't exist, try creating it. */
+		create_parent_dir(a, a->name);
+		/* Now try to create the object again. */
+		full = __la_win_permissive_name_w(a->name);
+		if (full == NULL) {
+			en = EINVAL;
+		} else {
+			/* Remove multiple directories such as "a/../b../c" */
+			archive_wstrcpy(&(a->_name_data), full);
+			a->name = a->_name_data.s;
+			free(full);
+			en = create_filesystem_object(a);
+		}
+	}
+
+	if ((en == EISDIR || en == EEXIST)
+	    && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+		/* If we're not overwriting, we're done. */
+		archive_entry_unset_size(a->entry);
+		return (ARCHIVE_OK);
+	}
+
+	/*
+	 * Some platforms return EISDIR if you call
+	 * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
+	 * return EEXIST.  POSIX is ambiguous, requiring EISDIR
+	 * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
+	 * on an existing item.
+	 */
+	if (en == EISDIR) {
+		/* A dir is in the way of a non-dir, rmdir it. */
+		if (disk_rmdir(a->name) != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Can't remove already-existing dir");
+			return (ARCHIVE_FAILED);
+		}
+		a->pst = NULL;
+		/* Try again. */
+		en = create_filesystem_object(a);
+	} else if (en == EEXIST) {
+		mode_t st_mode;
+		/*
+		 * We know something is in the way, but we don't know what;
+		 * we need to find out before we go any further.
+		 */
+		int r = 0;
+		/*
+		 * The SECURE_SYMLINK logic has already removed a
+		 * symlink to a dir if the client wants that.  So
+		 * follow the symlink if we're creating a dir.
+		 */
+		if (S_ISDIR(a->mode))
+			r = file_information(a, a->name, &a->st, &st_mode, 0);
+		/*
+		 * If it's not a dir (or it's a broken symlink),
+		 * then don't follow it.
+		 */
+		if (r != 0 || !S_ISDIR(a->mode))
+			r = file_information(a, a->name, &a->st, &st_mode, 1);
+		if (r != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Can't stat existing object");
+			return (ARCHIVE_FAILED);
+		}
+
+		/*
+		 * NO_OVERWRITE_NEWER doesn't apply to directories.
+		 */
+		if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
+		    &&  !S_ISDIR(st_mode)) {
+			if (!older(&(a->st), a->entry)) {
+				archive_entry_unset_size(a->entry);
+				return (ARCHIVE_OK);
+			}
+		}
+
+		/* If it's our archive, we're done. */
+		if (a->skip_file_set &&
+		    bhfi_dev(&a->st) == a->skip_file_dev &&
+		    bhfi_ino(&a->st) == a->skip_file_ino) {
+			archive_set_error(&a->archive, 0,
+			    "Refusing to overwrite archive");
+			return (ARCHIVE_FAILED);
+		}
+
+		if (!S_ISDIR(st_mode)) {
+			/* A non-dir is in the way, unlink it. */
+			if (disk_unlink(a->name) != 0) {
+				archive_set_error(&a->archive, errno,
+				    "Can't unlink already-existing object");
+				return (ARCHIVE_FAILED);
+			}
+			a->pst = NULL;
+			/* Try again. */
+			en = create_filesystem_object(a);
+		} else if (!S_ISDIR(a->mode)) {
+			/* A dir is in the way of a non-dir, rmdir it. */
+			if (disk_rmdir(a->name) != 0) {
+				archive_set_error(&a->archive, errno,
+				    "Can't remove already-existing dir");
+				return (ARCHIVE_FAILED);
+			}
+			/* Try again. */
+			en = create_filesystem_object(a);
+		} else {
+			/*
+			 * There's a dir in the way of a dir.  Don't
+			 * waste time with rmdir()/mkdir(), just fix
+			 * up the permissions on the existing dir.
+			 * Note that we don't change perms on existing
+			 * dirs unless _EXTRACT_PERM is specified.
+			 */
+			if ((a->mode != st_mode)
+			    && (a->todo & TODO_MODE_FORCE))
+				a->deferred |= (a->todo & TODO_MODE);
+			/* Ownership doesn't need deferred fixup. */
+			en = 0; /* Forget the EEXIST. */
+		}
+	}
+
+	if (en) {
+		/* Everything failed; give up here. */
+		archive_set_error(&a->archive, en, "Can't create '%ls'",
+		    a->name);
+		return (ARCHIVE_FAILED);
+	}
+
+	a->pst = NULL; /* Cached stat data no longer valid. */
+	return (ret);
+}
+
+/*
+ * Returns 0 if creation succeeds, or else returns errno value from
+ * the failed system call.   Note:  This function should only ever perform
+ * a single system call.
+ */
+static int
+create_filesystem_object(struct archive_write_disk *a)
+{
+	/* Create the entry. */
+	const wchar_t *linkname;
+	wchar_t *fullname;
+	mode_t final_mode, mode;
+	int r;
+
+	/* We identify hard/symlinks according to the link names. */
+	/* Since link(2) and symlink(2) don't handle modes, we're done here. */
+	linkname = archive_entry_hardlink_w(a->entry);
+	if (linkname != NULL) {
+		wchar_t *linkfull, *namefull;
+
+		linkfull = __la_win_permissive_name_w(linkname);
+		namefull = __la_win_permissive_name_w(a->name);
+		if (linkfull == NULL || namefull == NULL) {
+			errno = EINVAL;
+			r = -1;
+		} else {
+			r = la_CreateHardLinkW(namefull, linkfull);
+			if (r == 0) {
+				la_dosmaperr(GetLastError());
+				r = errno;
+			} else
+				r = 0;
+		}
+		/*
+		 * New cpio and pax formats allow hardlink entries
+		 * to carry data, so we may have to open the file
+		 * for hardlink entries.
+		 *
+		 * If the hardlink was successfully created and
+		 * the archive doesn't have carry data for it,
+		 * consider it to be non-authoritative for meta data.
+		 * This is consistent with GNU tar and BSD pax.
+		 * If the hardlink does carry data, let the last
+		 * archive entry decide ownership.
+		 */
+		if (r == 0 && a->filesize <= 0) {
+			a->todo = 0;
+			a->deferred = 0;
+		} else if (r == 0 && a->filesize > 0) {
+			a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
+			    TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+			if (a->fh == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				r = errno;
+			}
+		}
+		free(linkfull);
+		free(namefull);
+		return (r);
+	}
+	linkname = archive_entry_symlink_w(a->entry);
+	if (linkname != NULL) {
+#if HAVE_SYMLINK
+		return symlink(linkname, a->name) ? errno : 0;
+#else
+		return (EPERM);
+#endif
+	}
+
+	/*
+	 * The remaining system calls all set permissions, so let's
+	 * try to take advantage of that to avoid an extra chmod()
+	 * call.  (Recall that umask is set to zero right now!)
+	 */
+
+	/* Mode we want for the final restored object (w/o file type bits). */
+	final_mode = a->mode & 07777;
+	/*
+	 * The mode that will actually be restored in this step.  Note
+	 * that SUID, SGID, etc, require additional work to ensure
+	 * security, so we never restore them at this point.
+	 */
+	mode = final_mode & 0777 & ~a->user_umask;
+
+	switch (a->mode & AE_IFMT) {
+	default:
+		/* POSIX requires that we fall through here. */
+		/* FALLTHROUGH */
+	case AE_IFREG:
+		fullname = a->name;
+		/* O_WRONLY | O_CREAT | O_EXCL */
+		a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+		    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+		if (a->fh == INVALID_HANDLE_VALUE &&
+		    GetLastError() == ERROR_INVALID_NAME &&
+		    fullname == a->name) {
+			fullname = __la_win_permissive_name_w(a->name);
+			a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+			    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+		}
+		if (a->fh == INVALID_HANDLE_VALUE) {
+			if (GetLastError() == ERROR_ACCESS_DENIED) {
+				DWORD attr;
+				/* Simulate an errno of POSIX system. */
+				attr = GetFileAttributesW(fullname);
+				if (attr == (DWORD)-1)
+					la_dosmaperr(GetLastError());
+				else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+					errno = EISDIR;
+				else
+					errno = EACCES;
+			} else
+				la_dosmaperr(GetLastError());
+			r = 1;
+		} else
+			r = 0;
+		if (fullname != a->name)
+			free(fullname);
+		break;
+	case AE_IFCHR:
+	case AE_IFBLK:
+		/* TODO: Find a better way to warn about our inability
+		 * to restore a block device node. */
+		return (EINVAL);
+	case AE_IFDIR:
+		mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
+		fullname = a->name;
+		r = CreateDirectoryW(fullname, NULL);
+		if (r == 0 && GetLastError() == ERROR_INVALID_NAME &&
+			fullname == a->name) {
+			fullname = __la_win_permissive_name_w(a->name);
+			r = CreateDirectoryW(fullname, NULL);
+		}
+		if (r != 0) {
+			r = 0;
+			/* Defer setting dir times. */
+			a->deferred |= (a->todo & TODO_TIMES);
+			a->todo &= ~TODO_TIMES;
+			/* Never use an immediate chmod(). */
+			/* We can't avoid the chmod() entirely if EXTRACT_PERM
+			 * because of SysV SGID inheritance. */
+			if ((mode != final_mode)
+			    || (a->flags & ARCHIVE_EXTRACT_PERM))
+				a->deferred |= (a->todo & TODO_MODE);
+			a->todo &= ~TODO_MODE;
+		} else {
+			la_dosmaperr(GetLastError());
+			r = -1;
+		}
+		if (fullname != a->name)
+			free(fullname);
+		break;
+	case AE_IFIFO:
+		/* TODO: Find a better way to warn about our inability
+		 * to restore a fifo. */
+		return (EINVAL);
+	}
+
+	/* All the system calls above set errno on failure. */
+	if (r)
+		return (errno);
+
+	/* If we managed to set the final mode, we've avoided a chmod(). */
+	if (mode == final_mode)
+		a->todo &= ~TODO_MODE;
+	return (0);
+}
+
+/*
+ * Cleanup function for archive_extract.  Mostly, this involves processing
+ * the fixup list, which is used to address a number of problems:
+ *   * Dir permissions might prevent us from restoring a file in that
+ *     dir, so we restore the dir with minimum 0700 permissions first,
+ *     then correct the mode at the end.
+ *   * Similarly, the act of restoring a file touches the directory
+ *     and changes the timestamp on the dir, so we have to touch-up dir
+ *     timestamps at the end as well.
+ *   * Some file flags can interfere with the restore by, for example,
+ *     preventing the creation of hardlinks to those files.
+ *   * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
+ *
+ * Note that tar/cpio do not require that archives be in a particular
+ * order; there is no way to know when the last file has been restored
+ * within a directory, so there's no way to optimize the memory usage
+ * here by fixing up the directory any earlier than the
+ * end-of-archive.
+ *
+ * XXX TODO: Directory ACLs should be restored here, for the same
+ * reason we set directory perms here. XXX
+ */
+static int
+_archive_write_disk_close(struct archive *_a)
+{
+	struct archive_write_disk *a = (struct archive_write_disk *)_a;
+	struct fixup_entry *next, *p;
+	int ret;
+
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+	    "archive_write_disk_close");
+	ret = _archive_write_disk_finish_entry(&a->archive);
+
+	/* Sort dir list so directories are fixed up in depth-first order. */
+	p = sort_dir_list(a->fixup_list);
+
+	while (p != NULL) {
+		a->pst = NULL; /* Mark stat cache as out-of-date. */
+		if (p->fixup & TODO_TIMES) {
+			set_times(a, INVALID_HANDLE_VALUE, p->mode, p->name,
+			    p->atime, p->atime_nanos,
+			    p->birthtime, p->birthtime_nanos,
+			    p->mtime, p->mtime_nanos,
+			    p->ctime, p->ctime_nanos);
+		}
+		if (p->fixup & TODO_MODE_BASE)
+			la_chmod(p->name, p->mode);
+		if (p->fixup & TODO_ACLS)
+			set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
+		next = p->next;
+		archive_acl_clear(&p->acl);
+		free(p->name);
+		free(p);
+		p = next;
+	}
+	a->fixup_list = NULL;
+	return (ret);
+}
+
+static int
+_archive_write_disk_free(struct archive *_a)
+{
+	struct archive_write_disk *a;
+	int ret;
+	if (_a == NULL)
+		return (ARCHIVE_OK);
+	archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+	a = (struct archive_write_disk *)_a;
+	ret = _archive_write_disk_close(&a->archive);
+	archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+	archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
+	if (a->entry)
+		archive_entry_free(a->entry);
+	archive_wstring_free(&a->_name_data);
+	archive_string_free(&a->archive.error_string);
+	archive_wstring_free(&a->path_safe);
+	a->archive.magic = 0;
+	__archive_clean(&a->archive);
+	free(a);
+	return (ret);
+}
+
+/*
+ * Simple O(n log n) merge sort to order the fixup list.  In
+ * particular, we want to restore dir timestamps depth-first.
+ */
+static struct fixup_entry *
+sort_dir_list(struct fixup_entry *p)
+{
+	struct fixup_entry *a, *b, *t;
+
+	if (p == NULL)
+		return (NULL);
+	/* A one-item list is already sorted. */
+	if (p->next == NULL)
+		return (p);
+
+	/* Step 1: split the list. */
+	t = p;
+	a = p->next->next;
+	while (a != NULL) {
+		/* Step a twice, t once. */
+		a = a->next;
+		if (a != NULL)
+			a = a->next;
+		t = t->next;
+	}
+	/* Now, t is at the mid-point, so break the list here. */
+	b = t->next;
+	t->next = NULL;
+	a = p;
+
+	/* Step 2: Recursively sort the two sub-lists. */
+	a = sort_dir_list(a);
+	b = sort_dir_list(b);
+
+	/* Step 3: Merge the returned lists. */
+	/* Pick the first element for the merged list. */
+	if (wcscmp(a->name, b->name) > 0) {
+		t = p = a;
+		a = a->next;
+	} else {
+		t = p = b;
+		b = b->next;
+	}
+
+	/* Always put the later element on the list first. */
+	while (a != NULL && b != NULL) {
+		if (wcscmp(a->name, b->name) > 0) {
+			t->next = a;
+			a = a->next;
+		} else {
+			t->next = b;
+			b = b->next;
+		}
+		t = t->next;
+	}
+
+	/* Only one list is non-empty, so just splice it on. */
+	if (a != NULL)
+		t->next = a;
+	if (b != NULL)
+		t->next = b;
+
+	return (p);
+}
+
+/*
+ * Returns a new, initialized fixup entry.
+ *
+ * TODO: Reduce the memory requirements for this list by using a tree
+ * structure rather than a simple list of names.
+ */
+static struct fixup_entry *
+new_fixup(struct archive_write_disk *a, const wchar_t *pathname)
+{
+	struct fixup_entry *fe;
+
+	fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
+	if (fe == NULL)
+		return (NULL);
+	fe->next = a->fixup_list;
+	a->fixup_list = fe;
+	fe->fixup = 0;
+	fe->name = _wcsdup(pathname);
+	return (fe);
+}
+
+/*
+ * Returns a fixup structure for the current entry.
+ */
+static struct fixup_entry *
+current_fixup(struct archive_write_disk *a, const wchar_t *pathname)
+{
+	if (a->current_fixup == NULL)
+		a->current_fixup = new_fixup(a, pathname);
+	return (a->current_fixup);
+}
+
+/* TODO: Make this work. */
+/*
+ * TODO: The deep-directory support bypasses this; disable deep directory
+ * support if we're doing symlink checks.
+ */
+/*
+ * TODO: Someday, integrate this with the deep dir support; they both
+ * scan the path and both can be optimized by comparing against other
+ * recent paths.
+ */
+/* TODO: Extend this to support symlinks on Windows Vista and later. */
+static int
+check_symlinks(struct archive_write_disk *a)
+{
+	wchar_t *pn, *p;
+	wchar_t c;
+	int r;
+	BY_HANDLE_FILE_INFORMATION st;
+	mode_t st_mode;
+
+	/*
+	 * Guard against symlink tricks.  Reject any archive entry whose
+	 * destination would be altered by a symlink.
+	 */
+	/* Whatever we checked last time doesn't need to be re-checked. */
+	pn = a->name;
+	p = a->path_safe.s;
+	while ((*pn != '\0') && (*p == *pn))
+		++p, ++pn;
+	c = pn[0];
+	/* Keep going until we've checked the entire name. */
+	while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
+		/* Skip the next path element. */
+		while (*pn != '\0' && *pn != '\\')
+			++pn;
+		c = pn[0];
+		pn[0] = '\0';
+		/* Check that we haven't hit a symlink. */
+		r = file_information(a, a->name, &st, &st_mode, 1);
+		if (r != 0) {
+			/* We've hit a dir that doesn't exist; stop now. */
+			if (errno == ENOENT)
+				break;
+		} else if (S_ISLNK(st_mode)) {
+			if (c == '\0') {
+				/*
+				 * Last element is symlink; remove it
+				 * so we can overwrite it with the
+				 * item being extracted.
+				 */
+				if (disk_unlink(a->name)) {
+					archive_set_error(&a->archive, errno,
+					    "Could not remove symlink %ls",
+					    a->name);
+					pn[0] = c;
+					return (ARCHIVE_FAILED);
+				}
+				a->pst = NULL;
+				/*
+				 * Even if we did remove it, a warning
+				 * is in order.  The warning is silly,
+				 * though, if we're just replacing one
+				 * symlink with another symlink.
+				 */
+				if (!S_ISLNK(a->mode)) {
+					archive_set_error(&a->archive, 0,
+					    "Removing symlink %ls",
+					    a->name);
+				}
+				/* Symlink gone.  No more problem! */
+				pn[0] = c;
+				return (0);
+			} else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
+				/* User asked us to remove problems. */
+				if (disk_unlink(a->name) != 0) {
+					archive_set_error(&a->archive, 0,
+					    "Cannot remove intervening "
+					    "symlink %ls", a->name);
+					pn[0] = c;
+					return (ARCHIVE_FAILED);
+				}
+				a->pst = NULL;
+			} else {
+				archive_set_error(&a->archive, 0,
+				    "Cannot extract through symlink %ls",
+				    a->name);
+				pn[0] = c;
+				return (ARCHIVE_FAILED);
+			}
+		}
+	}
+	pn[0] = c;
+	/* We've checked and/or cleaned the whole path, so remember it. */
+	archive_wstrcpy(&a->path_safe, a->name);
+	return (ARCHIVE_OK);
+}
+
+static int
+guidword(wchar_t *p, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++) {
+		if ((*p >= L'0' && *p <= L'9') ||
+		    (*p >= L'a' && *p <= L'f') ||
+		    (*p >= L'A' && *p <= L'F'))
+			p++;
+		else
+			return (-1);
+	}
+	return (0);
+}
+
+/*
+ * Canonicalize the pathname.  In particular, this strips duplicate
+ * '\' characters, '.' elements, and trailing '\'.  It also raises an
+ * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is
+ * set) any '..' in the path.
+ */
+static int
+cleanup_pathname(struct archive_write_disk *a)
+{
+	wchar_t *dest, *src, *p, *top;
+	wchar_t separator = L'\0';
+
+	p = a->name;
+	if (*p == L'\0') {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Invalid empty pathname");
+		return (ARCHIVE_FAILED);
+	}
+
+	/* Replace '/' by '\' */
+	for (; *p != L'\0'; p++) {
+		if (*p == L'/')
+			*p = L'\\';
+	}
+	p = a->name;
+
+	/* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
+	 * "\\?\Volume{GUID}\"
+	 * (absolute path prefixes used by Windows API) */
+	if (p[0] == L'\\' && p[1] == L'\\' &&
+	    (p[2] == L'.' || p[2] == L'?') && p[3] ==  L'\\')
+	{
+		/* A path begin with "\\?\UNC\" */
+		if (p[2] == L'?' &&
+		    (p[4] == L'U' || p[4] == L'u') &&
+		    (p[5] == L'N' || p[5] == L'n') &&
+		    (p[6] == L'C' || p[6] == L'c') &&
+		    p[7] == L'\\')
+			p += 8;
+		/* A path begin with "\\?\Volume{GUID}\" */
+		else if (p[2] == L'?' &&
+		    (p[4] == L'V' || p[4] == L'v') &&
+		    (p[5] == L'O' || p[5] == L'o') &&
+		    (p[6] == L'L' || p[6] == L'l') &&
+		    (p[7] == L'U' || p[7] == L'u') &&
+		    (p[8] == L'M' || p[8] == L'm') &&
+		    (p[9] == L'E' || p[9] == L'e') &&
+		    p[10] == L'{') {
+			if (guidword(p+11, 8) == 0 && p[19] == L'-' &&
+			    guidword(p+20, 4) == 0 && p[24] == L'-' &&
+			    guidword(p+25, 4) == 0 && p[29] == L'-' &&
+			    guidword(p+30, 4) == 0 && p[34] == L'-' &&
+			    guidword(p+35, 12) == 0 && p[47] == L'}' &&
+			    p[48] == L'\\')
+				p += 49;
+			else
+				p += 4;
+		/* A path begin with "\\.\PhysicalDriveX" */
+		} else if (p[2] == L'.' &&
+		    (p[4] == L'P' || p[4] == L'p') &&
+		    (p[5] == L'H' || p[5] == L'h') &&
+		    (p[6] == L'Y' || p[6] == L'y') &&
+		    (p[7] == L'S' || p[7] == L's') &&
+		    (p[8] == L'I' || p[8] == L'i') &&
+		    (p[9] == L'C' || p[9] == L'c') &&
+		    (p[9] == L'A' || p[9] == L'a') &&
+		    (p[9] == L'L' || p[9] == L'l') &&
+		    (p[9] == L'D' || p[9] == L'd') &&
+		    (p[9] == L'R' || p[9] == L'r') &&
+		    (p[9] == L'I' || p[9] == L'i') &&
+		    (p[9] == L'V' || p[9] == L'v') &&
+		    (p[9] == L'E' || p[9] == L'e') &&
+		    (p[10] >= L'0' && p[10] <= L'9') &&
+		    p[11] == L'\0') {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Path is a physical drive name");
+			return (ARCHIVE_FAILED);
+		} else
+			p += 4;
+	}
+
+	/* Skip leading drive letter from archives created
+	 * on Windows. */
+	if (((p[0] >= L'a' && p[0] <= L'z') ||
+	     (p[0] >= L'A' && p[0] <= L'Z')) &&
+		 p[1] == L':') {
+		if (p[2] == L'\0') {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Path is a drive name");
+			return (ARCHIVE_FAILED);
+		}
+		if (p[2] == L'\\')
+			p += 2;
+	}
+
+	top = dest = src = p;
+	/* Rewrite the path name if its character is a unusable. */
+	for (; *p != L'\0'; p++) {
+		if (*p == L':' || *p == L'*' || *p == L'?' || *p == L'"' ||
+		    *p == L'<' || *p == L'>' || *p == L'|')
+			*p = L'_';
+	}
+	/* Skip leading '\'. */
+	if (*src == L'\\')
+		separator = *src++;
+
+	/* Scan the pathname one element at a time. */
+	for (;;) {
+		/* src points to first char after '\' */
+		if (src[0] == L'\0') {
+			break;
+		} else if (src[0] == L'\\') {
+			/* Found '\\'('//'), ignore second one. */
+			src++;
+			continue;
+		} else if (src[0] == L'.') {
+			if (src[1] == L'\0') {
+				/* Ignore trailing '.' */
+				break;
+			} else if (src[1] == L'\\') {
+				/* Skip '.\'. */
+				src += 2;
+				continue;
+			} else if (src[1] == L'.') {
+				if (src[2] == L'\\' || src[2] == L'\0') {
+					/* Conditionally warn about '..' */
+					if (a->flags &
+					    ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
+						archive_set_error(&a->archive,
+						    ARCHIVE_ERRNO_MISC,
+						    "Path contains '..'");
+						return (ARCHIVE_FAILED);
+					}
+				}
+				/*
+				 * Note: Under no circumstances do we
+				 * remove '..' elements.  In
+				 * particular, restoring
+				 * '\foo\..\bar\' should create the
+				 * 'foo' dir as a side-effect.
+				 */
+			}
+		}
+
+		/* Copy current element, including leading '\'. */
+		if (separator)
+			*dest++ = L'\\';
+		while (*src != L'\0' && *src != L'\\') {
+			*dest++ = *src++;
+		}
+
+		if (*src == L'\0')
+			break;
+
+		/* Skip '\' separator. */
+		separator = *src++;
+	}
+	/*
+	 * We've just copied zero or more path elements, not including the
+	 * final '\'.
+	 */
+	if (dest == top) {
+		/*
+		 * Nothing got copied.  The path must have been something
+		 * like '.' or '\' or './' or '/././././/./'.
+		 */
+		if (separator)
+			*dest++ = L'\\';
+		else
+			*dest++ = L'.';
+	}
+	/* Terminate the result. */
+	*dest = L'\0';
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Create the parent directory of the specified path, assuming path
+ * is already in mutable storage.
+ */
+static int
+create_parent_dir(struct archive_write_disk *a, wchar_t *path)
+{
+	wchar_t *slash;
+	int r;
+
+	/* Remove tail element to obtain parent name. */
+	slash = wcsrchr(path, L'\\');
+	if (slash == NULL)
+		return (ARCHIVE_OK);
+	*slash = L'\0';
+	r = create_dir(a, path);
+	*slash = L'\\';
+	return (r);
+}
+
+/*
+ * Create the specified dir, recursing to create parents as necessary.
+ *
+ * Returns ARCHIVE_OK if the path exists when we're done here.
+ * Otherwise, returns ARCHIVE_FAILED.
+ * Assumes path is in mutable storage; path is unchanged on exit.
+ */
+static int
+create_dir(struct archive_write_disk *a, wchar_t *path)
+{
+	BY_HANDLE_FILE_INFORMATION st;
+	struct fixup_entry *le;
+	wchar_t *slash, *base, *full;
+	mode_t mode_final, mode, st_mode;
+	int r;
+
+	/* Check for special names and just skip them. */
+	slash = wcsrchr(path, L'\\');
+	if (slash == NULL)
+		base = path;
+	else
+		base = slash + 1;
+
+	if (base[0] == L'\0' ||
+	    (base[0] == L'.' && base[1] == L'\0') ||
+	    (base[0] == L'.' && base[1] == L'.' && base[2] == L'\0')) {
+		/* Don't bother trying to create null path, '.', or '..'. */
+		if (slash != NULL) {
+			*slash = L'\0';
+			r = create_dir(a, path);
+			*slash = L'\\';
+			return (r);
+		}
+		return (ARCHIVE_OK);
+	}
+
+	/*
+	 * Yes, this should be stat() and not lstat().  Using lstat()
+	 * here loses the ability to extract through symlinks.  Also note
+	 * that this should not use the a->st cache.
+	 */
+	if (file_information(a, path, &st, &st_mode, 0) == 0) {
+		if (S_ISDIR(st_mode))
+			return (ARCHIVE_OK);
+		if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+			archive_set_error(&a->archive, EEXIST,
+			    "Can't create directory '%ls'", path);
+			return (ARCHIVE_FAILED);
+		}
+		if (disk_unlink(path) != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Can't create directory '%ls': "
+			    "Conflicting file cannot be removed",
+			    path);
+			return (ARCHIVE_FAILED);
+		}
+	} else if (errno != ENOENT && errno != ENOTDIR) {
+		/* Stat failed? */
+		archive_set_error(&a->archive, errno,
+		    "Can't test directory '%ls'", path);
+		return (ARCHIVE_FAILED);
+	} else if (slash != NULL) {
+		*slash = '\0';
+		r = create_dir(a, path);
+		*slash = '\\';
+		if (r != ARCHIVE_OK)
+			return (r);
+	}
+
+	/*
+	 * Mode we want for the final restored directory.  Per POSIX,
+	 * implicitly-created dirs must be created obeying the umask.
+	 * There's no mention whether this is different for privileged
+	 * restores (which the rest of this code handles by pretending
+	 * umask=0).  I've chosen here to always obey the user's umask for
+	 * implicit dirs, even if _EXTRACT_PERM was specified.
+	 */
+	mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
+	/* Mode we want on disk during the restore process. */
+	mode = mode_final;
+	mode |= MINIMUM_DIR_MODE;
+	mode &= MAXIMUM_DIR_MODE;
+	/*
+	 * Apply __la_win_permissive_name_w to path in order to
+	 * remove '../' path string.
+	 */
+	full = __la_win_permissive_name_w(path);
+	if (full == NULL)
+		errno = EINVAL;
+	else if (CreateDirectoryW(full, NULL) != 0) {
+		if (mode != mode_final) {
+			le = new_fixup(a, path);
+			le->fixup |=TODO_MODE_BASE;
+			le->mode = mode_final;
+		}
+		free(full);
+		return (ARCHIVE_OK);
+	} else {
+		la_dosmaperr(GetLastError());
+	}
+	free(full);
+
+	/*
+	 * Without the following check, a/b/../b/c/d fails at the
+	 * second visit to 'b', so 'd' can't be created.  Note that we
+	 * don't add it to the fixup list here, as it's already been
+	 * added.
+	 */
+	if (file_information(a, path, &st, &st_mode, 0) == 0 &&
+	    S_ISDIR(st_mode))
+		return (ARCHIVE_OK);
+
+	archive_set_error(&a->archive, errno, "Failed to create dir '%ls'",
+	    path);
+	return (ARCHIVE_FAILED);
+}
+
+/*
+ * Note: Although we can skip setting the user id if the desired user
+ * id matches the current user, we cannot skip setting the group, as
+ * many systems set the gid based on the containing directory.  So
+ * we have to perform a chown syscall if we want to set the SGID
+ * bit.  (The alternative is to stat() and then possibly chown(); it's
+ * more efficient to skip the stat() and just always chown().)  Note
+ * that a successful chown() here clears the TODO_SGID_CHECK bit, which
+ * allows set_mode to skip the stat() check for the GID.
+ */
+static int
+set_ownership(struct archive_write_disk *a)
+{
+/* unfortunately, on win32 there is no 'root' user with uid 0,
+   so we just have to try the chown and see if it works */
+
+	/* If we know we can't change it, don't bother trying. */
+	if (a->user_uid != 0  &&  a->user_uid != a->uid) {
+		archive_set_error(&a->archive, errno,
+		    "Can't set UID=%jd", (intmax_t)a->uid);
+		return (ARCHIVE_WARN);
+	}
+
+	archive_set_error(&a->archive, errno,
+	    "Can't set user=%jd/group=%jd for %ls",
+	    (intmax_t)a->uid, (intmax_t)a->gid, a->name);
+	return (ARCHIVE_WARN);
+}
+
+static int
+set_times(struct archive_write_disk *a,
+    HANDLE h, int mode, const wchar_t *name,
+    time_t atime, long atime_nanos,
+    time_t birthtime, long birthtime_nanos,
+    time_t mtime, long mtime_nanos,
+    time_t ctime_sec, long ctime_nanos)
+{
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
+	 + (((nsec)/1000)*10))
+
+	HANDLE hw = 0;
+	ULARGE_INTEGER wintm;
+	FILETIME *pfbtime;
+	FILETIME fatime, fbtime, fmtime;
+
+	(void)ctime_sec; /* UNUSED */
+	(void)ctime_nanos; /* UNUSED */
+
+	if (h != INVALID_HANDLE_VALUE) {
+		hw = NULL;
+	} else {
+		wchar_t *ws;
+
+		if (S_ISLNK(mode))
+			return (ARCHIVE_OK);
+		ws = __la_win_permissive_name_w(name);
+		if (ws == NULL)
+			goto settimes_failed;
+		hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
+		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+		free(ws);
+		if (hw == INVALID_HANDLE_VALUE)
+			goto settimes_failed;
+		h = hw;
+	}
+
+	wintm.QuadPart = WINTIME(atime, atime_nanos);
+	fatime.dwLowDateTime = wintm.LowPart;
+	fatime.dwHighDateTime = wintm.HighPart;
+	wintm.QuadPart = WINTIME(mtime, mtime_nanos);
+	fmtime.dwLowDateTime = wintm.LowPart;
+	fmtime.dwHighDateTime = wintm.HighPart;
+	/*
+	 * SetFileTime() supports birthtime.
+	 */
+	if (birthtime > 0 || birthtime_nanos > 0) {
+		wintm.QuadPart = WINTIME(birthtime, birthtime_nanos);
+		fbtime.dwLowDateTime = wintm.LowPart;
+		fbtime.dwHighDateTime = wintm.HighPart;
+		pfbtime = &fbtime;
+	} else
+		pfbtime = NULL;
+	if (SetFileTime(h, pfbtime, &fatime, &fmtime) == 0)
+		goto settimes_failed;
+	CloseHandle(hw);
+	return (ARCHIVE_OK);
+
+settimes_failed:
+	CloseHandle(hw);
+	archive_set_error(&a->archive, EINVAL, "Can't restore time");
+	return (ARCHIVE_WARN);
+}
+
+static int
+set_times_from_entry(struct archive_write_disk *a)
+{
+	time_t atime, birthtime, mtime, ctime_sec;
+	long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
+
+	/* Suitable defaults. */
+	atime = birthtime = mtime = ctime_sec = a->start_time;
+	atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
+
+	/* If no time was provided, we're done. */
+	if (!archive_entry_atime_is_set(a->entry)
+	    && !archive_entry_birthtime_is_set(a->entry)
+	    && !archive_entry_mtime_is_set(a->entry))
+		return (ARCHIVE_OK);
+
+	if (archive_entry_atime_is_set(a->entry)) {
+		atime = archive_entry_atime(a->entry);
+		atime_nsec = archive_entry_atime_nsec(a->entry);
+	}
+	if (archive_entry_birthtime_is_set(a->entry)) {
+		birthtime = archive_entry_birthtime(a->entry);
+		birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
+	}
+	if (archive_entry_mtime_is_set(a->entry)) {
+		mtime = archive_entry_mtime(a->entry);
+		mtime_nsec = archive_entry_mtime_nsec(a->entry);
+	}
+	if (archive_entry_ctime_is_set(a->entry)) {
+		ctime_sec = archive_entry_ctime(a->entry);
+		ctime_nsec = archive_entry_ctime_nsec(a->entry);
+	}
+
+	return set_times(a, a->fh, a->mode, a->name,
+			 atime, atime_nsec,
+			 birthtime, birthtime_nsec,
+			 mtime, mtime_nsec,
+			 ctime_sec, ctime_nsec);
+}
+
+static int
+set_mode(struct archive_write_disk *a, int mode)
+{
+	int r = ARCHIVE_OK;
+	mode &= 07777; /* Strip off file type bits. */
+
+	if (a->todo & TODO_SGID_CHECK) {
+		/*
+		 * If we don't know the GID is right, we must stat()
+		 * to verify it.  We can't just check the GID of this
+		 * process, since systems sometimes set GID from
+		 * the enclosing dir or based on ACLs.
+		 */
+		if ((r = lazy_stat(a)) != ARCHIVE_OK)
+			return (r);
+		if (0 != a->gid) {
+			mode &= ~ S_ISGID;
+		}
+		/* While we're here, double-check the UID. */
+		if (0 != a->uid
+		    && (a->todo & TODO_SUID)) {
+			mode &= ~ S_ISUID;
+		}
+		a->todo &= ~TODO_SGID_CHECK;
+		a->todo &= ~TODO_SUID_CHECK;
+	} else if (a->todo & TODO_SUID_CHECK) {
+		/*
+		 * If we don't know the UID is right, we can just check
+		 * the user, since all systems set the file UID from
+		 * the process UID.
+		 */
+		if (a->user_uid != a->uid) {
+			mode &= ~ S_ISUID;
+		}
+		a->todo &= ~TODO_SUID_CHECK;
+	}
+
+	if (S_ISLNK(a->mode)) {
+#ifdef HAVE_LCHMOD
+		/*
+		 * If this is a symlink, use lchmod().  If the
+		 * platform doesn't support lchmod(), just skip it.  A
+		 * platform that doesn't provide a way to set
+		 * permissions on symlinks probably ignores
+		 * permissions on symlinks, so a failure here has no
+		 * impact.
+		 */
+		if (lchmod(a->name, mode) != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Can't set permissions to 0%o", (int)mode);
+			r = ARCHIVE_WARN;
+		}
+#endif
+	} else if (!S_ISDIR(a->mode)) {
+		/*
+		 * If it's not a symlink and not a dir, then use
+		 * fchmod() or chmod(), depending on whether we have
+		 * an fd.  Dirs get their perms set during the
+		 * post-extract fixup, which is handled elsewhere.
+		 */
+#ifdef HAVE_FCHMOD
+		if (a->fd >= 0) {
+			if (fchmod(a->fd, mode) != 0) {
+				archive_set_error(&a->archive, errno,
+				    "Can't set permissions to 0%o", (int)mode);
+				r = ARCHIVE_WARN;
+			}
+		} else
+#endif
+			/* If this platform lacks fchmod(), then
+			 * we'll just use chmod(). */
+			if (la_chmod(a->name, mode) != 0) {
+				archive_set_error(&a->archive, errno,
+				    "Can't set permissions to 0%o", (int)mode);
+				r = ARCHIVE_WARN;
+			}
+	}
+	return (r);
+}
+
+static int
+set_fflags(struct archive_write_disk *a)
+{
+	(void)a; /* UNUSED */
+	return (ARCHIVE_OK);
+}
+
+/* Default empty function body to satisfy mainline code. */
+static int
+set_acls(struct archive_write_disk *a, HANDLE h, const wchar_t *name,
+	 struct archive_acl *acl)
+{
+	(void)a; /* UNUSED */
+	(void)h; /* UNUSED */
+	(void)name; /* UNUSED */
+	(void)acl; /* UNUSED */
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Restore extended attributes - stub implementation for unsupported systems
+ */
+static int
+set_xattrs(struct archive_write_disk *a)
+{
+	static int warning_done = 0;
+
+	/* If there aren't any extended attributes, then it's okay not
+	 * to extract them, otherwise, issue a single warning. */
+	if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
+		warning_done = 1;
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Cannot restore extended attributes on this system");
+		return (ARCHIVE_WARN);
+	}
+	/* Warning was already emitted; suppress further warnings. */
+	return (ARCHIVE_OK);
+}
+
+static void
+fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
+{
+	ULARGE_INTEGER utc;
+
+	utc.HighPart = filetime->dwHighDateTime;
+	utc.LowPart  = filetime->dwLowDateTime;
+	if (utc.QuadPart >= EPOC_TIME) {
+		utc.QuadPart -= EPOC_TIME;
+		/* milli seconds base */
+		*t = (time_t)(utc.QuadPart / 10000000);
+		/* nano seconds base */
+		*ns = (long)(utc.QuadPart % 10000000) * 100;
+	} else {
+		*t = 0;
+		*ns = 0;
+	}
+}
+/*
+ * Test if file on disk is older than entry.
+ */
+static int
+older(BY_HANDLE_FILE_INFORMATION *st, struct archive_entry *entry)
+{
+	time_t sec;
+	long nsec;
+
+	fileTimeToUtc(&st->ftLastWriteTime, &sec, &nsec);
+	/* First, test the seconds and return if we have a definite answer. */
+	/* Definitely older. */
+	if (sec < archive_entry_mtime(entry))
+		return (1);
+	/* Definitely younger. */
+	if (sec > archive_entry_mtime(entry))
+		return (0);
+	if (nsec < archive_entry_mtime_nsec(entry))
+		return (1);
+	/* Same age or newer, so not older. */
+	return (0);
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
+
diff --git a/libarchive/config_freebsd.h b/libarchive/config_freebsd.h
new file mode 100644
index 000000000000..d61c4167b3b9
--- /dev/null
+++ b/libarchive/config_freebsd.h
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* FreeBSD 5.0 and later have ACL and extattr support. */
+#if __FreeBSD__ > 4
+#define	HAVE_ACL_CREATE_ENTRY 1
+#define	HAVE_ACL_GET_LINK_NP 1
+#define	HAVE_ACL_GET_PERM_NP 1
+#define	HAVE_ACL_INIT 1
+#define	HAVE_ACL_SET_FD 1
+#define	HAVE_ACL_SET_FD_NP 1
+#define	HAVE_ACL_SET_FILE 1
+#define	HAVE_ACL_USER 1
+#define	HAVE_EXTATTR_GET_FILE 1
+#define	HAVE_EXTATTR_LIST_FILE 1
+#define	HAVE_EXTATTR_SET_FD 1
+#define	HAVE_EXTATTR_SET_FILE 1
+#define	HAVE_SYS_ACL_H 1
+#define	HAVE_SYS_EXTATTR_H 1
+#endif
+
+#ifdef WITH_OPENSSL
+#define	HAVE_OPENSSL_MD5_H 1
+#define	HAVE_OPENSSL_RIPEMD_H 1
+#define	HAVE_OPENSSL_SHA_H 1
+#define	HAVE_SHA384 1
+#define	HAVE_SHA512 1
+#endif
+
+#define	HAVE_BSDXML_H 1
+#define	HAVE_BZLIB_H 1
+#define	HAVE_CHFLAGS 1
+#define	HAVE_CHOWN 1
+#define	HAVE_DECL_INT64_MAX 1
+#define	HAVE_DECL_INT64_MIN 1
+#define	HAVE_DECL_SIZE_MAX 1
+#define	HAVE_DECL_SSIZE_MAX 1
+#define	HAVE_DECL_STRERROR_R 1
+#define	HAVE_DECL_UINT32_MAX 1
+#define	HAVE_DECL_UINT64_MAX 1
+#define	HAVE_DIRENT_H 1
+#define	HAVE_EFTYPE 1
+#define	HAVE_EILSEQ 1
+#define	HAVE_ERRNO_H 1
+#define	HAVE_FCHDIR 1
+#define	HAVE_FCHFLAGS 1
+#define	HAVE_FCHMOD 1
+#define	HAVE_FCHOWN 1
+#define	HAVE_FCNTL 1
+#define	HAVE_FCNTL_H 1
+#define	HAVE_FSEEKO 1
+#define	HAVE_FSTAT 1
+#define	HAVE_FTRUNCATE 1
+#define	HAVE_FUTIMES 1
+#define	HAVE_GETEUID 1
+#define	HAVE_GETGRGID_R 1
+#define	HAVE_GETPID 1
+#define	HAVE_GETPWUID_R 1
+#define	HAVE_GRP_H 1
+#define	HAVE_INTTYPES_H 1
+#define	HAVE_LCHFLAGS 1
+#define	HAVE_LCHMOD 1
+#define	HAVE_LCHOWN 1
+#define	HAVE_LIMITS_H 1
+#define	HAVE_LINK 1
+#define	HAVE_LSTAT 1
+#define	HAVE_LUTIMES 1
+#define	HAVE_MALLOC 1
+#define	HAVE_MD5 1
+#define	HAVE_MD5_H 1
+#define	HAVE_MEMMOVE 1
+#define	HAVE_MKDIR 1
+#define	HAVE_MKFIFO 1
+#define	HAVE_MKNOD 1
+#define	HAVE_PIPE 1
+#define	HAVE_POLL 1
+#define	HAVE_POLL_H 1
+#define	HAVE_PWD_H 1
+#define	HAVE_READLINK 1
+#define	HAVE_RMD160 1
+#define	HAVE_SELECT 1
+#define	HAVE_SETENV 1
+#define	HAVE_SHA_H 1
+#define	HAVE_SHA1 1
+#define	HAVE_SHA256 1
+#define	HAVE_SHA256_H 1
+#define	HAVE_SIGNAL_H 1
+#define	HAVE_STDINT_H 1
+#define	HAVE_STDLIB_H 1
+#define	HAVE_STRCHR 1
+#define	HAVE_STRDUP 1
+#define	HAVE_STRERROR 1
+#define	HAVE_STRERROR_R 1
+#define	HAVE_STRINGS_H 1
+#define	HAVE_STRING_H 1
+#define	HAVE_STRRCHR 1
+#define	HAVE_STRUCT_STAT_ST_BLKSIZE 1
+#define	HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+#define	HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
+#define	HAVE_STRUCT_STAT_ST_FLAGS 1
+#define	HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+#define	HAVE_STRUCT_TM_TM_GMTOFF 1
+#define	HAVE_SYMLINK 1
+#define	HAVE_SYS_CDEFS_H 1
+#define	HAVE_SYS_IOCTL_H 1
+#define	HAVE_SYS_MOUNT_H 1
+#define	HAVE_SYS_PARAM_H 1
+#define	HAVE_SYS_SELECT_H 1
+#define	HAVE_SYS_STAT_H 1
+#define	HAVE_SYS_TIME_H 1
+#define	HAVE_SYS_TYPES_H 1
+#undef	HAVE_SYS_UTIME_H
+#define	HAVE_SYS_UTSNAME_H 1
+#define	HAVE_SYS_WAIT_H 1
+#define	HAVE_TIMEGM 1
+#define	HAVE_TZSET 1
+#define	HAVE_UNISTD_H 1
+#define	HAVE_UNSETENV 1
+#define	HAVE_UTIME 1
+#define	HAVE_UTIMES 1
+#define	HAVE_UTIME_H 1
+#define	HAVE_VFORK 1
+#define	HAVE_WCHAR_H 1
+#define	HAVE_WCSCPY 1
+#define	HAVE_WCSLEN 1
+#define	HAVE_WCTOMB 1
+#define	HAVE_WMEMCMP 1
+#define	HAVE_WMEMCPY 1
+#define	HAVE_ZLIB_H 1
+#define	TIME_WITH_SYS_TIME 1
+
+/* FreeBSD 4 and earlier lack intmax_t/uintmax_t */
+#if __FreeBSD__ < 5
+#define	intmax_t int64_t
+#define	uintmax_t uint64_t
+#endif
diff --git a/libarchive/filter_fork_windows.c b/libarchive/filter_fork_windows.c
new file mode 100644
index 000000000000..fa59cc9e90ce
--- /dev/null
+++ b/libarchive/filter_fork_windows.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2009-2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include "archive_cmdline_private.h"
+#include "archive_string.h"
+
+#include "filter_fork.h"
+
+pid_t
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
+{
+	HANDLE childStdout[2], childStdin[2],childStderr;
+	SECURITY_ATTRIBUTES secAtts;
+	STARTUPINFO staInfo;
+	PROCESS_INFORMATION childInfo;
+	struct archive_string cmdline;
+	struct archive_string fullpath;
+	struct archive_cmdline *acmd;
+	char *arg0, *ext;
+	int i, l;
+	DWORD fl, fl_old;
+
+	childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE;
+	childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE;
+	childStderr = INVALID_HANDLE_VALUE;
+	archive_string_init(&cmdline);
+	archive_string_init(&fullpath);
+
+	acmd = __archive_cmdline_allocate();
+	if (acmd == NULL)
+		goto fail;
+	if (__archive_cmdline_parse(acmd, cmd) != ARCHIVE_OK)
+		goto fail;
+
+	/*
+	 * Search the full path of 'path'.
+	 * NOTE: This does not need if we give CreateProcessA 'path' as
+	 * a part of the cmdline and give CreateProcessA NULL as first
+	 * parameter, but I do not like that way.
+	 */
+	ext = strrchr(acmd->path, '.');
+	if (ext == NULL || strlen(ext) > 4)
+		/* 'path' does not have a proper extension, so we have to
+		 * give SearchPath() ".exe" as the extension. */
+		ext = ".exe";
+	else
+		ext = NULL;/* 'path' has an extension. */
+
+	fl = MAX_PATH;
+	do {
+		if (archive_string_ensure(&fullpath, fl) == NULL)
+			goto fail;
+		fl_old = fl;
+		fl = SearchPathA(NULL, acmd->path, ext, fl, fullpath.s,
+			&arg0);
+	} while (fl != 0 && fl > fl_old);
+	if (fl == 0)
+		goto fail;
+
+	/*
+	 * Make a command line.
+	 */
+	for (l = 0, i = 0;  acmd->argv[i] != NULL; i++) {
+		if (i == 0)
+			continue;
+		l += (int)strlen(acmd->argv[i]) + 1;
+	}
+	if (archive_string_ensure(&cmdline, l + 1) == NULL)
+		goto fail;
+	for (i = 0;  acmd->argv[i] != NULL; i++) {
+		if (i == 0) {
+			const char *p, *sp;
+
+			if ((p = strchr(acmd->argv[i], '/')) != NULL ||
+			    (p = strchr(acmd->argv[i], '\\')) != NULL)
+				p++;
+			else
+				p = acmd->argv[i];
+			if ((sp = strchr(p, ' ')) != NULL)
+				archive_strappend_char(&cmdline, '"');
+			archive_strcat(&cmdline, p);
+			if (sp != NULL)
+				archive_strappend_char(&cmdline, '"');
+		} else {
+			archive_strappend_char(&cmdline, ' ');
+			archive_strcat(&cmdline, acmd->argv[i]);
+		}
+	}
+	if (i <= 1) {
+		const char *sp;
+
+		if ((sp = strchr(arg0, ' ')) != NULL)
+			archive_strappend_char(&cmdline, '"');
+		archive_strcat(&cmdline, arg0);
+		if (sp != NULL)
+			archive_strappend_char(&cmdline, '"');
+	}
+
+	secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
+	secAtts.bInheritHandle = TRUE;
+	secAtts.lpSecurityDescriptor = NULL;
+	if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
+		goto fail;
+	if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
+		goto fail;
+	if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0)
+		goto fail;
+	if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
+		goto fail;
+	if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
+	    GetCurrentProcess(), &childStderr, 0, TRUE,
+	    DUPLICATE_SAME_ACCESS) == 0)
+		goto fail;
+
+	memset(&staInfo, 0, sizeof(staInfo));
+	staInfo.cb = sizeof(staInfo);
+	staInfo.hStdError = childStderr;
+	staInfo.hStdOutput = childStdout[1];
+	staInfo.hStdInput = childStdin[0];
+	staInfo.wShowWindow = SW_HIDE;
+	staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+	if (CreateProcessA(fullpath.s, cmdline.s, NULL, NULL, TRUE, 0,
+	      NULL, NULL, &staInfo, &childInfo) == 0)
+		goto fail;
+	WaitForInputIdle(childInfo.hProcess, INFINITE);
+	CloseHandle(childInfo.hProcess);
+	CloseHandle(childInfo.hThread);
+
+	*child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
+	*child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
+	
+	CloseHandle(childStdout[1]);
+	CloseHandle(childStdin[0]);
+
+	archive_string_free(&cmdline);
+	archive_string_free(&fullpath);
+	__archive_cmdline_free(acmd);
+	return (childInfo.dwProcessId);
+
+fail:
+	if (childStdout[0] != INVALID_HANDLE_VALUE)
+		CloseHandle(childStdout[0]);
+	if (childStdout[1] != INVALID_HANDLE_VALUE)
+		CloseHandle(childStdout[1]);
+	if (childStdin[0] != INVALID_HANDLE_VALUE)
+		CloseHandle(childStdin[0]);
+	if (childStdin[1] != INVALID_HANDLE_VALUE)
+		CloseHandle(childStdin[1]);
+	if (childStderr != INVALID_HANDLE_VALUE)
+		CloseHandle(childStderr);
+	archive_string_free(&cmdline);
+	archive_string_free(&fullpath);
+	__archive_cmdline_free(acmd);
+	return (-1);
+}
+
+void
+__archive_check_child(int in, int out)
+{
+	(void)in; /* UNUSED */
+	(void)out; /* UNUSED */
+	Sleep(100);
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/libarchive/mtree.5 b/libarchive/mtree.5
new file mode 100644
index 000000000000..983fff723891
--- /dev/null
+++ b/libarchive/mtree.5
@@ -0,0 +1,269 @@
+.\" Copyright (c) 1989, 1990, 1993
+.\"     The Regents of the University of California.  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.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     From: @(#)mtree.8       8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd May 6, 2008
+.Dt MTREE 5
+.Os
+.Sh NAME
+.Nm mtree
+.Nd format of mtree dir hierarchy files
+.Sh DESCRIPTION
+The
+.Nm
+format is a textual format that describes a collection of filesystem objects.
+Such files are typically used to create or verify directory hierarchies.
+.Ss General Format
+An
+.Nm
+file consists of a series of lines, each providing information
+about a single filesystem object.
+Leading whitespace is always ignored.
+.Pp
+When encoding file or pathnames, any backslash character or
+character outside of the 95 printable ASCII characters must be
+encoded as a a backslash followed by three
+octal digits.
+When reading mtree files, any appearance of a backslash
+followed by three octal digits should be converted into the
+corresponding character.
+.Pp
+Each line is interpreted independently as one of the following types:
+.Bl -tag -width Cm
+.It Signature
+The first line of any mtree file must begin with
+.Dq #mtree .
+If a file contains any full path entries, the first line should
+begin with
+.Dq #mtree v2.0 ,
+otherwise, the first line should begin with
+.Dq #mtree v1.0 .
+.It Blank
+Blank lines are ignored.
+.It Comment
+Lines beginning with
+.Cm #
+are ignored.
+.It Special
+Lines beginning with
+.Cm /
+are special commands that influence
+the interpretation of later lines.
+.It Relative
+If the first whitespace-delimited word has no
+.Cm /
+characters,
+it is the name of a file in the current directory.
+Any relative entry that describes a directory changes the
+current directory.
+.It dot-dot
+As a special case, a relative entry with the filename
+.Pa ..
+changes the current directory to the parent directory.
+Options on dot-dot entries are always ignored.
+.It Full
+If the first whitespace-delimited word has a
+.Cm /
+character after
+the first character, it is the pathname of a file relative to the
+starting directory.
+There can be multiple full entries describing the same file.
+.El
+.Pp
+Some tools that process
+.Nm
+files may require that multiple lines describing the same file
+occur consecutively.
+It is not permitted for the same file to be mentioned using
+both a relative and a full file specification.
+.Ss Special commands
+Two special commands are currently defined:
+.Bl -tag -width Cm
+.It Cm /set
+This command defines default values for one or more keywords.
+It is followed on the same line by one or more whitespace-separated
+keyword definitions.
+These definitions apply to all following files that do not specify
+a value for that keyword.
+.It Cm /unset
+This command removes any default value set by a previous
+.Cm /set
+command.
+It is followed on the same line by one or more keywords
+separated by whitespace.
+.El
+.Ss Keywords
+After the filename, a full or relative entry consists of zero
+or more whitespace-separated keyword definitions.
+Each such definition consists of a key from the following
+list immediately followed by an '=' sign
+and a value.
+Software programs reading mtree files should warn about
+unrecognized keywords.
+.Pp
+Currently supported keywords are as follows:
+.Bl -tag -width Cm
+.It Cm cksum
+The checksum of the file using the default algorithm specified by
+the
+.Xr cksum 1
+utility.
+.It Cm contents
+The full pathname of a file that holds the contents of this file.
+.It Cm flags
+The file flags as a symbolic name.
+See
+.Xr chflags 1
+for information on these names.
+If no flags are to be set the string
+.Dq none
+may be used to override the current default.
+.It Cm gid
+The file group as a numeric value.
+.It Cm gname
+The file group as a symbolic name.
+.It Cm ignore
+Ignore any file hierarchy below this file.
+.It Cm link
+The target of the symbolic link when type=link.
+.It Cm md5
+The MD5 message digest of the file.
+.It Cm md5digest
+A synonym for
+.Cm md5 .
+.It Cm mode
+The current file's permissions as a numeric (octal) or symbolic
+value.
+.It Cm nlink
+The number of hard links the file is expected to have.
+.It Cm nochange
+Make sure this file or directory exists but otherwise ignore all attributes.
+.It Cm ripemd160digest
+The
+.Tn RIPEMD160
+message digest of the file.
+.It Cm rmd160
+A synonym for
+.Cm ripemd160digest .
+.It Cm rmd160digest
+A synonym for
+.Cm ripemd160digest .
+.It Cm sha1
+The
+.Tn FIPS
+160-1
+.Pq Dq Tn SHA-1
+message digest of the file.
+.It Cm sha1digest
+A synonym for
+.Cm sha1 .
+.It Cm sha256
+The
+.Tn FIPS
+180-2
+.Pq Dq Tn SHA-256
+message digest of the file.
+.It Cm sha256digest
+A synonym for
+.Cm sha256 .
+.It Cm size
+The size, in bytes, of the file.
+.It Cm time
+The last modification time of the file.
+.It Cm type
+The type of the file; may be set to any one of the following:
+.Pp
+.Bl -tag -width Cm -compact
+.It Cm block
+block special device
+.It Cm char
+character special device
+.It Cm dir
+directory
+.It Cm fifo
+fifo
+.It Cm file
+regular file
+.It Cm link
+symbolic link
+.It Cm socket
+socket
+.El
+.It Cm uid
+The file owner as a numeric value.
+.It Cm uname
+The file owner as a symbolic name.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr find 1 ,
+.Xr mtree 8
+.Sh BUGS
+The
+.Fx
+implementation of mtree does not currently support
+the
+.Nm
+2.0
+format.
+The requirement for a
+.Dq #mtree
+signature line is new and not yet widely implemented.
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Bx 4.3 Reno .
+The
+.Tn MD5
+digest capability was added in
+.Fx 2.1 ,
+in response to the widespread use of programs which can spoof
+.Xr cksum 1 .
+The
+.Tn SHA-1
+and
+.Tn RIPEMD160
+digests were added in
+.Fx 4.0 ,
+as new attacks have demonstrated weaknesses in
+.Tn MD5 .
+The
+.Tn SHA-256
+digest was added in
+.Fx 6.0 .
+Support for file flags was added in
+.Fx 4.0 ,
+and mostly comes from
+.Nx .
+The
+.Dq full
+entry format was added by
+.Nx .
diff --git a/libarchive/test/.cvsignore b/libarchive/test/.cvsignore
new file mode 100644
index 000000000000..b71f5a0dbd62
--- /dev/null
+++ b/libarchive/test/.cvsignore
@@ -0,0 +1,10 @@
+*.tar
+*.tar.gz
+*.tgz
+*.zip
+.depend
+.deps
+.dirstamp
+archive.h
+libarchive_test
+list.h
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
new file mode 100644
index 000000000000..d2eb2c2f39ef
--- /dev/null
+++ b/libarchive/test/CMakeLists.txt
@@ -0,0 +1,256 @@
+############################################
+#
+# How to build libarchive_test
+#
+############################################
+IF(ENABLE_TEST)
+  SET(libarchive_test_SOURCES
+    ../../test_utils/test_utils.c
+   main.c
+    read_open_memory.c
+    test.h
+    test_acl_freebsd_posix1e.c
+    test_acl_freebsd_nfs4.c
+    test_acl_nfs4.c
+    test_acl_pax.c
+    test_acl_posix1e.c
+    test_archive_api_feature.c
+    test_archive_clear_error.c
+    test_archive_cmdline.c
+    test_archive_crypto.c
+    test_archive_getdate.c
+    test_archive_match_owner.c
+    test_archive_match_path.c
+    test_archive_match_time.c
+    test_archive_pathmatch.c
+    test_archive_read_close_twice.c
+    test_archive_read_close_twice_open_fd.c
+    test_archive_read_close_twice_open_filename.c
+    test_archive_read_multiple_data_objects.c
+    test_archive_read_next_header_empty.c
+    test_archive_read_next_header_raw.c
+    test_archive_read_open2.c
+    test_archive_read_set_filter_option.c
+    test_archive_read_set_format_option.c
+    test_archive_read_set_option.c
+    test_archive_read_set_options.c
+    test_archive_read_support.c
+    test_archive_set_error.c
+    test_archive_string.c
+    test_archive_string_conversion.c
+    test_archive_write_add_filter_by_name.c
+    test_archive_write_set_filter_option.c
+    test_archive_write_set_format_by_name.c
+    test_archive_write_set_format_option.c
+    test_archive_write_set_option.c
+    test_archive_write_set_options.c
+    test_bad_fd.c
+    test_compat_bzip2.c
+    test_compat_cpio.c
+    test_compat_gtar.c
+    test_compat_gzip.c
+    test_compat_lzip.c
+    test_compat_lzma.c
+    test_compat_lzop.c
+    test_compat_mac.c
+    test_compat_pax_libarchive_2x.c
+    test_compat_solaris_tar_acl.c
+    test_compat_solaris_pax_sparse.c
+    test_compat_tar_hardlink.c
+    test_compat_uudecode.c
+    test_compat_xz.c
+    test_compat_zip.c
+    test_empty_write.c
+    test_entry.c
+    test_entry_strmode.c
+    test_extattr_freebsd.c
+    test_filter_count.c
+    test_fuzz.c
+    test_gnutar_filename_encoding.c
+    test_link_resolver.c
+    test_open_failure.c
+    test_open_fd.c
+    test_open_file.c
+    test_open_filename.c
+    test_pax_filename_encoding.c
+    test_read_data_large.c
+    test_read_disk.c
+    test_read_disk_directory_traversals.c
+    test_read_disk_entry_from_file.c
+    test_read_extract.c
+    test_read_file_nonexistent.c
+    test_read_filter_grzip.c
+    test_read_filter_lrzip.c
+    test_read_filter_lzop.c
+    test_read_filter_lzop_multiple_parts.c
+    test_read_filter_program.c
+    test_read_filter_program_signature.c
+    test_read_filter_uudecode.c
+    test_read_format_7zip.c
+    test_read_format_ar.c
+    test_read_format_cab.c
+    test_read_format_cab_filename.c
+    test_read_format_cpio_afio.c
+    test_read_format_cpio_bin.c
+    test_read_format_cpio_bin_Z.c
+    test_read_format_cpio_bin_be.c
+    test_read_format_cpio_bin_bz2.c
+    test_read_format_cpio_bin_gz.c
+    test_read_format_cpio_bin_lzip.c
+    test_read_format_cpio_bin_lzma.c
+    test_read_format_cpio_bin_xz.c
+    test_read_format_cpio_filename.c
+    test_read_format_cpio_odc.c
+    test_read_format_cpio_svr4_bzip2_rpm.c
+    test_read_format_cpio_svr4_gzip.c
+    test_read_format_cpio_svr4_gzip_rpm.c
+    test_read_format_cpio_svr4c_Z.c
+    test_read_format_empty.c
+    test_read_format_gtar_filename.c
+    test_read_format_gtar_gz.c
+    test_read_format_gtar_lzma.c
+    test_read_format_gtar_sparse.c
+    test_read_format_iso_Z.c
+    test_read_format_iso_multi_extent.c
+    test_read_format_iso_xorriso.c
+    test_read_format_isojoliet_bz2.c
+    test_read_format_isojoliet_long.c
+    test_read_format_isojoliet_rr.c
+    test_read_format_isojoliet_versioned.c
+    test_read_format_isorr_bz2.c
+    test_read_format_isorr_ce.c
+    test_read_format_isorr_new_bz2.c
+    test_read_format_isorr_rr_moved.c
+    test_read_format_isozisofs_bz2.c
+    test_read_format_lha.c
+    test_read_format_lha_filename.c
+    test_read_format_mtree.c
+    test_read_format_pax_bz2.c
+    test_read_format_rar.c
+    test_read_format_raw.c
+    test_read_format_tar.c
+    test_read_format_tar_empty_filename.c
+    test_read_format_tar_filename.c
+    test_read_format_tbz.c
+    test_read_format_tgz.c
+    test_read_format_tlz.c
+    test_read_format_txz.c
+    test_read_format_tz.c
+    test_read_format_ustar_filename.c
+    test_read_format_xar.c
+    test_read_format_zip.c
+    test_read_format_zip_comment_stored.c
+    test_read_format_zip_filename.c
+    test_read_format_zip_mac_metadata.c
+    test_read_format_zip_sfx.c
+    test_read_large.c
+    test_read_pax_truncated.c
+    test_read_position.c
+    test_read_set_format.c
+    test_read_truncated.c
+    test_read_truncated_filter.c
+    test_sparse_basic.c
+    test_tar_filenames.c
+    test_tar_large.c
+    test_ustar_filenames.c
+    test_ustar_filename_encoding.c
+    test_write_disk.c
+    test_write_disk_appledouble.c
+    test_write_disk_failures.c
+    test_write_disk_hardlink.c
+    test_write_disk_hfs_compression.c
+    test_write_disk_lookup.c
+    test_write_disk_mac_metadata.c
+    test_write_disk_no_hfs_compression.c
+    test_write_disk_perms.c
+    test_write_disk_secure.c
+    test_write_disk_sparse.c
+    test_write_disk_symlink.c
+    test_write_disk_times.c
+    test_write_filter_b64encode.c
+    test_write_filter_bzip2.c
+    test_write_filter_compress.c
+    test_write_filter_gzip.c
+    test_write_filter_gzip_timestamp.c
+    test_write_filter_lrzip.c
+    test_write_filter_lzip.c
+    test_write_filter_lzma.c
+    test_write_filter_lzop.c
+    test_write_filter_program.c
+    test_write_filter_uuencode.c
+    test_write_filter_xz.c
+    test_write_format_7zip.c
+    test_write_format_7zip_empty.c
+    test_write_format_7zip_large.c
+    test_write_format_ar.c
+    test_write_format_cpio.c
+    test_write_format_cpio_empty.c
+    test_write_format_cpio_newc.c
+    test_write_format_cpio_odc.c
+    test_write_format_gnutar.c
+    test_write_format_iso9660.c
+    test_write_format_iso9660_boot.c
+    test_write_format_iso9660_empty.c
+    test_write_format_iso9660_filename.c
+    test_write_format_iso9660_zisofs.c
+    test_write_format_mtree.c
+    test_write_format_mtree_absolute_path.c
+    test_write_format_mtree_classic.c
+    test_write_format_mtree_classic_indent.c
+    test_write_format_mtree_fflags.c
+    test_write_format_mtree_no_separator.c
+    test_write_format_mtree_quoted_filename.c
+    test_write_format_pax.c
+    test_write_format_shar_empty.c
+    test_write_format_tar.c
+    test_write_format_tar_empty.c
+    test_write_format_tar_sparse.c
+    test_write_format_tar_ustar.c
+    test_write_format_tar_v7tar.c
+    test_write_format_xar.c
+    test_write_format_xar_empty.c
+    test_write_format_zip.c
+    test_write_format_zip_empty.c
+    test_write_format_zip_no_compression.c
+    test_write_zip_set_compression_store.c
+    test_write_open_memory.c
+    test_zip_filename_encoding.c
+  )
+
+  #
+  # Register target
+  #
+  ADD_EXECUTABLE(libarchive_test ${libarchive_test_SOURCES})
+  TARGET_LINK_LIBRARIES(libarchive_test archive_static ${ADDITIONAL_LIBS})
+  SET_PROPERTY(TARGET libarchive_test PROPERTY COMPILE_DEFINITIONS
+    LIBARCHIVE_STATIC LIST_H)
+
+  #
+  # Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
+  #
+  GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
+    ${CMAKE_CURRENT_LIST_FILE} ${libarchive_test_SOURCES})
+  SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
+    ${CMAKE_CURRENT_BINARY_DIR})
+
+  # list.h has a line DEFINE_TEST(testname) for every
+  # test.  We can use that to define the tests for cmake by
+  # defining a DEFINE_TEST macro and reading list.h in.
+  MACRO (DEFINE_TEST _testname)
+    ADD_TEST(
+      NAME libarchive_${_testname}
+      COMMAND libarchive_test -vv
+                              -r ${CMAKE_CURRENT_SOURCE_DIR}
+                              ${_testname})
+  ENDMACRO (DEFINE_TEST _testname)
+
+  INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
+  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
+
+  # Experimental new test handling
+  ADD_CUSTOM_TARGET(run_libarchive_test
+	COMMAND	libarchive_test -r ${CMAKE_CURRENT_SOURCE_DIR})
+  ADD_DEPENDENCIES(run_all_tests run_libarchive_test)
+ENDIF(ENABLE_TEST)
+
diff --git a/tar/CMakeLists.txt b/tar/CMakeLists.txt
new file mode 100644
index 000000000000..46ce58b02e2e
--- /dev/null
+++ b/tar/CMakeLists.txt
@@ -0,0 +1,49 @@
+############################################
+#
+# How to build bsdtar
+#
+############################################
+IF(ENABLE_TAR)
+
+  SET(bsdtar_SOURCES
+    bsdtar.c
+    bsdtar.h
+    bsdtar_platform.h
+    cmdline.c
+    creation_set.c
+    read.c
+    subst.c
+    util.c
+    write.c
+    ../libarchive_fe/err.c
+    ../libarchive_fe/err.h
+    ../libarchive_fe/lafe_platform.h
+    ../libarchive_fe/line_reader.c
+    ../libarchive_fe/line_reader.h
+  )
+  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
+  IF(WIN32 AND NOT CYGWIN)
+    LIST(APPEND bsdtar_SOURCES bsdtar_windows.c)
+    LIST(APPEND bsdtar_SOURCES bsdtar_windows.h)
+  ENDIF(WIN32 AND NOT CYGWIN)
+
+  # bsdtar documentation
+  SET(bsdtar_MANS bsdtar.1)
+
+  # How to build bsdtar
+  ADD_EXECUTABLE(bsdtar ${bsdtar_SOURCES})
+  IF(ENABLE_TAR_SHARED)
+    TARGET_LINK_LIBRARIES(bsdtar archive ${ADDITIONAL_LIBS})
+  ELSE(ENABLE_TAR_SHARED)
+    TARGET_LINK_LIBRARIES(bsdtar archive_static ${ADDITIONAL_LIBS})
+    SET_TARGET_PROPERTIES(bsdtar PROPERTIES COMPILE_DEFINITIONS
+    				 LIBARCHIVE_STATIC)
+  ENDIF(ENABLE_TAR_SHARED)
+  GET_TARGET_PROPERTY(BSDTAR bsdtar LOCATION)
+
+  # Installation rules
+  INSTALL(TARGETS bsdtar RUNTIME DESTINATION bin)
+  INSTALL_MAN(${bsdtar_MANS})
+ENDIF(ENABLE_TAR)
+
+add_subdirectory(test)
diff --git a/tar/bsdtar_windows.c b/tar/bsdtar_windows.c
new file mode 100644
index 000000000000..41ce6eb78c8b
--- /dev/null
+++ b/tar/bsdtar_windows.c
@@ -0,0 +1,298 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include "bsdtar_platform.h"
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
+#include <stddef.h>
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#include <sys/stat.h>
+#include <process.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <windows.h>
+#include <sddl.h>
+
+#include "bsdtar.h"
+#include "err.h"
+
+/* This may actually not be needed anymore.
+ * TODO: Review the error handling for chdir() failures and
+ * simply dump this if it's not really needed. */
+static void __tar_dosmaperr(unsigned long);
+
+/*
+ * Prepend "\\?\" to the path name and convert it to unicode to permit
+ * an extended-length path for a maximum total path length of 32767
+ * characters.
+ * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ */
+static wchar_t *
+permissive_name(const char *name)
+{
+	wchar_t *wn, *wnp;
+	wchar_t *ws, *wsp;
+	DWORD l, len, slen, alloclen;
+	int unc;
+
+	len = (DWORD)strlen(name);
+	wn = malloc((len + 1) * sizeof(wchar_t));
+	if (wn == NULL)
+		return (NULL);
+	l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len);
+	if (l == 0) {
+		free(wn);
+		return (NULL);
+	}
+	wn[l] = L'\0';
+
+	/* Get a full path names */
+	l = GetFullPathNameW(wn, 0, NULL, NULL);
+	if (l == 0) {
+		free(wn);
+		return (NULL);
+	}
+	wnp = malloc(l * sizeof(wchar_t));
+	if (wnp == NULL) {
+		free(wn);
+		return (NULL);
+	}
+	len = GetFullPathNameW(wn, l, wnp, NULL);
+	free(wn);
+	wn = wnp;
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+	    wnp[2] == L'?' && wnp[3] == L'\\')
+		/* We have already permissive names. */
+		return (wn);
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+		wnp[2] == L'.' && wnp[3] == L'\\') {
+		/* Device names */
+		if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+		     (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+		    wnp[5] == L':' && wnp[6] == L'\\')
+			wnp[2] = L'?';/* Not device names. */
+		return (wn);
+	}
+
+	unc = 0;
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+		wchar_t *p = &wnp[2];
+
+		/* Skip server-name letters. */
+		while (*p != L'\\' && *p != L'\0')
+			++p;
+		if (*p == L'\\') {
+			wchar_t *rp = ++p;
+			/* Skip share-name letters. */
+			while (*p != L'\\' && *p != L'\0')
+				++p;
+			if (*p == L'\\' && p != rp) {
+				/* Now, match patterns such as
+				 * "\\server-name\share-name\" */
+				wnp += 2;
+				len -= 2;
+				unc = 1;
+			}
+		}
+	}
+
+	alloclen = slen = 4 + (unc * 4) + len + 1;
+	ws = wsp = malloc(slen * sizeof(wchar_t));
+	if (ws == NULL) {
+		free(wn);
+		return (NULL);
+	}
+	/* prepend "\\?\" */
+	wcsncpy(wsp, L"\\\\?\\", 4);
+	wsp += 4;
+	slen -= 4;
+	if (unc) {
+		/* append "UNC\" ---> "\\?\UNC\" */
+		wcsncpy(wsp, L"UNC\\", 4);
+		wsp += 4;
+		slen -= 4;
+	}
+	wcsncpy(wsp, wnp, slen);
+	free(wn);
+	ws[alloclen - 1] = L'\0';
+	return (ws);
+}
+
+int
+__tar_chdir(const char *path)
+{
+	wchar_t *ws;
+	int r;
+
+	r = SetCurrentDirectoryA(path);
+	if (r == 0) {
+		if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+			__tar_dosmaperr(GetLastError());
+			return (-1);
+		}
+	} else
+		return (0);
+	ws = permissive_name(path);
+	if (ws == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+	r = SetCurrentDirectoryW(ws);
+	free(ws);
+	if (r == 0) {
+		__tar_dosmaperr(GetLastError());
+		return (-1);
+	}
+	return (0);
+}
+
+/*
+ * The following function was modified from PostgreSQL sources and is
+ * subject to the copyright below.
+ */
+/*-------------------------------------------------------------------------
+ *
+ * win32error.c
+ *	  Map win32 error codes to errno values
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+static const struct {
+	DWORD		winerr;
+	int		doserr;
+} doserrors[] =
+{
+	{	ERROR_INVALID_FUNCTION, EINVAL	},
+	{	ERROR_FILE_NOT_FOUND, ENOENT	},
+	{	ERROR_PATH_NOT_FOUND, ENOENT	},
+	{	ERROR_TOO_MANY_OPEN_FILES, EMFILE	},
+	{	ERROR_ACCESS_DENIED, EACCES	},
+	{	ERROR_INVALID_HANDLE, EBADF	},
+	{	ERROR_ARENA_TRASHED, ENOMEM	},
+	{	ERROR_NOT_ENOUGH_MEMORY, ENOMEM	},
+	{	ERROR_INVALID_BLOCK, ENOMEM	},
+	{	ERROR_BAD_ENVIRONMENT, E2BIG	},
+	{	ERROR_BAD_FORMAT, ENOEXEC	},
+	{	ERROR_INVALID_ACCESS, EINVAL	},
+	{	ERROR_INVALID_DATA, EINVAL	},
+	{	ERROR_INVALID_DRIVE, ENOENT	},
+	{	ERROR_CURRENT_DIRECTORY, EACCES	},
+	{	ERROR_NOT_SAME_DEVICE, EXDEV	},
+	{	ERROR_NO_MORE_FILES, ENOENT	},
+	{	ERROR_LOCK_VIOLATION, EACCES	},
+	{	ERROR_SHARING_VIOLATION, EACCES	},
+	{	ERROR_BAD_NETPATH, ENOENT	},
+	{	ERROR_NETWORK_ACCESS_DENIED, EACCES	},
+	{	ERROR_BAD_NET_NAME, ENOENT	},
+	{	ERROR_FILE_EXISTS, EEXIST	},
+	{	ERROR_CANNOT_MAKE, EACCES	},
+	{	ERROR_FAIL_I24, EACCES	},
+	{	ERROR_INVALID_PARAMETER, EINVAL	},
+	{	ERROR_NO_PROC_SLOTS, EAGAIN	},
+	{	ERROR_DRIVE_LOCKED, EACCES	},
+	{	ERROR_BROKEN_PIPE, EPIPE	},
+	{	ERROR_DISK_FULL, ENOSPC	},
+	{	ERROR_INVALID_TARGET_HANDLE, EBADF	},
+	{	ERROR_INVALID_HANDLE, EINVAL	},
+	{	ERROR_WAIT_NO_CHILDREN, ECHILD	},
+	{	ERROR_CHILD_NOT_COMPLETE, ECHILD	},
+	{	ERROR_DIRECT_ACCESS_HANDLE, EBADF	},
+	{	ERROR_NEGATIVE_SEEK, EINVAL	},
+	{	ERROR_SEEK_ON_DEVICE, EACCES	},
+	{	ERROR_DIR_NOT_EMPTY, ENOTEMPTY	},
+	{	ERROR_NOT_LOCKED, EACCES	},
+	{	ERROR_BAD_PATHNAME, ENOENT	},
+	{	ERROR_MAX_THRDS_REACHED, EAGAIN	},
+	{	ERROR_LOCK_FAILED, EACCES	},
+	{	ERROR_ALREADY_EXISTS, EEXIST	},
+	{	ERROR_FILENAME_EXCED_RANGE, ENOENT	},
+	{	ERROR_NESTING_NOT_ALLOWED, EAGAIN	},
+	{	ERROR_NOT_ENOUGH_QUOTA, ENOMEM	}
+};
+
+static void
+__tar_dosmaperr(unsigned long e)
+{
+	int			i;
+
+	if (e == 0)	{
+		errno = 0;
+		return;
+	}
+
+	for (i = 0; i < (int)sizeof(doserrors); i++) {
+		if (doserrors[i].winerr == e) {
+			errno = doserrors[i].doserr;
+			return;
+		}
+	}
+
+	/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+	errno = EINVAL;
+	return;
+}
+
+#endif
diff --git a/tar/bsdtar_windows.h b/tar/bsdtar_windows.h
new file mode 100644
index 000000000000..f0611d79abdc
--- /dev/null
+++ b/tar/bsdtar_windows.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef BSDTAR_WINDOWS_H
+#define	BSDTAR_WINDOWS_H 1
+#include <direct.h>
+#include <windows.h>
+
+#ifndef PRId64
+#define	PRId64 "I64"
+#endif
+#define	geteuid()	0
+
+#ifndef S_IFIFO
+#define	S_IFIFO	0010000 /* pipe */
+#endif
+
+#include <string.h>  /* Must include before redefining 'strdup' */
+#if !defined(__BORLANDC__)
+#define	strdup _strdup
+#endif
+#if !defined(__BORLANDC__)
+#define	getcwd _getcwd
+#endif
+
+#define	chdir __tar_chdir
+int __tar_chdir(const char *);
+
+#ifndef S_ISREG
+#define	S_ISREG(a)	(a & _S_IFREG)
+#endif
+#ifndef S_ISBLK
+#define	S_ISBLK(a)	(0)
+#endif
+
+#endif /* BSDTAR_WINDOWS_H */
diff --git a/tar/config_freebsd.h b/tar/config_freebsd.h
new file mode 100644
index 000000000000..e9c2b0a81bbc
--- /dev/null
+++ b/tar/config_freebsd.h
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* A default configuration for FreeBSD, used if there is no config.h. */
+
+#include <sys/param.h>  /* __FreeBSD_version */
+
+#undef	HAVE_ATTR_XATTR_H
+#define	HAVE_CHROOT 1
+#define	HAVE_DIRENT_D_NAMLEN 1
+#define	HAVE_DIRENT_H 1
+#define	HAVE_D_MD_ORDER 1
+#define	HAVE_ERRNO_H 1
+#undef	HAVE_EXT2FS_EXT2_FS_H
+#define	HAVE_FCHDIR 1
+#define	HAVE_FCNTL_H 1
+#define	HAVE_GRP_H 1
+#define	HAVE_LANGINFO_H 1
+#undef	HAVE_LIBACL
+#define	HAVE_LIBARCHIVE 1
+#define	HAVE_LIMITS_H 1
+#define	HAVE_LINK 1
+#undef	HAVE_LINUX_EXT2_FS_H
+#undef	HAVE_LINUX_FS_H
+#define	HAVE_LOCALE_H 1
+#define	HAVE_MBTOWC 1
+#undef	HAVE_NDIR_H
+#if __FreeBSD_version >= 450002 /* nl_langinfo introduced */
+#define	HAVE_NL_LANGINFO 1
+#endif
+#define	HAVE_PATHS_H 1
+#define	HAVE_PWD_H 1
+#define	HAVE_READLINK 1
+#define	HAVE_REGEX_H 1
+#define	HAVE_SETLOCALE 1
+#define	HAVE_SIGNAL_H 1
+#define	HAVE_STDARG_H 1
+#define	HAVE_STDLIB_H 1
+#define	HAVE_STRING_H 1
+#define	HAVE_STRUCT_STAT_ST_FLAGS 1
+#undef	HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+#undef	HAVE_STRUCT_STAT_ST_MTIME_N
+#undef	HAVE_STRUCT_STAT_ST_MTIME_USEC
+#define	HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+#undef	HAVE_STRUCT_STAT_ST_UMTIME
+#define	HAVE_SYMLINK 1
+#define	HAVE_SYS_CDEFS_H 1
+#undef	HAVE_SYS_DIR_H
+#define	HAVE_SYS_IOCTL_H 1
+#undef	HAVE_SYS_NDIR_H
+#define	HAVE_SYS_PARAM_H 1
+#define	HAVE_SYS_STAT_H 1
+#define	HAVE_TIME_H 1
+#define	HAVE_SYS_TYPES_H 1
+#define	HAVE_UINTMAX_T 1
+#define	HAVE_UNISTD_H 1
+#define	HAVE_UNSIGNED_LONG_LONG
+#define	HAVE_WCTYPE_H 1
+#define	HAVE_ZLIB_H 1
+#undef	MAJOR_IN_MKDEV
diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt
new file mode 100644
index 000000000000..98f49e29298b
--- /dev/null
+++ b/tar/test/CMakeLists.txt
@@ -0,0 +1,101 @@
+############################################
+#
+# How to build bsdtar_test
+#
+############################################
+IF(ENABLE_TAR AND ENABLE_TEST)
+  SET(bsdtar_test_SOURCES
+    ../../test_utils/test_utils.c
+    main.c
+    test.h
+    test_0.c
+    test_basic.c
+    test_copy.c
+    test_empty_mtree.c
+    test_extract_tar_Z.c
+    test_extract_tar_bz2.c
+    test_extract_tar_grz.c
+    test_extract_tar_gz.c
+    test_extract_tar_lrz.c
+    test_extract_tar_lz.c
+    test_extract_tar_lzma.c
+    test_extract_tar_lzo.c
+    test_extract_tar_xz.c
+    test_format_newc.c
+    test_help.c
+    test_option_C_upper.c
+    test_option_H_upper.c
+    test_option_L_upper.c
+    test_option_O_upper.c
+    test_option_T_upper.c
+    test_option_U_upper.c
+    test_option_X_upper.c
+    test_option_a.c
+    test_option_b.c
+    test_option_b64encode.c
+    test_option_exclude.c
+    test_option_gid_gname.c
+    test_option_grzip.c
+    test_option_j.c
+    test_option_k.c
+    test_option_keep_newer_files.c
+    test_option_lrzip.c
+    test_option_lzma.c
+    test_option_lzop.c
+    test_option_n.c
+    test_option_newer_than.c
+    test_option_nodump.c
+    test_option_older_than.c
+    test_option_q.c
+    test_option_r.c
+    test_option_s.c
+    test_option_uid_uname.c
+    test_option_uuencode.c
+    test_option_xz.c
+    test_option_z.c
+    test_patterns.c
+    test_print_longpath.c
+    test_stdio.c
+    test_strip_components.c
+    test_symlink_dir.c
+    test_version.c
+    test_windows.c
+  )
+
+  #
+  # Register target
+  #
+  ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
+  SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
+
+  #
+  # Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
+  #
+  GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
+    ${CMAKE_CURRENT_LIST_FILE} ${bsdtar_test_SOURCES})
+  SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
+    ${CMAKE_CURRENT_BINARY_DIR})
+
+  # list.h has a line DEFINE_TEST(testname) for every
+  # test.  We can use that to define the tests for cmake by
+  # defining a DEFINE_TEST macro and reading list.h in.
+  MACRO (DEFINE_TEST _testname)
+    ADD_TEST(
+      NAME bsdtar_${_testname}
+      COMMAND bsdtar_test -vv
+                          -p $<TARGET_FILE:bsdtar>
+                          -r ${CMAKE_CURRENT_SOURCE_DIR}
+                          ${_testname})
+  ENDMACRO (DEFINE_TEST _testname)
+
+  INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
+  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
+
+  # Experimental new test handling
+  ADD_CUSTOM_TARGET(run_bsdtar_test
+	COMMAND	bsdtar_test -p ${BSDTAR} -r ${CMAKE_CURRENT_SOURCE_DIR})
+  ADD_DEPENDENCIES(run_bsdtar_test bsdtar)
+  ADD_DEPENDENCIES(run_all_tests run_bsdtar_test)
+
+ENDIF(ENABLE_TAR AND ENABLE_TEST)
diff --git a/tar/test/test_windows.c b/tar/test/test_windows.c
new file mode 100644
index 000000000000..1977ec644e68
--- /dev/null
+++ b/tar/test/test_windows.c
@@ -0,0 +1,324 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <direct.h>
+#include <windows.h>
+
+static void
+mkfile(const char *name)
+{
+	FILE *f;
+
+	f = fopen(name, "wb");
+	assert(f != NULL);
+	assertEqualInt(5, fwrite("01234", 1, 5, f));
+	fclose(f);
+}
+
+static void
+mkfullpath(char **path1, char **path2, const char *tpath, int type)
+{
+	char *fp1 = NULL, *fp2 = NULL, *p1 = NULL, *p2 = NULL;
+	size_t l;
+
+	/*
+	 * Get full path name of "tpath"
+	 */
+	l = GetFullPathNameA(tpath, 0, NULL, NULL);
+	assert(0 != l);
+	fp1 = malloc(l);
+	assert(NULL != fp1);
+	fp2 = malloc(l*2);
+	assert(NULL != fp2);
+	l = GetFullPathNameA(tpath, (DWORD)l, fp1, NULL);
+	if ((type & 0x01) == 0) {
+		for (p1 = fp1; *p1 != '\0'; p1++)
+			if (*p1 == '\\')
+				*p1 = '/';
+	}
+
+	switch(type) {
+	case 0: /* start with "/" */
+	case 1: /* start with "\" */
+		/* strip "c:" */
+		memmove(fp1, fp1 + 2, l - 2);
+		fp1[l -2] = '\0';
+		p1 = fp1 + 1;
+		break;
+	case 2: /* start with "c:/" */
+	case 3: /* start with "c:\" */
+		p1 = fp1 + 3;
+		break;
+	case 4: /* start with "//./c:/" */
+	case 5: /* start with "\\.\c:\" */
+	case 6: /* start with "//?/c:/" */
+	case 7: /* start with "\\?\c:\" */
+		p1 = malloc(l + 4 + 1);
+		assert(NULL != p1);
+		if (type & 0x1)
+			memcpy(p1, "\\\\.\\", 4);
+		else
+			memcpy(p1, "//./", 4);
+		if (type == 6 || type == 7)
+			p1[2] = '?';
+		memcpy(p1 + 4, fp1, l);
+		p1[l + 4] = '\0';
+		free(fp1);
+		fp1 = p1;
+		p1 = fp1 + 7;
+		break;
+	}
+
+	/*
+	 * Strip leading drive names and converting "\" to "\\"
+	 */
+	p2 = fp2;
+	while (*p1 != '\0') {
+		if (*p1 == '\\')
+			*p2 = '/';
+		else
+			*p2 = *p1;
+		++p1;
+		++p2;
+	}
+	*p2++ = '\r';
+	*p2++ = '\n';
+	*p2 = '\0';
+
+	*path1 = fp1;
+	*path2 = fp2;
+}
+
+static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/",
+	"aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1",
+	"aab/", "aac/", "abb/", "abc/", "abd/", NULL};
+static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/",
+	"bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/",
+	"bbd/", "bcc/", "bcd/", "bce/", NULL};
+static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL};
+static const char *list4[] = {"fff/abca", "fff/acca", NULL};
+static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1",
+	"aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL};
+static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/",
+	"aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL};
+#endif /* _WIN32 && !__CYGWIN__ */
+
+DEFINE_TEST(test_windows)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	char *fp1, *fp2;
+
+	/*
+	 * Preparre tests.
+	 * Create directories and files.
+	 */
+	assertMakeDir("tmp", 0775);
+	assertChdir("tmp");
+
+	assertMakeDir("aaa", 0775);
+	assertMakeDir("aaa/xxa", 0775);
+	assertMakeDir("aaa/xxb", 0775);
+	assertMakeDir("aaa/zzc", 0775);
+	mkfile("aaa/file1");
+	mkfile("aaa/xxa/file1");
+	mkfile("aaa/xxb/file1");
+	mkfile("aaa/zzc/file1");
+	assertMakeDir("aab", 0775);
+	assertMakeDir("aac", 0775);
+	assertMakeDir("abb", 0775);
+	assertMakeDir("abc", 0775);
+	assertMakeDir("abd", 0775);
+	assertMakeDir("bbb", 0775);
+	assertMakeDir("bbb/xxa", 0775);
+	assertMakeDir("bbb/xxb", 0775);
+	assertMakeDir("bbb/zzc", 0775);
+	mkfile("bbb/file1");
+	mkfile("bbb/xxa/file1");
+	mkfile("bbb/xxb/file1");
+	mkfile("bbb/zzc/file1");
+	assertMakeDir("bbc", 0775);
+	assertMakeDir("bbd", 0775);
+	assertMakeDir("bcc", 0775);
+	assertMakeDir("bcd", 0775);
+	assertEqualInt(0, _mkdir("bce"));
+	assertEqualInt(0, _mkdir("ccc"));
+	assertEqualInt(0, _mkdir("fff"));
+	mkfile("fff/aaaa");
+	mkfile("fff/abba");
+	mkfile("fff/abca");
+	mkfile("fff/acba");
+	mkfile("fff/acca");
+
+	/*
+	 * Test1: Command line pattern matching.
+	 */
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive1.tar a*", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive1.tar > ../list1", testprog));
+	assertFileContainsLinesAnyOrder("../list1", list1);
+
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive2.tar b*", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive2.tar > ../list2", testprog));
+	assertFileContainsLinesAnyOrder("../list2", list2);
+
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive3.tar ??c", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive3.tar > ../list3", testprog));
+	assertFileContainsLinesAnyOrder("../list3", list3);
+
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive3b.tar *c", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive3b.tar > ../list3b", testprog));
+	assertFileContainsLinesAnyOrder("../list3b", list3);
+
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive4.tar fff/a?ca", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive4.tar > ../list4", testprog));
+	assertFileContainsLinesAnyOrder("../list4", list4);
+
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive5.tar aaa\\*", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive5.tar > ../list5", testprog));
+	assertFileContainsLinesAnyOrder("../list5", list5);
+
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive6.tar > ../list6", testprog));
+	assertFileContainsLinesAnyOrder("../list6", list6);
+
+	/*
+	 * Test2: Archive the file start with drive letters.
+	 */
+	/* Test2a: start with "/" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 0);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive10.tar %s > ../out10 2> ../err10",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive10.tar > ../list10", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list10");
+	free(fp1);
+	free(fp2);
+
+	/* Test2b: start with "\" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 1);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive11.tar %s > ../out11 2> ../err11",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive11.tar > ../list11", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list11");
+	free(fp1);
+	free(fp2);
+
+	/* Test2c: start with "c:/" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 2);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive12.tar %s > ../out12 2> ../err12",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive12.tar > ../list12", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list12");
+	free(fp1);
+	free(fp2);
+
+	/* Test2d: start with "c:\" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 3);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive13.tar %s > ../out13 2> ../err13",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive13.tar > ../list13", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list13");
+	free(fp1);
+	free(fp2);
+
+	/* Test2e: start with "//./c:/" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 4);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive14.tar %s > ../out14 2> ../err14",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive14.tar > ../list14", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list14");
+	free(fp1);
+	free(fp2);
+
+	/* Test2f: start with "\\.\c:\" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 5);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive15.tar %s > ../out15 2> ../err15",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive15.tar > ../list15", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list15");
+	free(fp1);
+	free(fp2);
+
+	/* Test2g: start with "//?/c:/" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 6);
+	failure("fp1=%s, fp2=%s", fp1, fp2);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive16.tar %s > ../out16 2> ../err16",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive16.tar > ../list16", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list16");
+	free(fp1);
+	free(fp2);
+
+	/* Test2h: start with "\\?\c:\" */
+	mkfullpath(&fp1, &fp2, "aaa/file1", 7);
+	failure("fp1=%s, fp2=%s", fp1, fp2);
+	assertEqualInt(0,
+	    systemf("%s -cf ../archive17.tar %s > ../out17 2> ../err17",
+	        testprog, fp1));
+	assertEqualInt(0,
+	    systemf("%s -tf ../archive17.tar > ../list17", testprog));
+	/* Check drive letters have been stripped. */
+	assertFileContents(fp2, (int)strlen(fp2), "../list17");
+	free(fp1);
+	free(fp2);
+#else
+	skipping("Windows specific test");
+#endif /* _WIN32 && !__CYGWIN__ */
+}