summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt11
-rw-r--r--CONTRIBUTING.rst5
-rw-r--r--CompileFlags.cmake12
-rw-r--r--Help/command/file.rst11
-rw-r--r--Help/dev/maint.rst42
-rw-r--r--Help/manual/cmake-buildsystem.7.rst2
-rw-r--r--Help/manual/cmake-qt.7.rst6
-rw-r--r--Help/prop_tgt/AUTOMOC.rst3
-rw-r--r--Help/prop_tgt/AUTOUIC.rst3
-rw-r--r--Help/release/dev/autogen-configs.rst8
-rw-r--r--Help/release/dev/drop-HP-UX.rst8
-rw-r--r--Help/release/index.rst2
-rw-r--r--Modules/CheckCXXSymbolExists.cmake2
-rw-r--r--Modules/CheckSymbolExists.cmake6
-rw-r--r--Modules/Compiler/IAR-C.cmake3
-rw-r--r--Modules/Compiler/IAR-CXX.cmake2
-rw-r--r--Modules/FindBoost.cmake2
-rw-r--r--Modules/FindCygwin.cmake10
-rw-r--r--Modules/FindHDF5.cmake77
-rw-r--r--Modules/FindJava.cmake4
-rw-r--r--Modules/FindLibXml2.cmake7
-rw-r--r--Modules/FindMatlab.cmake4
-rw-r--r--Modules/Platform/Android-Common.cmake12
-rw-r--r--Modules/UseSWIG.cmake6
-rw-r--r--README.rst2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmFindPackageCommand.cxx20
-rw-r--r--Source/cmFindPackageCommand.h1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx2
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx1
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx124
-rw-r--r--Source/cmQtAutoGenerators.cxx54
-rw-r--r--Source/cmServerProtocol.cxx4
-rw-r--r--Tests/AliasTarget/CMakeLists.txt7
-rw-r--r--Tests/CMakeLists.txt39
-rw-r--r--Tests/Complex/CMakeLists.txt7
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt7
-rw-r--r--Tests/Plugin/CMakeLists.txt7
-rw-r--r--Tests/QtAutoUicInterface/CMakeLists.txt5
-rw-r--r--Tests/QtAutogen/CMakeLists.txt203
-rw-r--r--Tests/QtAutogen/mocDepends/CMakeLists.txt97
-rw-r--r--Tests/QtAutogen/mocDepends/simpleLib.hpp.in5
-rw-r--r--Tests/QtAutogen/mocDepends/test1.cpp3
-rw-r--r--Tests/QtAutogen/mocDepends/test2.cpp7
-rw-r--r--Tests/QtAutogen/mocDepends/test3.cpp12
-rw-r--r--Tests/QtAutogen/mocDepends/test3.hpp (renamed from Tests/QtAutogen/mocDepends/test2.hpp)4
-rw-r--r--Tests/QtAutogen/mocInclude/shared.cmake6
-rw-r--r--Tests/QtAutogenRerun/CMakeLists.txt239
-rw-r--r--Tests/QtAutogenRerun/defines_test/CMakeLists.txt4
-rw-r--r--Tests/QtAutogenRerun/defines_test/defines_test.cpp38
-rw-r--r--Tests/QtAutogenRerun/dummy.cpp5
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt (renamed from Tests/QtAutogen/mocPlugin/CMakeLists.txt)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleA.cpp (renamed from Tests/QtAutogen/mocPlugin/StyleA.cpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleA.hpp (renamed from Tests/QtAutogen/mocPlugin/StyleA.hpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleA.json (renamed from Tests/QtAutogen/mocPlugin/StyleA.json)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleA_Custom.json (renamed from Tests/QtAutogen/mocPlugin/StyleA_Custom.json)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleB.cpp (renamed from Tests/QtAutogen/mocPlugin/StyleB.cpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleB.hpp (renamed from Tests/QtAutogen/mocPlugin/StyleB.hpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleC.cpp (renamed from Tests/QtAutogen/mocPlugin/StyleC.cpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleC.hpp (renamed from Tests/QtAutogen/mocPlugin/StyleC.hpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleCommon.hpp (renamed from Tests/QtAutogen/mocPlugin/StyleCommon.hpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleD.cpp (renamed from Tests/QtAutogen/mocPlugin/StyleD.cpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleD.hpp (renamed from Tests/QtAutogen/mocPlugin/StyleD.hpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleE.cpp (renamed from Tests/QtAutogen/mocPlugin/StyleE.cpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/StyleE.hpp (renamed from Tests/QtAutogen/mocPlugin/StyleE.hpp)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json (renamed from Tests/QtAutogen/mocPlugin/jsonIn/StyleB.json)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB_Custom.json (renamed from Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleC.json (renamed from Tests/QtAutogen/mocPlugin/jsonIn/StyleC.json)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleD.json (renamed from Tests/QtAutogen/mocPlugin/jsonIn/StyleD.json)0
-rw-r--r--Tests/QtAutogenRerun/mocPlugin/main.cpp (renamed from Tests/QtAutogen/mocPlugin/main.cpp)0
-rw-r--r--Tests/QtAutogenRerun/mocRerun/CMakeLists.txt (renamed from Tests/QtAutogen/mocRerun/CMakeLists.txt)0
-rw-r--r--Tests/QtAutogenRerun/mocRerun/input.txt (renamed from Tests/QtAutogen/mocRerun/input.txt)0
-rw-r--r--Tests/QtAutogenRerun/mocRerun/main.cpp.in (renamed from Tests/QtAutogen/mocRerun/main.cpp.in)0
-rw-r--r--Tests/QtAutogenRerun/mocRerun/res1.qrc (renamed from Tests/QtAutogen/mocRerun/res1.qrc)0
-rw-r--r--Tests/QtAutogenRerun/mocRerun/test1a.h.in (renamed from Tests/QtAutogen/mocRerun/test1a.h.in)0
-rw-r--r--Tests/QtAutogenRerun/mocRerun/test1b.h.in (renamed from Tests/QtAutogen/mocRerun/test1b.h.in)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/CMakeLists.txt (renamed from Tests/QtAutogen/rccDepends/CMakeLists.txt)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/main.cpp (renamed from Tests/QtAutogen/rccDepends/main.cpp)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/res/input1.txt.in (renamed from Tests/QtAutogen/rccDepends/res/input1.txt.in)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/res/input2.txt.in (renamed from Tests/QtAutogen/rccDepends/res/input2.txt.in)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/res1a.qrc.in (renamed from Tests/QtAutogen/rccDepends/res1a.qrc.in)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/res1b.qrc.in (renamed from Tests/QtAutogen/rccDepends/res1b.qrc.in)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/res2a.qrc.in (renamed from Tests/QtAutogen/rccDepends/res2a.qrc.in)0
-rw-r--r--Tests/QtAutogenRerun/rccDepends/res2b.qrc.in (renamed from Tests/QtAutogen/rccDepends/res2b.qrc.in)0
-rw-r--r--Tests/RunCMake/GenerateExportHeader/GEH.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt4
-rw-r--r--Tests/RunCMake/find_package/PackageRoot-stderr.txt362
-rw-r--r--Tests/RunCMake/find_package/PackageRoot.cmake118
-rw-r--r--Tests/RunCMake/find_package/PackageRoot/BarConfig.cmake9
-rw-r--r--Tests/RunCMake/find_package/PackageRoot/FindBar.cmake1
-rw-r--r--Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake4
-rw-r--r--Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake9
-rw-r--r--Tests/RunCMake/find_package/PackageRoot/foo/env_root/cmake/BarConfig.cmake9
-rw-r--r--Tests/RunCMake/find_package/PackageRootNestedConfig-stderr.txt298
-rw-r--r--Tests/RunCMake/find_package/PackageRootNestedConfig.cmake135
-rw-r--r--Tests/RunCMake/find_package/PackageRootNestedModule-stderr.txt298
-rw-r--r--Tests/RunCMake/find_package/PackageRootNestedModule.cmake135
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake2
-rwxr-xr-xUtilities/Scripts/update-expat.bash6
-rwxr-xr-xUtilities/Scripts/update-libarchive.bash2
-rw-r--r--Utilities/Sphinx/cmake.py17
-rw-r--r--Utilities/cmexpat/CMakeLists.txt7
-rw-r--r--Utilities/cmexpat/ConfigureChecks.cmake2
-rw-r--r--Utilities/cmexpat/README139
-rw-r--r--Utilities/cmexpat/README.md126
-rw-r--r--Utilities/cmexpat/lib/expat.h3
-rw-r--r--Utilities/cmexpat/lib/loadlibrary.c141
-rw-r--r--Utilities/cmexpat/lib/siphash.h55
-rw-r--r--Utilities/cmexpat/lib/xmlparse.c530
-rw-r--r--Utilities/cmexpat/lib/xmlrole.c30
-rw-r--r--Utilities/cmexpat/lib/xmltok.c13
-rw-r--r--Utilities/cmexpat/lib/xmltok_impl.c39
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt409
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in92
-rw-r--r--Utilities/cmlibarchive/build/version2
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_check_magic.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_disk_acl_darwin.c559
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_disk_acl_freebsd.c700
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_disk_acl_linux.c743
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c821
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c31
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_acl.310
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_paths.312
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_perms.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_sparse.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_getdate.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pack_dev.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform.h26
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform_acl.h49
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform_xattr.h41
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_random.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk.372
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c1285
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_private.h9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_format.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c156
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c180
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c18
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c39
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string_sprintf.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c88
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_version_details.c133
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_data.324
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk.3185
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c654
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c296
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_finish_entry.35
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_format.31
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c17
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/config_freebsd.h351
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_changes.31
-rw-r--r--Utilities/cmlibarchive/libarchive/mtree.52
-rw-r--r--Utilities/cmlibarchive/libarchive/xxhash.c12
-rwxr-xr-xbootstrap59
183 files changed, 6915 insertions, 3953 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed924eb..831e25f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,14 @@ if(CMAKE_BOOTSTRAP)
endif()
if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ if(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
+ message(FATAL_ERROR
+ "CMake no longer compiles on HP-UX. See\n"
+ " https://gitlab.kitware.com/cmake/cmake/issues/17137\n"
+ "Use CMake 3.9 or lower instead."
+ )
+ endif()
+
set(CMake_BIN_DIR ${CMake_BINARY_DIR}/bin)
endif()
@@ -536,9 +544,6 @@ int main(void) { return 0; }
if(NOT HAVE_CoreServices_OS_X_10_5)
set(CMAKE_USE_LIBUV 0)
endif()
- elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
- # Disable until it can be ported.
- set(CMAKE_USE_LIBUV 0)
endif()
endif()
if(CMAKE_USE_LIBUV)
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index e219763..3c84c2b 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -27,9 +27,12 @@ To contribute patches:
#. Run `Utilities/SetupForDevelopment.sh`_ for local configuration.
#. See the `CMake Source Code Guide`_ for coding guidelines.
#. Base all new work on the upstream ``master`` branch.
+ Base work on the upstream ``release`` branch only if it fixes a
+ regression or bug in a feature new to that release.
#. Create commits making incremental, distinct, logically complete changes.
#. Push a topic branch to a personal repository fork on GitLab.
-#. Create a GitLab Merge Request targeting the upstream ``master`` branch.
+#. Create a GitLab Merge Request targeting the upstream ``master`` branch
+ (even if the change is intended for merge to the ``release`` branch).
The merge request will enter the `CMake Review Process`_ for consideration.
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index 7a9d4cd..9834b04 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -37,18 +37,6 @@ if(CMAKE_SYSTEM MATCHES "OSF1-V")
endif()
endif()
-if(CMAKE_SYSTEM_NAME MATCHES "HP-UX" AND CMAKE_CXX_COMPILER_ID MATCHES "HP")
- # HP aCC since version 3.80 supports the flag +hpxstd98 to get ANSI C++98
- # template support. It is known that version 6.25 doesn't need that flag.
- # Versions prior to 3.80 will not be able to build CMake. Current assumption:
- # it is needed for every version from 3.80 to 4 to get it working.
- if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4 AND
- NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.80)
- # use new C++ library and improved template support
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
- endif()
-endif()
-
# Workaround for short jump tables on PA-RISC
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^parisc")
if(CMAKE_COMPILER_IS_GNUCC)
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 97466ff..edccac5 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -13,8 +13,11 @@ File manipulation command.
Write ``<content>`` into a file called ``<filename>``. If the file does
not exist, it will be created. If the file already exists, ``WRITE``
mode will overwrite it and ``APPEND`` mode will append to the end.
-(If the file is a build input, use the :command:`configure_file` command
-to update the file only when its content changes.)
+Any directories in the path specified by ``<filename>`` that do not
+exist will be created.
+
+If the file is a build input, use the :command:`configure_file` command
+to update the file only when its content changes.
------------------------------------------------------------------------------
@@ -105,9 +108,7 @@ Generate a list of files that match the ``<globbing-expressions>`` and
store it into the ``<variable>``. Globbing expressions are similar to
regular expressions, but much simpler. If ``RELATIVE`` flag is
specified, the results will be returned as relative paths to the given
-path. No specific order of results is defined other than that it is
-deterministic. If order is important then sort the list explicitly
-(e.g. using the :command:`list(SORT)` command).
+path. The results will be ordered lexicographically.
By default ``GLOB`` lists directories - directories are omited in result if
``LIST_DIRECTORIES`` is set to false.
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 889e4e3..bdfb3d0 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -37,6 +37,48 @@ command to integrate a merge request. Please check at least the following:
introduced. (Learn to tolerate spurious failures due to idiosyncrasies
of various nightly builders.)
+* Ensure that the MR targets the ``master`` branch. A MR intended for
+ the ``release`` branch should be based on ``release`` but still merged
+ to ``master`` first (via ``Do: merge``). A maintainer may then merge
+ the MR topic to ``release`` manually.
+
+Maintain Current Release
+========================
+
+The ``release`` branch is used to maintain the current release or release
+candidate. The branch is published with no version number but maintained
+using a local branch named ``release-$ver``, where ``$ver`` is the version
+number of the current release in the form ``$major.$minor``. It is always
+merged into ``master`` before publishing.
+
+To merge some ``$topic`` branch into ``release``, first create the local
+branch:
+
+.. code-block:: shell
+
+ git fetch origin
+ git checkout -b release-$ver origin/release
+
+Merge the ``$topic`` branch into the local ``release-$ver`` branch:
+
+.. code-block:: shell
+
+ git merge --no-ff $topic
+
+Merge the ``release-$ver`` branch to ``master``:
+
+.. code-block:: shell
+
+ git checkout master
+ git pull
+ git merge --no-ff release-$ver
+
+Publish both ``master`` and ``release`` simultaneously:
+
+.. code-block:: shell
+
+ git push --atomic origin master release-$ver:release
+
.. _`CMake Review Process`: review.rst
.. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 95f5b87..debaf23 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -266,7 +266,7 @@ The :command:`target_link_libraries` command has ``PRIVATE``,
Because ``archive`` is a ``PUBLIC`` dependency of ``archiveExtras``, the
usage requirements of it are propagated to ``consumer`` too. Because
-``serialization`` is a ``PRIVATE`` dependency of ``archive``, the usage
+``serialization`` is a ``PRIVATE`` dependency of ``archiveExtras``, the usage
requirements of it are not propagated to ``consumer``.
Generally, a dependency should be specified in a use of
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst
index 00d6e6e..b3b09d1 100644
--- a/Help/manual/cmake-qt.7.rst
+++ b/Help/manual/cmake-qt.7.rst
@@ -72,6 +72,9 @@ Included ``moc_*.cpp`` and ``*.moc`` files will be generated in the
automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`.
(This differs from CMake 3.7 and below; see their documentation for details.)
+* For multi configuration generators, the include directory is
+ ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``.
+
* See :prop_tgt:`AUTOGEN_BUILD_DIR`.
Not included ``moc_<basename>.cpp`` files will be generated in custom
@@ -117,6 +120,9 @@ The generated generated ``ui_*.h`` files are placed in the
automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`.
(This differs from CMake 3.7 and below; see their documentation for details.)
+* For multi configuration generators, the include directory is
+ ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``.
+
* See :prop_tgt:`AUTOGEN_BUILD_DIR`.
The :prop_tgt:`AUTOUIC` target property may be pre-set for all following
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
index 0171d20..e70fe0d 100644
--- a/Help/prop_tgt/AUTOMOC.rst
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -20,6 +20,9 @@ source files at build time and invoke moc accordingly.
This allows the compiler to find the included ``moc_<basename>.cpp`` file
regardless of the location the original source.
+ * For multi configuration generators, the include directory is
+ ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``.
+
* See :prop_tgt:`AUTOGEN_BUILD_DIR`.
* If an ``#include`` statement like ``#include "<basename>.moc"`` is found,
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
index 6493bbc..2fc2167 100644
--- a/Help/prop_tgt/AUTOUIC.rst
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -17,6 +17,9 @@ optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target.
``<AUTOGEN_BUILD_DIR>/include``,
which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`.
+* For multi configuration generators, the include directory is
+ ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``.
+
* See :prop_tgt:`AUTOGEN_BUILD_DIR`.
This property is initialized by the value of the :variable:`CMAKE_AUTOUIC`
diff --git a/Help/release/dev/autogen-configs.rst b/Help/release/dev/autogen-configs.rst
new file mode 100644
index 0000000..7613c68
--- /dev/null
+++ b/Help/release/dev/autogen-configs.rst
@@ -0,0 +1,8 @@
+autogen-configs
+---------------
+
+* When using :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` with a
+ multi configuration generator (e.g. :generator:`Xcode`),
+ included ``*.moc``, ``moc_*.cpp`` and ``ui_*.h`` files are generated in
+ ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>`` instead of
+ ``<AUTOGEN_BUILD_DIR>/include``.
diff --git a/Help/release/dev/drop-HP-UX.rst b/Help/release/dev/drop-HP-UX.rst
new file mode 100644
index 0000000..199fa09
--- /dev/null
+++ b/Help/release/dev/drop-HP-UX.rst
@@ -0,0 +1,8 @@
+drop-HP-UX
+----------
+
+* Support for building CMake on HP-UX has been dropped pending better
+ support for C++11 and a port of libuv. See `CMake Issue 17137`_.
+ Use CMake 3.9 or lower instead for HP-UX support.
+
+.. _`CMake Issue 17137`: https://gitlab.kitware.com/cmake/cmake/issues/17137
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 7f481a3..6c68e65 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
CMake Release Notes
*******************
diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake
index 354eea3..8552154 100644
--- a/Modules/CheckCXXSymbolExists.cmake
+++ b/Modules/CheckCXXSymbolExists.cmake
@@ -35,5 +35,5 @@
include(CheckSymbolExists)
macro(CHECK_CXX_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
- _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
endmacro()
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index 6f1afcf..6d52d56 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -45,15 +45,15 @@ the way the check is run:
macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
if(CMAKE_C_COMPILER_LOADED)
- _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
elseif(CMAKE_CXX_COMPILER_LOADED)
- _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
else()
message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled")
endif()
endmacro()
-macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
+macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE)
if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake
index 48a9a16..55e019e 100644
--- a/Modules/Compiler/IAR-C.cmake
+++ b/Modules/Compiler/IAR-C.cmake
@@ -5,6 +5,9 @@ include(Compiler/CMakeCommonCompilerMacros)
# The toolchains for ARM and AVR are quite different:
if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM")
+
+ set(CMAKE_C_EXTENSION_COMPILE_OPTION -e)
+
set(CMAKE_C90_STANDARD_COMPILE_OPTION "")
set(CMAKE_C90_EXTENSION_COMPILE_OPTION -e)
diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake
index 7a6ba2b..8d86100 100644
--- a/Modules/Compiler/IAR-CXX.cmake
+++ b/Modules/Compiler/IAR-CXX.cmake
@@ -17,6 +17,8 @@ if("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM")
endif()
endif()
+ set(CMAKE_CXX_EXTENSION_COMPILE_OPTION -e)
+
set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION -e)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index cc273e0..b4abf75 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -244,6 +244,8 @@ if (NOT Boost_NO_BOOST_CMAKE)
message("Found Boost components:")
message(" ${Boost_FIND_COMPONENTS}")
endif()
+ # Restore project's policies
+ cmake_policy(POP)
return()
endif()
endif()
diff --git a/Modules/FindCygwin.cmake b/Modules/FindCygwin.cmake
index b2ed703..086c7dc 100644
--- a/Modules/FindCygwin.cmake
+++ b/Modules/FindCygwin.cmake
@@ -9,10 +9,12 @@
if (WIN32)
find_program(CYGWIN_INSTALL_PATH
- cygwin.bat
- "C:/Cygwin"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygwin\\setup;rootdir]"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/;native]"
+ NAMES cygwin.bat
+ PATHS
+ "C:/Cygwin"
+ "C:/Cygwin64"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygwin\\setup;rootdir]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/;native]"
)
get_filename_component(CYGWIN_INSTALL_PATH "${CYGWIN_INSTALL_PATH}" DIRECTORY)
mark_as_advanced(
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 48d5de4..de20049 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -396,6 +396,45 @@ macro( _HDF5_parse_compile_line
endforeach()
endmacro()
+# Select a preferred imported configuration from a target
+function(_HDF5_select_imported_config target imported_conf)
+ # We will first assign the value to a local variable _imported_conf, then assign
+ # it to the function argument at the end.
+ get_target_property(_imported_conf ${target} MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE})
+ if (NOT _imported_conf)
+ # Get available imported configurations by examining target properties
+ get_target_property(_imported_conf ${target} IMPORTED_CONFIGURATIONS)
+ if(HDF5_FIND_DEBUG)
+ message(STATUS "Found imported configurations: ${_imported_conf}")
+ endif()
+ # Find the imported configuration that we prefer.
+ # We do this by making list of configurations in order of preference,
+ # starting with ${CMAKE_BUILD_TYPE} and ending with the first imported_conf
+ set(_preferred_confs ${CMAKE_BUILD_TYPE})
+ list(GET _imported_conf 0 _fallback_conf)
+ list(APPEND _preferred_confs RELWITHDEBINFO RELEASE DEBUG ${_fallback_conf})
+ if(HDF5_FIND_DEBUG)
+ message(STATUS "Start search through imported configurations in the following order: ${_preferred_confs}")
+ endif()
+ # Now find the first of these that is present in imported_conf
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0057 NEW) # support IN_LISTS
+ foreach (_conf IN LISTS _preferred_confs)
+ if (${_conf} IN_LIST _imported_conf)
+ set(_imported_conf ${_conf})
+ break()
+ endif()
+ endforeach()
+ cmake_policy(POP)
+ endif()
+ if(HDF5_FIND_DEBUG)
+ message(STATUS "Selected imported configuration: ${_imported_conf}")
+ endif()
+ # assign value to function argument
+ set(${imported_conf} ${_imported_conf} PARENT_SCOPE)
+endfunction()
+
+
if(NOT HDF5_ROOT)
set(HDF5_ROOT $ENV{HDF5_ROOT})
endif()
@@ -452,30 +491,39 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE)
message(STATUS "Trying to get properties of target ${HDF5_${_lang}_TARGET}${_suffix}")
endif()
# Find library for this target. Complicated as on Windows with a DLL, we need to search for the import-lib.
- get_target_property(_imported_conf ${HDF5_${_lang}_TARGET}${_suffix} IMPORTED_CONFIGURATIONS)
- get_target_property(_lang_location ${HDF5_${_lang}_TARGET}${_suffix} IMPORTED_IMPLIB_${_imported_conf} )
- if (NOT _lang_location)
+ _HDF5_select_imported_config(${HDF5_${_lang}_TARGET}${_suffix} _hdf5_imported_conf)
+ get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} )
+ if (NOT _hdf5_lang_location)
# no import lib, just try LOCATION
- get_target_property(_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION)
+ get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf})
+ if (NOT _hdf5_lang_location)
+ get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION)
+ endif()
endif()
- if( _lang_location )
- set(HDF5_${_lang}_LIBRARY ${_lang_location})
+ if( _hdf5_lang_location )
+ set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location})
list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
set(HDF5_${_lang}_FOUND True)
endif()
if(FIND_HL)
- get_target_property(__lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_imported_conf} )
- if (NOT _lang_hl_location)
- get_target_property(_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION)
+ get_target_property(__lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} )
+ if (NOT _hdf5_lang_hl_location)
+ get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf})
+ if (NOT _hdf5_hl_lang_location)
+ get_target_property(_hdf5_hl_lang_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION)
+ endif()
endif()
- if( _lang_hl_location )
- set(HDF5_${_lang}_HL_LIBRARY ${_lang_hl_location})
- list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
- set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
+ if( _hdf5_lang_hl_location )
+ set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location})
+ list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
+ set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
set(HDF5_HL_FOUND True)
endif()
+ unset(_hdf5_lang_hl_location)
endif()
+ unset(_hdf5_imported_conf)
+ unset(_hdf5_lang_location)
endforeach()
endif()
endif()
@@ -873,11 +921,14 @@ if (HDF5_FIND_DEBUG)
message(STATUS "HDF5_DEFINITIONS: ${HDF5_DEFINITIONS}")
message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}")
message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}")
+ message(STATUS "HDF5_HL_LIBRARIES: ${HDF5_HL_LIBRARIES}")
foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS)
message(STATUS "HDF5_${__lang}_DEFINITIONS: ${HDF5_${__lang}_DEFINITIONS}")
message(STATUS "HDF5_${__lang}_INCLUDE_DIR: ${HDF5_${__lang}_INCLUDE_DIR}")
message(STATUS "HDF5_${__lang}_INCLUDE_DIRS: ${HDF5_${__lang}_INCLUDE_DIRS}")
message(STATUS "HDF5_${__lang}_LIBRARY: ${HDF5_${__lang}_LIBRARY}")
message(STATUS "HDF5_${__lang}_LIBRARIES: ${HDF5_${__lang}_LIBRARIES}")
+ message(STATUS "HDF5_${__lang}_HL_LIBRARY: ${HDF5_${__lang}_HL_LIBRARY}")
+ message(STATUS "HDF5_${__lang}_HL_LIBRARIES: ${HDF5_${__lang}_HL_LIBRARIES}")
endforeach()
endif()
diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake
index 3d32560..eb2242b 100644
--- a/Modules/FindJava.cmake
+++ b/Modules/FindJava.cmake
@@ -90,7 +90,7 @@ list(APPEND _JAVA_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.9;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.8;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.7;JavaHome]/bin"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\2.6;JavaHome]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.6;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.5;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.4;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.3;JavaHome]/bin"
@@ -143,7 +143,7 @@ if(Java_JAVA_EXECUTABLE)
if(var MATCHES "java version \"([0-9]+\\.[0-9]+\\.[0-9_.]+.*)\"")
# This is most likely Sun / OpenJDK, or maybe GCJ-java compat layer
set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
- elseif(var MATCHES "openjdk version \"([0-9]+)-[a-z]+\"")
+ elseif(var MATCHES "openjdk version \"([0-9]+)-[A-Za-z]+\"")
# OpenJDK 9 early access builds or locally built
set(Java_VERSION_STRING "1.${CMAKE_MATCH_1}.0")
elseif(var MATCHES "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+)\"")
diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake
index f68628d..8ac2980 100644
--- a/Modules/FindLibXml2.cmake
+++ b/Modules/FindLibXml2.cmake
@@ -50,6 +50,13 @@ find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
PATH_SUFFIXES libxml2
)
+# CMake 3.9 and below used 'LIBXML2_LIBRARIES' as the name of
+# the cache entry storing the find_library result. Use the
+# value if it was set by the project or user.
+if(DEFINED LIBXML2_LIBRARIES AND NOT DEFINED LIBXML2_LIBRARY)
+ set(LIBXML2_LIBRARY ${LIBXML2_LIBRARIES})
+endif()
+
find_library(LIBXML2_LIBRARY NAMES xml2 libxml2
HINTS
${PC_LIBXML_LIBDIR}
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 80bcda3..cd8246d 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -721,7 +721,7 @@ endfunction()
# matlab_add_unit_test(
# NAME <name>
# UNITTEST_FILE matlab_file_containing_unittest.m
-# [CUSTOM_MATLAB_COMMAND matlab_command_to_run_as_test]
+# [CUSTOM_TEST_COMMAND matlab_command_to_run_as_test]
# [UNITTEST_PRECOMMAND matlab_command_to_run]
# [TIMEOUT timeout]
# [ADDITIONAL_PATH path1 [path2 ...]]
@@ -737,7 +737,7 @@ endfunction()
# ``UNITTEST_FILE``
# the matlab unittest file. Its path will be automatically
# added to the Matlab path.
-# ``CUSTOM_MATLAB_COMMAND``
+# ``CUSTOM_TEST_COMMAND``
# Matlab script command to run as the test.
# If this is not set, then the following is run:
# ``runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))``
diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index 5faada3..80a8f41 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -160,13 +160,19 @@ macro(__android_compiler_common lang)
# Do not do this for a standalone toolchain because it is already
# tied to a specific API version.
if(CMAKE_ANDROID_NDK)
+ if(CMAKE_SYSROOT_COMPILE)
+ set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}")
+ else()
+ set(_cmake_sysroot_compile "${CMAKE_SYSROOT}")
+ endif()
if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES
- "${CMAKE_SYSROOT_COMPILE}/usr/include"
- "${CMAKE_SYSROOT_COMPILE}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}"
+ "${_cmake_sysroot_compile}/usr/include"
+ "${_cmake_sysroot_compile}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}"
)
else()
- list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include")
+ list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${_cmake_sysroot_compile}/usr/include")
endif()
+ unset(_cmake_sysroot_compile)
endif()
endmacro()
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 456a6bd..c8b1cd7 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -121,8 +121,10 @@ macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
endif()
foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSIONS})
- set(${outfiles} ${${outfiles}}
- "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}${it}")
+ set(extra_file "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}${it}")
+ list(APPEND ${outfiles} ${extra_file})
+ # Treat extra outputs as plain files regardless of language.
+ set_property(SOURCE "${extra_file}" PROPERTY LANGUAGE "")
endforeach()
endmacro()
diff --git a/README.rst b/README.rst
index d5acd4a..0946b70 100644
--- a/README.rst
+++ b/README.rst
@@ -36,7 +36,7 @@ Supported Platforms
* FreeBSD
* OpenBSD
* Solaris
-* HP-UX
+* AIX
Other UNIX-like operating systems may work too out of the box, if not
it should not be a major problem to port CMake to this platform.
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 33c363b..e8ea5ee 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 9)
-set(CMake_VERSION_PATCH 20170721)
+set(CMake_VERSION_PATCH 20170808)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index f291f9d..ca47535 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1090,6 +1090,9 @@ void cmFindPackageCommand::AppendSuccessInformation()
void cmFindPackageCommand::ComputePrefixes()
{
if (!this->NoDefaultPath) {
+ if (!this->NoPackageRootPath) {
+ this->FillPrefixesPackageRoot();
+ }
if (!this->NoCMakePath) {
this->FillPrefixesCMakeVariable();
}
@@ -1117,6 +1120,23 @@ void cmFindPackageCommand::ComputePrefixes()
this->ComputeFinalPaths();
}
+void cmFindPackageCommand::FillPrefixesPackageRoot()
+{
+ cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
+
+ // Add package specific search prefixes
+ // NOTE: This should be using const_reverse_iterator but HP aCC and
+ // Oracle sunCC both currently have standard library issues
+ // with the reverse iterator APIs.
+ for (std::deque<std::string>::reverse_iterator pkg =
+ this->Makefile->FindPackageModuleStack.rbegin();
+ pkg != this->Makefile->FindPackageModuleStack.rend(); ++pkg) {
+ std::string varName = *pkg + "_ROOT";
+ paths.AddCMakePath(varName);
+ paths.AddEnvPath(varName);
+ }
+}
+
void cmFindPackageCommand::FillPrefixesCMakeEnvironment()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeEnvironment];
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 318b1dc..99b0059 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -100,6 +100,7 @@ private:
void StoreVersionFound();
void ComputePrefixes();
+ void FillPrefixesPackageRoot();
void FillPrefixesCMakeEnvironment();
void FillPrefixesCMakeVariable();
void FillPrefixesSystemEnvironment();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index a57d2a0..4d2e5c7 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -813,7 +813,7 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
reportError(
context, content->GetOriginalExpression(),
"$<COMPILE_LANGUAGE:...> may only be used to specify include "
- "directories compile definitions, compile options and to evaluate "
+ "directories, compile definitions, compile options, and to evaluate "
"components of the file(GENERATE) command.");
return std::string();
}
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index e3835ff..4fff11a 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -757,6 +757,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
std::vector<std::string> cmd;
cmd.push_back(this->GetMSBuildCommand());
cmd.push_back(vcxproj);
+ cmd.push_back("/p:Configuration=Debug");
cmd.push_back(std::string("/p:VisualStudioVersion=") +
this->GetIDEVersion());
std::string out;
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 92fa1bd..5a06730 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -158,16 +158,6 @@ static void GetCompileDefinitionsAndDirectories(
static bool IsMultiConfig(cmGlobalGenerator* globalGen)
{
- // FIXME: Xcode does not support per-config sources, yet.
- // (EXCLUDED_SOURCE_FILE_NAMES)
- // Treat it as a single configuration generator meanwhile.
- if (globalGen->GetName().find("Xcode") != std::string::npos) {
- return false;
- }
- // FIXME: Visual Studio does not fully support per-config sources yet.
- if (globalGen->GetName().find("Visual Studio") != std::string::npos) {
- return false;
- }
return globalGen->IsMultiConfig();
}
@@ -707,24 +697,11 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenSources(
{
if (target->GetPropertyAsBool("AUTOMOC")) {
cmMakefile* makefile = target->Target->GetMakefile();
- const std::vector<std::string> suffixes =
- GetConfigurationSuffixes(makefile);
- // Get build directory
- const std::string autogenBuildDir = GetAutogenTargetBuildDir(target);
- // Register all compilation files as generated
- for (std::vector<std::string>::const_iterator it = suffixes.begin();
- it != suffixes.end(); ++it) {
- std::string mcFile = autogenBuildDir + "/mocs_compilation";
- mcFile += *it;
- mcFile += ".cpp";
- AddGeneratedSource(makefile, mcFile, cmQtAutoGeneratorCommon::MOC);
- }
// Mocs compilation file
- if (IsMultiConfig(target->GetGlobalGenerator())) {
- target->AddSource(autogenBuildDir + "/mocs_compilation_$<CONFIG>.cpp");
- } else {
- target->AddSource(autogenBuildDir + "/mocs_compilation.cpp");
- }
+ const std::string mocsComp =
+ GetAutogenTargetBuildDir(target) + "/mocs_compilation.cpp";
+ AddGeneratedSource(makefile, mocsComp, cmQtAutoGeneratorCommon::MOC);
+ target->AddSource(mocsComp);
}
}
@@ -745,7 +722,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
const std::string qtMajorVersion = GetQtMajorVersion(target);
const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
const std::vector<std::string> suffixes = GetConfigurationSuffixes(makefile);
- std::vector<std::string> autogenDepends;
+ std::set<std::string> autogenDependsSet;
std::vector<std::string> autogenProvides;
// Remove build directories on cleanup
@@ -803,24 +780,17 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// Add moc compilation to generated files list
if (mocEnabled) {
- for (std::vector<std::string>::const_iterator it = suffixes.begin();
- it != suffixes.end(); ++it) {
- std::string mcFile = autogenBuildDir + "/mocs_compilation";
- mcFile += *it;
- mcFile += ".cpp";
- autogenProvides.push_back(mcFile);
- }
+ const std::string mocsComp = autogenBuildDir + "/mocs_compilation.cpp";
+ autogenProvides.push_back(mocsComp);
}
// Add autogen includes directory to the origin target INCLUDE_DIRECTORIES
if (mocEnabled || uicEnabled) {
+ std::string includeDir = autogenBuildDir + "/include";
if (multiConfig) {
- target->AddIncludeDirectory(autogenBuildDir + "/include_$<CONFIG>",
- true);
-
- } else {
- target->AddIncludeDirectory(autogenBuildDir + "/include", true);
+ includeDir += "_$<CONFIG>";
}
+ target->AddIncludeDirectory(includeDir, true);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -837,7 +807,20 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// Initialize autogen target dependencies
if (const char* deps = target->GetProperty("AUTOGEN_TARGET_DEPENDS")) {
- cmSystemTools::ExpandListArgument(deps, autogenDepends);
+ std::vector<std::string> extraDepends;
+ cmSystemTools::ExpandListArgument(deps, extraDepends);
+ autogenDependsSet.insert(extraDepends.begin(), extraDepends.end());
+ }
+ // Add other target dependencies autogen dependencies
+ {
+ const std::set<std::string>& utils = target->Target->GetUtilities();
+ for (std::set<std::string>::const_iterator it = utils.begin();
+ it != utils.end(); ++it) {
+ const std::string& targetName = *it;
+ if (makefile->FindTargetToUse(targetName) != CM_NULLPTR) {
+ autogenDependsSet.insert(targetName);
+ }
+ }
}
// Add link library targets to the autogen dependencies
{
@@ -847,7 +830,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
it != libVec.end(); ++it) {
const std::string& libName = it->first;
if (makefile->FindTargetToUse(libName) != CM_NULLPTR) {
- autogenDepends.push_back(libName);
+ autogenDependsSet.insert(libName);
}
}
}
@@ -871,7 +854,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
if (PropertyEnabled(sf, "GENERATED")) {
if ((mocEnabled && !PropertyEnabled(sf, "SKIP_AUTOMOC")) ||
(uicEnabled && !PropertyEnabled(sf, "SKIP_AUTOUIC"))) {
- autogenDepends.push_back(
+ autogenDependsSet.insert(
cmsys::SystemTools::GetRealPath(sf->GetFullPath()));
#if defined(_WIN32) && !defined(__CYGWIN__)
// Cannot use PRE_BUILD with generated files
@@ -889,44 +872,40 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// Compose rcc output file name
{
- std::string rccOutBase = autogenBuildDir + "/";
- rccOutBase += fpathCheckSum.getPart(absFile);
- rccOutBase += "/qrc_";
- rccOutBase +=
+ std::string rccBuildFile = autogenBuildDir + "/";
+ rccBuildFile += fpathCheckSum.getPart(absFile);
+ rccBuildFile += "/qrc_";
+ rccBuildFile +=
cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+ rccBuildFile += ".cpp";
// Register rcc ouput file as generated
- for (std::vector<std::string>::const_iterator it =
- suffixes.begin();
- it != suffixes.end(); ++it) {
- std::string rccOutCfg = rccOutBase;
- rccOutCfg += *it;
- rccOutCfg += ".cpp";
- AddGeneratedSource(makefile, rccOutCfg,
- cmQtAutoGeneratorCommon::RCC);
- autogenProvides.push_back(rccOutCfg);
- }
+ AddGeneratedSource(makefile, rccBuildFile,
+ cmQtAutoGeneratorCommon::RCC);
// Add rcc output file to origin target sources
- if (multiConfig) {
- target->AddSource(rccOutBase + "_$<CONFIG>.cpp");
- } else {
- target->AddSource(rccOutBase + ".cpp");
- }
+ target->AddSource(rccBuildFile);
+ // Register rcc ouput file as generated by the _autogen target
+ autogenProvides.push_back(rccBuildFile);
}
if (PropertyEnabled(sf, "GENERATED")) {
// Add generated qrc file to the dependencies
- autogenDepends.push_back(absFile);
+ autogenDependsSet.insert(absFile);
} else {
// Run cmake again when .qrc file changes
makefile->AddCMakeDependFile(absFile);
-
// Add the qrc input files to the dependencies
- std::string error;
- if (!cmQtAutoGeneratorCommon::RccListInputs(
- qtMajorVersion, rccCommand, absFile, autogenDepends,
- &error)) {
- cmSystemTools::Error(error.c_str());
+ {
+ std::string error;
+ std::vector<std::string> extraDepends;
+ if (cmQtAutoGeneratorCommon::RccListInputs(
+ qtMajorVersion, rccCommand, absFile, extraDepends,
+ &error)) {
+ autogenDependsSet.insert(extraDepends.begin(),
+ extraDepends.end());
+ } else {
+ cmSystemTools::Error(error.c_str());
+ }
}
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -940,10 +919,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
}
}
+ // Convert std::set to std::vector
+ const std::vector<std::string> autogenDepends(autogenDependsSet.begin(),
+ autogenDependsSet.end());
#if defined(_WIN32) && !defined(__CYGWIN__)
if (usePRE_BUILD) {
// If the autogen target depends on an other target don't use PRE_BUILD
- for (std::vector<std::string>::iterator it = autogenDepends.begin();
+ for (std::vector<std::string>::const_iterator it = autogenDepends.begin();
it != autogenDepends.end(); ++it) {
if (makefile->FindTargetToUse(*it) != CM_NULLPTR) {
usePRE_BUILD = false;
@@ -1014,7 +996,7 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
if (IsMultiConfig(target->GetGlobalGenerator())) {
for (std::vector<std::string>::const_iterator it = configs.begin();
it != configs.end(); ++it) {
- configSuffix[*it] = "_" + *it;
+ configSuffix[*it] = cmOutputConverter::EscapeForCMake("_" + *it);
}
}
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index feec735..bdf682a 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -366,6 +366,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
return false;
}
+ // -- Meta
+ InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix);
+
// - Old settings file
{
this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory);
@@ -375,9 +378,6 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
this->SettingsFile += ".cmake";
}
- // -- Meta
- InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix);
-
// - Files and directories
InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir);
InfoGet(makefile, "AM_CMAKE_BINARY_DIR", this->ProjectBinaryDir);
@@ -636,9 +636,7 @@ bool cmQtAutoGenerators::SettingsFileWrite()
void cmQtAutoGenerators::Init(cmMakefile* makefile)
{
// Mocs compilation file
- this->MocCompFileRel = "mocs_compilation";
- this->MocCompFileRel += this->ConfigSuffix;
- this->MocCompFileRel += ".cpp";
+ this->MocCompFileRel = "mocs_compilation.cpp";
this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath(
this->AutogenBuildDir, this->MocCompFileRel);
@@ -649,7 +647,9 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile)
// Moc predefs file
if (!this->MocPredefsCmd.empty()) {
- this->MocPredefsFileRel = "moc_predefs.h";
+ this->MocPredefsFileRel = "moc_predefs";
+ this->MocPredefsFileRel += this->ConfigSuffix;
+ this->MocPredefsFileRel += ".h";
this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath(
this->AutogenBuildDir, this->MocPredefsFileRel);
}
@@ -724,10 +724,10 @@ bool cmQtAutoGenerators::RunAutogen()
// the program goes through all .cpp files to see which moc files are
// included. It is not really interesting how the moc file is named, but
// what file the moc is created from. Once a moc is included the same moc
- // may not be included in the mocs_compilation_$<CONFIG>.cpp file anymore.
+ // may not be included in the mocs_compilation.cpp file anymore.
// OTOH if there's a header containing Q_OBJECT where no corresponding
// moc file is included anywhere a moc_<filename>.cpp file is created and
- // included in the mocs_compilation_$<CONFIG>.cpp file.
+ // included in the mocs_compilation.cpp file.
// key = moc source filepath, value = moc output filepath
std::map<std::string, std::string> mocsIncluded;
@@ -1664,10 +1664,10 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
{
bool rccGenerated = false;
bool generateRcc = this->RccSettingsChanged;
-
const std::string rccBuildFile =
cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile);
+ // Check if regeneration is required
if (!generateRcc) {
// Test if the resources list file is newer than build file
generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile);
@@ -1700,6 +1700,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
}
}
}
+ // Regenerate on demand
if (generateRcc) {
// Log
this->LogBold("Generating RCC source " + rccOutputFile);
@@ -1755,6 +1756,39 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
this->RccRunFailed = true;
}
}
+ // For a multi configuration generator generate a wrapper file
+ if (!this->ConfigSuffix.empty() && !this->RccRunFailed) {
+ // Wrapper file name
+ const std::string cppSuffix = ".cpp";
+ const size_t suffixLength = this->ConfigSuffix.size() + cppSuffix.size();
+ const std::string wrapperFileRel =
+ rccOutputFile.substr(0, rccOutputFile.size() - suffixLength) + cppSuffix;
+ const std::string wrapperFileAbs = cmSystemTools::CollapseCombinedPath(
+ this->AutogenBuildDir, wrapperFileRel);
+ // Wrapper file content
+ std::string content =
+ "// This is an autogenerated configuration wrapper file. Do not edit.\n"
+ "#include \"";
+ content += cmsys::SystemTools::GetFilenameName(rccBuildFile);
+ content += "\"\n";
+ // Write content to file
+ if (this->FileDiffers(wrapperFileAbs, content)) {
+ // Write new wrapper file if the content differs
+ this->LogBold("Generating RCC wrapper " + wrapperFileRel);
+ if (!this->FileWrite("AutoRcc", wrapperFileAbs, content)) {
+ // Error
+ rccGenerated = false;
+ this->RccRunFailed = true;
+ }
+ } else if (rccGenerated) {
+ // Only touch wrapper file if the content matches
+ if (this->Verbose) {
+ this->LogInfo("Touching RCC wrapper " + wrapperFileRel);
+ }
+ cmSystemTools::Touch(wrapperFileAbs, false);
+ }
+ }
+
return rccGenerated;
}
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 8ad4916..7a841a8 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -289,7 +289,9 @@ static bool testValue(cmState* state, const std::string& key,
std::string& value, const std::string& keyDescription,
std::string* errorMessage)
{
- const std::string cachedValue = std::string(state->GetCacheEntryValue(key));
+ const char* entry = state->GetCacheEntryValue(key);
+ const std::string cachedValue =
+ entry == nullptr ? std::string() : std::string(entry);
if (!cachedValue.empty() && !value.empty() && cachedValue != value) {
setErrorMessage(errorMessage, std::string("\"") + key +
"\" is set but incompatible with configured " +
diff --git a/Tests/AliasTarget/CMakeLists.txt b/Tests/AliasTarget/CMakeLists.txt
index e156420..fc70135 100644
--- a/Tests/AliasTarget/CMakeLists.txt
+++ b/Tests/AliasTarget/CMakeLists.txt
@@ -4,13 +4,6 @@ project(AliasTarget)
set(CMAKE_CXX_STANDARD 98)
-# Those versions of the HP compiler that need a flag to get proper C++98
-# template support also need a flag to use the newer C++ library.
-if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
- CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
- string(APPEND CMAKE_CXX_FLAGS " -AA")
-endif ()
-
# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 34418c5..13d796e 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1285,12 +1285,28 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5Autogen"
--force-new-ctest-process
--build-options ${build_options}
- -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=5
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ -DQT_TEST_VERSION=5
${QtAutogen_BUILD_OPTIONS}
--test-command ${run_autogen_test}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5Autogen")
+ add_test(NAME Qt5AutogenRerun COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/QtAutogenRerun"
+ "${CMake_BINARY_DIR}/Tests/Qt5AutogenRerun"
+ ${build_generator_args}
+ --build-project QtAutogenRerun
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5AutogenRerun"
+ --force-new-ctest-process
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ -DQT_TEST_VERSION=5
+ ${QtAutogen_BUILD_OPTIONS}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5AutogenRerun")
+
add_test(Qt5AutoUicInterface ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/QtAutoUicInterface"
@@ -1315,12 +1331,28 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Autogen"
--force-new-ctest-process
--build-options ${build_options}
- -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ -DQT_TEST_VERSION=4
${QtAutogen_BUILD_OPTIONS}
--test-command ${run_autogen_test}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Autogen")
+ add_test(NAME Qt4AutogenRerun COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/QtAutogenRerun"
+ "${CMake_BINARY_DIR}/Tests/Qt4AutogenRerun"
+ ${build_generator_args}
+ --build-project QtAutogenRerun
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4AutogenRerun"
+ --force-new-ctest-process
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ -DQT_TEST_VERSION=4
+ ${QtAutogen_BUILD_OPTIONS}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4AutogenRerun")
+
add_test(Qt4AutoUicInterface ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/QtAutoUicInterface"
@@ -1330,7 +1362,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface"
--force-new-ctest-process
--build-options ${build_options}
- -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ -DQT_TEST_VERSION=4
--test-command ${run_autouic_test}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface")
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index 8537cd9..2e41754 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -440,13 +440,6 @@ set(CMAKE_CXX_STANDARD 98)
#
set(CMAKE_CXX_EXTENSIONS TRUE)
-# Those versions of the HP compiler that need a flag to get proper C++98
-# template support also need a flag to use the newer C++ library.
-if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
- CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
- string(APPEND CMAKE_CXX_FLAGS " -AA")
-endif ()
-
# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index 4cd0bae..628cd4e 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -397,13 +397,6 @@ set(CMAKE_CXX_STANDARD 98)
#
set(CMAKE_CXX_EXTENSIONS TRUE)
-# Those versions of the HP compiler that need a flag to get proper C++98
-# template support also need a flag to use the newer C++ library.
-if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
- CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
- string(APPEND CMAKE_CXX_FLAGS " -AA")
-endif ()
-
# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt
index 9e2b4ab..227d990 100644
--- a/Tests/Plugin/CMakeLists.txt
+++ b/Tests/Plugin/CMakeLists.txt
@@ -28,13 +28,6 @@ include_directories(
${Plugin_SOURCE_DIR}/include
)
-# Those versions of the HP compiler that need a flag to get proper C++98
-# template support also need a flag to use the newer C++ library.
-if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
- CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
- string(APPEND CMAKE_CXX_FLAGS " -AA")
-endif ()
-
# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
diff --git a/Tests/QtAutoUicInterface/CMakeLists.txt b/Tests/QtAutoUicInterface/CMakeLists.txt
index 3ea1294..a5c2d99 100644
--- a/Tests/QtAutoUicInterface/CMakeLists.txt
+++ b/Tests/QtAutoUicInterface/CMakeLists.txt
@@ -53,8 +53,9 @@ set_property(TARGET KI18n APPEND PROPERTY
# END upstream
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
-set(INC_DIR "include_${CMAKE_BUILD_TYPE}" )
+get_property(_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_GENERATOR_IS_MULTI_CONFIG)
+set(INC_DIR "include_$<CONFIG>" )
else()
set(INC_DIR "include" )
endif()
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index b3e83fd..5064d26 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -2,13 +2,6 @@ cmake_minimum_required(VERSION 3.9)
cmake_policy(SET CMP0071 NEW)
project(QtAutogen)
-# Tell find_package(Qt5) where to find Qt.
-if(QT_QMAKE_EXECUTABLE)
- get_filename_component(Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
- get_filename_component(Qt_PREFIX_DIR "${Qt_BIN_DIR}" PATH)
- set(CMAKE_PREFIX_PATH ${Qt_PREFIX_DIR})
-endif()
-
if (QT_TEST_VERSION STREQUAL 4)
find_package(Qt4 REQUIRED)
@@ -108,132 +101,6 @@ set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE)
target_compile_features(no_link_language PRIVATE ${QT_COMPILE_FEATURES})
target_compile_features(empty PRIVATE ${QT_COMPILE_FEATURES})
-# -- Test
-# When a file listed in a .qrc file changes the target must be rebuilt
-set(timeformat "%Y%j%H%M%S")
-set(RCC_DEPENDS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends")
-set(RCC_DEPENDS_BIN "${CMAKE_CURRENT_BINARY_DIR}/rccDepends")
-configure_file(${RCC_DEPENDS_SRC}/res1a.qrc.in ${RCC_DEPENDS_BIN}/res1.qrc COPYONLY)
-configure_file(${RCC_DEPENDS_SRC}/res2a.qrc.in ${RCC_DEPENDS_BIN}/res2.qrc.in COPYONLY)
-try_compile(RCC_DEPENDS
- "${RCC_DEPENDS_BIN}"
- "${RCC_DEPENDS_SRC}"
- rccDepends
- CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
- "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
- "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
- OUTPUT_VARIABLE output
-)
-if (NOT RCC_DEPENDS)
- message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}")
-endif()
-# Get name and timestamp of the output binary
-file(STRINGS "${RCC_DEPENDS_BIN}/target.txt" targetList ENCODING UTF-8)
-list(GET targetList 0 rccDependsBin)
-file(TIMESTAMP "${rccDependsBin}" timeBegin "${timeformat}")
-# Sleep, touch regular qrc input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res1/input.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
- message(SEND_ERROR "Second build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep1 "${timeformat}")
-if (NOT timeStep1 GREATER timeBegin)
- message(SEND_ERROR "File (${rccDependsBin}) should have changed in the first step!")
-endif()
-# Sleep, update regular qrc file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-configure_file(${RCC_DEPENDS_SRC}/res1b.qrc.in ${RCC_DEPENDS_BIN}/res1.qrc COPYONLY)
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
- message(SEND_ERROR "Third build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep2 "${timeformat}")
-if (NOT timeStep2 GREATER timeStep1)
- message(SEND_ERROR "File (${rccDependsBin}) should have changed in the second step!")
-endif()
-# Sleep, touch regular qrc newly added input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res1/inputAdded.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
- message(SEND_ERROR "Fourth build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep3 "${timeformat}")
-if (NOT timeStep3 GREATER timeStep2)
- message(SEND_ERROR "File (${rccDependsBin}) should have changed in the third step!")
-endif()
-# Sleep, touch generated qrc input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res2/input.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
- message(SEND_ERROR "Fifth build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep4 "${timeformat}")
-if (NOT timeStep4 GREATER timeStep3)
- message(SEND_ERROR "File (${rccDependsBin}) should have changed in the fourth step!")
-endif()
-# Sleep, update generated qrc file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-configure_file(${RCC_DEPENDS_SRC}/res2b.qrc.in ${RCC_DEPENDS_BIN}/res2.qrc.in COPYONLY)
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
- message(SEND_ERROR "Sixth build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep5 "${timeformat}")
-if (NOT timeStep5 GREATER timeStep4)
- message(SEND_ERROR "File (${rccDependsBin}) should have changed in the fitfh step!")
-endif()
-# Sleep, touch generated qrc newly added input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res2/inputAdded.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
- message(SEND_ERROR "Seventh build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep6 "${timeformat}")
-if (NOT timeStep6 GREATER timeStep5)
- message(SEND_ERROR "File (${rccDependsBin}) should have changed in the sixth step!")
-endif()
-
-
-# -- Test
-# Ensure a repeated build succeeds when a header containing a QObject changes
-set(timeformat "%Y%j%H%M%S")
-configure_file(mocRerun/test1a.h.in mocRerun/test1.h COPYONLY)
-try_compile(MOC_RERUN
- "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
- "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun"
- mocRerun
- CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
- "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
- "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
- OUTPUT_VARIABLE output
-)
-if (NOT MOC_RERUN)
- message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}")
-endif()
-# Get name and timestamp of the output binary
-file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List ENCODING UTF-8)
-list(GET target1List 0 binFile)
-file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")
-# Change file content and rebuild
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY)
-execute_process(COMMAND "${CMAKE_COMMAND}" --build .
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
- RESULT_VARIABLE mocRerun_result
- )
-if (mocRerun_result)
- message(SEND_ERROR "Second build of mocRerun failed.")
-endif()
-# Compare timestamps
-file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
-if (NOT timeStep1 GREATER timeBegin)
- message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
-endif()
# -- Test
# Test for SKIP_AUTOMOC and SKIP_AUTOGEN on an AUTOMOC enabled target
@@ -322,76 +189,6 @@ if(ALLOW_WRAP_CPP)
endif()
# -- Test
-# Tests Q_PLUGIN_METADATA json file change detection
-if (NOT QT_TEST_VERSION STREQUAL 4)
- try_compile(MOC_PLUGIN
- "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin"
- "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin"
- mocPlugin
- CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
- "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
- OUTPUT_VARIABLE output
- )
- if (NOT MOC_PLUGIN)
- message(SEND_ERROR "Initial build of mocPlugin failed. Output: ${output}")
- endif()
-
- set(timeformat "%Y%j%H%M%S")
- set(mocPlugSrcDir "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin")
- set(mocPlugBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin")
- find_library(plAFile "PlugA" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
- find_library(plBFile "PlugB" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
- find_library(plCFile "PlugC" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
- find_library(plDFile "PlugD" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
-
- file(TIMESTAMP "${plAFile}" plABefore "${timeformat}")
- file(TIMESTAMP "${plBFile}" plBBefore "${timeformat}")
- file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
- file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
-
- # Ensure that the timestamp will change and change the json files
- execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
- configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC.json")
- configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD.json")
- execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
-
- file(TIMESTAMP "${plAFile}" plAAfter "${timeformat}")
- file(TIMESTAMP "${plBFile}" plBAfter "${timeformat}")
- file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
- file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
-
- if (plAAfter GREATER plABefore)
- message(SEND_ERROR "file (${plAFile}) should not have changed!")
- endif()
- if (plBAfter GREATER plBBefore)
- message(SEND_ERROR "file (${plBFile}) should not have changed!")
- endif()
- if (NOT plCAfter GREATER plCBefore)
- message(SEND_ERROR "file (${plCFile}) should have changed!")
- endif()
- if (NOT plDAfter GREATER plDBefore)
- message(SEND_ERROR "file (${plDFile}) should have changed!")
- endif()
-
- # Test custom macro
- file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
- file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
- execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
- configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC_Custom.json")
- configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD_Custom.json")
- execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
- file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
- file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
- if (NOT plCAfter GREATER plCBefore)
- message(SEND_ERROR "file (${plCFile}) should have changed!")
- endif()
- if (NOT plDAfter GREATER plDBefore)
- message(SEND_ERROR "file (${plDFile}) should have changed!")
- endif()
-
-endif()
-
-# -- Test
# Tests various .ui include directories
add_subdirectory(uicInclude)
diff --git a/Tests/QtAutogen/mocDepends/CMakeLists.txt b/Tests/QtAutogen/mocDepends/CMakeLists.txt
index cd5adf5..d71d740 100644
--- a/Tests/QtAutogen/mocDepends/CMakeLists.txt
+++ b/Tests/QtAutogen/mocDepends/CMakeLists.txt
@@ -16,31 +16,80 @@ endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR})
-# -- Test 1 using generated header
-# This tests the dependency of AUTOMOC of mocDepends1 to the generated object.hpp
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
- COMMAND ${CMAKE_COMMAND} -E sleep 3
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/object.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
- )
-
-add_executable(mocDepends1 test1.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/object.hpp
-)
+# -- Test 1: Depend on generated header
+# The ORIGIN_autogen target must depend on the same *GENERATED* source files as
+# the ORIGIN target. This is a requirement to ensure that all files for the
+# ORIGIN target are generated before the ORIGIN_autogen target is built.
+#
+# This tests the dependency of the mocDepends1_autogen target of mocDepends1
+# to the source file test1_object.hpp, which is *GENERATED* by a custom command.
+# If mocDepends1_autogen gets built *before* or in *parallel* to the
+# custom command, the build will fail. That's because test1_object.hpp,
+# which is required by mocDepends1_autogen, is only valid after the
+# custom command has been completed.
+#
+# The sleep seconds artificially increase the build time of the custom command
+# to simulate a slow file generation process that takes longer to run than
+# the build of the mocDepends1_autogen target.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test1_object.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/test1_object.hpp
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/object.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/test1_object.hpp)
+
+add_executable(mocDepends1 test1.cpp ${CMAKE_CURRENT_BINARY_DIR}/test1_object.hpp)
target_link_libraries(mocDepends1 ${QT_CORE_TARGET})
set_target_properties(mocDepends1 PROPERTIES AUTOMOC TRUE)
-# -- Test 2 using generated library
-# This tests the dependency of AUTOMOC of mocDepends2 to the
-# generated simpleLib.hpp which belongs to a linked library of mocDepends2
-add_custom_command(OUTPUT simpleLib.hpp simpleLib.cpp
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp
- COMMAND ${CMAKE_COMMAND} -E sleep 3
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.cpp
- )
-add_library(SimpleLib STATIC simpleLib.hpp simpleLib.cpp)
-
-add_executable(mocDepends2 test2.cpp )
-target_link_libraries(mocDepends2 SimpleLib ${QT_CORE_TARGET})
+# -- Test 2: Depend on header generating target
+# The ORIGIN_autogen target must depend on the same user defined targets
+# as the ORIGIN target. This is a requirement to ensure that all files for the
+# ORIGIN target are generated before the ORIGIN_autogen target is built.
+#
+# This tests the dependency of the mocDepends2_autogen target of mocDepends2
+# to the utility target mocDepends2Object. If mocDepends2_autogen gets built
+# *before* or in *parallel* to mocDepends2Object, the build will fail. That's
+# because test2_object.hpp, which is required by mocDepends2_autogen,
+# is only valid after the mocDepends2Object build has been completed.
+#
+# The sleep seconds artificially increase the build time of mocDepends2Object
+# to simulate a slow utility target build that takes longer to run than
+# the build of the mocDepends2_autogen target.
+add_custom_target(mocDepends2Object
+ BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/test2_object.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/test2_object.hpp
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/object.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/test2_object.hpp)
+
+add_executable(mocDepends2 test2.cpp)
+target_link_libraries(mocDepends2 ${QT_CORE_TARGET})
set_target_properties(mocDepends2 PROPERTIES AUTOMOC TRUE)
+add_dependencies(mocDepends2 mocDepends2Object)
+
+# -- Test 3: Depend on generated linked library
+# The ORIGIN_autogen target must depend on the same linked libraries
+# as the ORIGIN target. This is a requirement to ensure that all files for the
+# ORIGIN target are generated before the ORIGIN_autogen target is built.
+#
+# This tests the dependency of the mocDepends3_autogen target of mocDepends3
+# to the user generated library SimpleLib, which mocDepends3 links to.
+# If mocDepends3_autogen gets built *before* or in *parallel* to SimpleLib,
+# the build will fail. That's because simpleLib.hpp, which is required by
+# mocDepends3_autogen, is only valid after the SimpleLib build has been
+# completed.
+#
+# The sleep seconds artificially increase the build time of SimpleLib
+# to simulate a slow utility library build that takes longer to run than
+# the build of the mocDepends3_autogen target.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.cpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp
+ COMMAND ${CMAKE_COMMAND} -E sleep 3
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.cpp)
+add_library(SimpleLib STATIC ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.cpp)
+target_link_libraries(SimpleLib ${QT_CORE_TARGET})
+
+add_executable(mocDepends3 test3.cpp)
+target_link_libraries(mocDepends3 SimpleLib ${QT_CORE_TARGET})
+set_target_properties(mocDepends3 PROPERTIES AUTOMOC TRUE)
diff --git a/Tests/QtAutogen/mocDepends/simpleLib.hpp.in b/Tests/QtAutogen/mocDepends/simpleLib.hpp.in
index 758f1f6..b65b0cb 100644
--- a/Tests/QtAutogen/mocDepends/simpleLib.hpp.in
+++ b/Tests/QtAutogen/mocDepends/simpleLib.hpp.in
@@ -1,8 +1,11 @@
#ifndef SIMPLE_LIB_H
#define SIMPLE_LIB_H
-class SimpleLib
+#include <QObject>
+
+class SimpleLib : public QObject
{
+ Q_OBJECT
public:
SimpleLib();
~SimpleLib();
diff --git a/Tests/QtAutogen/mocDepends/test1.cpp b/Tests/QtAutogen/mocDepends/test1.cpp
index 92c259c..002dfd8 100644
--- a/Tests/QtAutogen/mocDepends/test1.cpp
+++ b/Tests/QtAutogen/mocDepends/test1.cpp
@@ -1,9 +1,8 @@
-#include "object.hpp"
+#include "test1_object.hpp"
int main()
{
Object obj;
-
return 0;
}
diff --git a/Tests/QtAutogen/mocDepends/test2.cpp b/Tests/QtAutogen/mocDepends/test2.cpp
index 155b19b..3fd845e 100644
--- a/Tests/QtAutogen/mocDepends/test2.cpp
+++ b/Tests/QtAutogen/mocDepends/test2.cpp
@@ -1,10 +1,9 @@
-#include "test2.hpp"
+#include "moc_test2_object.cpp"
+#include "test2_object.hpp"
int main()
{
- SimpleLib obj;
- LObject lobject;
-
+ Object obj;
return 0;
}
diff --git a/Tests/QtAutogen/mocDepends/test3.cpp b/Tests/QtAutogen/mocDepends/test3.cpp
new file mode 100644
index 0000000..a009598
--- /dev/null
+++ b/Tests/QtAutogen/mocDepends/test3.cpp
@@ -0,0 +1,12 @@
+
+#include "test3.hpp"
+
+int main()
+{
+ SimpleLib libObject;
+ LObject lobject;
+ return 0;
+}
+
+// AUTOMOC the SimpleLib header simpleLib.hpp
+#include "moc_simpleLib.cpp"
diff --git a/Tests/QtAutogen/mocDepends/test2.hpp b/Tests/QtAutogen/mocDepends/test3.hpp
index 0125f07..408335b 100644
--- a/Tests/QtAutogen/mocDepends/test2.hpp
+++ b/Tests/QtAutogen/mocDepends/test3.hpp
@@ -1,5 +1,5 @@
-#ifndef TEST2_HPP
-#define TEST2_HPP
+#ifndef TEST3_HPP
+#define TEST3_HPP
#include "simpleLib.hpp"
#include <QObject>
diff --git a/Tests/QtAutogen/mocInclude/shared.cmake b/Tests/QtAutogen/mocInclude/shared.cmake
index c426050..d05f27c 100644
--- a/Tests/QtAutogen/mocInclude/shared.cmake
+++ b/Tests/QtAutogen/mocInclude/shared.cmake
@@ -29,9 +29,11 @@ set_property(SOURCE ${CMAKE_CURRENT_BINARY_DIR}/SObjB.cpp PROPERTY SKIP_AUTOMOC
qtx_generate_moc(
${CMAKE_CURRENT_SOURCE_DIR}/../mocInclude/SObjCExtra.hpp
${CMAKE_CURRENT_BINARY_DIR}/SObjCExtra_extMoc.cpp)
-set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../mocInclude/SObjCExtra.hpp PROPERTY SKIP_AUTOMOC ON)
+set_property(
+ SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../mocInclude/SObjCExtra.hpp
+ PROPERTY SKIP_AUTOMOC ON)
# Custom target to depend on
-set(SOBJC_MOC ${CMAKE_CURRENT_BINARY_DIR}/${MOC_INCLUDE_NAME}_autogen/include/moc_SObjCExtra.cpp)
+set(SOBJC_MOC ${CMAKE_CURRENT_BINARY_DIR}/moc_SObjCExtra.cpp)
add_custom_target("${MOC_INCLUDE_NAME}_SOBJC"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SObjCExtra_extMoc.cpp
BYPRODUCTS ${SOBJC_MOC}
diff --git a/Tests/QtAutogenRerun/CMakeLists.txt b/Tests/QtAutogenRerun/CMakeLists.txt
new file mode 100644
index 0000000..088025f
--- /dev/null
+++ b/Tests/QtAutogenRerun/CMakeLists.txt
@@ -0,0 +1,239 @@
+cmake_minimum_required(VERSION 3.9)
+cmake_policy(SET CMP0071 NEW)
+project(QtAutogenRerun)
+
+# Tell find_package(Qt5) where to find Qt.
+if(QT_QMAKE_EXECUTABLE)
+ get_filename_component(Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
+ get_filename_component(Qt_PREFIX_DIR "${Qt_BIN_DIR}" PATH)
+ set(CMAKE_PREFIX_PATH ${Qt_PREFIX_DIR})
+endif()
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+
+ # Include this directory before using the UseQt4 file.
+ add_subdirectory(defines_test)
+
+ include(UseQt4)
+
+ set(QT_QTCORE_TARGET Qt4::QtCore)
+
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+ find_package(Qt5Widgets REQUIRED)
+
+ set(QT_QTCORE_TARGET Qt5::Core)
+
+ include_directories(${Qt5Widgets_INCLUDE_DIRS})
+ set(QT_LIBRARIES Qt5::Widgets)
+
+ if(Qt5_POSITION_INDEPENDENT_CODE AND CMAKE_CXX_COMPILE_OPTIONS_PIC)
+ add_definitions(${CMAKE_CXX_COMPILE_OPTIONS_PIC})
+ endif()
+
+endif()
+
+# -- Test
+# Dummy test to generate clean target
+add_executable(dummy dummy.cpp)
+
+# -- Test
+# When a file listed in a .qrc file changes the target must be rebuilt
+set(timeformat "%Y%j%H%M%S")
+set(RCC_DEPENDS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends")
+set(RCC_DEPENDS_BIN "${CMAKE_CURRENT_BINARY_DIR}/rccDepends")
+configure_file(${RCC_DEPENDS_SRC}/res1a.qrc.in ${RCC_DEPENDS_BIN}/res1.qrc COPYONLY)
+configure_file(${RCC_DEPENDS_SRC}/res2a.qrc.in ${RCC_DEPENDS_BIN}/res2.qrc.in COPYONLY)
+try_compile(RCC_DEPENDS
+ "${RCC_DEPENDS_BIN}"
+ "${RCC_DEPENDS_SRC}"
+ rccDepends
+ CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+ "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+ OUTPUT_VARIABLE output
+)
+if (NOT RCC_DEPENDS)
+ message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}")
+endif()
+# Get name and timestamp of the output binary
+file(STRINGS "${RCC_DEPENDS_BIN}/target.txt" targetList ENCODING UTF-8)
+list(GET targetList 0 rccDependsBin)
+file(TIMESTAMP "${rccDependsBin}" timeBegin "${timeformat}")
+# Sleep, touch regular qrc input file, rebuild and compare timestamp
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res1/input.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
+if (result)
+ message(SEND_ERROR "Second build of rccDepends failed.")
+endif()
+file(TIMESTAMP "${rccDependsBin}" timeStep1 "${timeformat}")
+if (NOT timeStep1 GREATER timeBegin)
+ message(SEND_ERROR "File (${rccDependsBin}) should have changed in the first step!")
+endif()
+# Sleep, update regular qrc file, rebuild and compare timestamp
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+configure_file(${RCC_DEPENDS_SRC}/res1b.qrc.in ${RCC_DEPENDS_BIN}/res1.qrc COPYONLY)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
+if (result)
+ message(SEND_ERROR "Third build of rccDepends failed.")
+endif()
+file(TIMESTAMP "${rccDependsBin}" timeStep2 "${timeformat}")
+if (NOT timeStep2 GREATER timeStep1)
+ message(SEND_ERROR "File (${rccDependsBin}) should have changed in the second step!")
+endif()
+# Sleep, touch regular qrc newly added input file, rebuild and compare timestamp
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res1/inputAdded.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
+if (result)
+ message(SEND_ERROR "Fourth build of rccDepends failed.")
+endif()
+file(TIMESTAMP "${rccDependsBin}" timeStep3 "${timeformat}")
+if (NOT timeStep3 GREATER timeStep2)
+ message(SEND_ERROR "File (${rccDependsBin}) should have changed in the third step!")
+endif()
+# Sleep, touch generated qrc input file, rebuild and compare timestamp
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res2/input.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
+if (result)
+ message(SEND_ERROR "Fifth build of rccDepends failed.")
+endif()
+file(TIMESTAMP "${rccDependsBin}" timeStep4 "${timeformat}")
+if (NOT timeStep4 GREATER timeStep3)
+ message(SEND_ERROR "File (${rccDependsBin}) should have changed in the fourth step!")
+endif()
+# Sleep, update generated qrc file, rebuild and compare timestamp
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+configure_file(${RCC_DEPENDS_SRC}/res2b.qrc.in ${RCC_DEPENDS_BIN}/res2.qrc.in COPYONLY)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
+if (result)
+ message(SEND_ERROR "Sixth build of rccDepends failed.")
+endif()
+file(TIMESTAMP "${rccDependsBin}" timeStep5 "${timeformat}")
+if (NOT timeStep5 GREATER timeStep4)
+ message(SEND_ERROR "File (${rccDependsBin}) should have changed in the fitfh step!")
+endif()
+# Sleep, touch generated qrc newly added input file, rebuild and compare timestamp
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res2/inputAdded.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
+if (result)
+ message(SEND_ERROR "Seventh build of rccDepends failed.")
+endif()
+file(TIMESTAMP "${rccDependsBin}" timeStep6 "${timeformat}")
+if (NOT timeStep6 GREATER timeStep5)
+ message(SEND_ERROR "File (${rccDependsBin}) should have changed in the sixth step!")
+endif()
+
+
+# -- Test
+# Ensure a repeated build succeeds when a header containing a QObject changes
+set(timeformat "%Y%j%H%M%S")
+configure_file(mocRerun/test1a.h.in mocRerun/test1.h COPYONLY)
+try_compile(MOC_RERUN
+ "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
+ "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun"
+ mocRerun
+ CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+ "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+ OUTPUT_VARIABLE output
+)
+if (NOT MOC_RERUN)
+ message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}")
+endif()
+# Get name and timestamp of the output binary
+file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List ENCODING UTF-8)
+list(GET target1List 0 binFile)
+file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")
+# Change file content and rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build .
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
+ RESULT_VARIABLE mocRerun_result
+ )
+if (mocRerun_result)
+ message(SEND_ERROR "Second build of mocRerun failed.")
+endif()
+# Compare timestamps
+file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
+if (NOT timeStep1 GREATER timeBegin)
+ message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
+endif()
+
+
+# -- Test
+# Tests Q_PLUGIN_METADATA json file change detection
+if (NOT QT_TEST_VERSION STREQUAL 4)
+ try_compile(MOC_PLUGIN
+ "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin"
+ "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin"
+ mocPlugin
+ CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+ OUTPUT_VARIABLE output
+ )
+ if (NOT MOC_PLUGIN)
+ message(SEND_ERROR "Initial build of mocPlugin failed. Output: ${output}")
+ endif()
+
+ set(timeformat "%Y%j%H%M%S")
+ set(mocPlugSrcDir "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin")
+ set(mocPlugBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin")
+ find_library(plAFile "PlugA" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+ find_library(plBFile "PlugB" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+ find_library(plCFile "PlugC" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+ find_library(plDFile "PlugD" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+
+ file(TIMESTAMP "${plAFile}" plABefore "${timeformat}")
+ file(TIMESTAMP "${plBFile}" plBBefore "${timeformat}")
+ file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
+ file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
+
+ # Ensure that the timestamp will change and change the json files
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+ configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC.json")
+ configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD.json")
+ execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
+
+ file(TIMESTAMP "${plAFile}" plAAfter "${timeformat}")
+ file(TIMESTAMP "${plBFile}" plBAfter "${timeformat}")
+ file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
+ file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
+
+ if (plAAfter GREATER plABefore)
+ message(SEND_ERROR "file (${plAFile}) should not have changed!")
+ endif()
+ if (plBAfter GREATER plBBefore)
+ message(SEND_ERROR "file (${plBFile}) should not have changed!")
+ endif()
+ if (NOT plCAfter GREATER plCBefore)
+ message(SEND_ERROR "file (${plCFile}) should have changed!")
+ endif()
+ if (NOT plDAfter GREATER plDBefore)
+ message(SEND_ERROR "file (${plDFile}) should have changed!")
+ endif()
+
+ # Test custom macro
+ file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
+ file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+ configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC_Custom.json")
+ configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD_Custom.json")
+ execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
+ file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
+ file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
+ if (NOT plCAfter GREATER plCBefore)
+ message(SEND_ERROR "file (${plCFile}) should have changed!")
+ endif()
+ if (NOT plDAfter GREATER plDBefore)
+ message(SEND_ERROR "file (${plDFile}) should have changed!")
+ endif()
+
+endif()
diff --git a/Tests/QtAutogenRerun/defines_test/CMakeLists.txt b/Tests/QtAutogenRerun/defines_test/CMakeLists.txt
new file mode 100644
index 0000000..9ee9a22
--- /dev/null
+++ b/Tests/QtAutogenRerun/defines_test/CMakeLists.txt
@@ -0,0 +1,4 @@
+
+add_executable(defines_test defines_test.cpp)
+set_target_properties(defines_test PROPERTIES AUTOMOC TRUE)
+target_link_libraries(defines_test Qt4::QtGui)
diff --git a/Tests/QtAutogenRerun/defines_test/defines_test.cpp b/Tests/QtAutogenRerun/defines_test/defines_test.cpp
new file mode 100644
index 0000000..cf4e9cb
--- /dev/null
+++ b/Tests/QtAutogenRerun/defines_test/defines_test.cpp
@@ -0,0 +1,38 @@
+
+#include <QObject>
+
+#ifdef QT_GUI_LIB
+#include <QTextDocument>
+
+class SomeDocument : public QTextDocument
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void someSig();
+};
+#endif
+
+#ifdef QT_CORE_LIB
+class SomeObject : public QObject
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void someSig();
+};
+#endif
+
+int main(int argc, char** argv)
+{
+#ifdef QT_CORE_LIB
+ QMetaObject sosmo = SomeObject::staticMetaObject;
+#endif
+#ifdef QT_GUI_LIB
+ QMetaObject sdsmo = SomeDocument::staticMetaObject;
+#endif
+
+ return 0;
+}
+
+#include "defines_test.moc"
diff --git a/Tests/QtAutogenRerun/dummy.cpp b/Tests/QtAutogenRerun/dummy.cpp
new file mode 100644
index 0000000..4837a76
--- /dev/null
+++ b/Tests/QtAutogenRerun/dummy.cpp
@@ -0,0 +1,5 @@
+
+int main(int argv, char** args)
+{
+ return 0;
+}
diff --git a/Tests/QtAutogen/mocPlugin/CMakeLists.txt b/Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt
index 9b224fb..9b224fb 100644
--- a/Tests/QtAutogen/mocPlugin/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt
diff --git a/Tests/QtAutogen/mocPlugin/StyleA.cpp b/Tests/QtAutogenRerun/mocPlugin/StyleA.cpp
index b5e8753..b5e8753 100644
--- a/Tests/QtAutogen/mocPlugin/StyleA.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleA.cpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleA.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleA.hpp
index 1b6154d..1b6154d 100644
--- a/Tests/QtAutogen/mocPlugin/StyleA.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleA.hpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleA.json b/Tests/QtAutogenRerun/mocPlugin/StyleA.json
index cc33953..cc33953 100644
--- a/Tests/QtAutogen/mocPlugin/StyleA.json
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleA.json
diff --git a/Tests/QtAutogen/mocPlugin/StyleA_Custom.json b/Tests/QtAutogenRerun/mocPlugin/StyleA_Custom.json
index cc33953..cc33953 100644
--- a/Tests/QtAutogen/mocPlugin/StyleA_Custom.json
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleA_Custom.json
diff --git a/Tests/QtAutogen/mocPlugin/StyleB.cpp b/Tests/QtAutogenRerun/mocPlugin/StyleB.cpp
index 17d4400..17d4400 100644
--- a/Tests/QtAutogen/mocPlugin/StyleB.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleB.cpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleB.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleB.hpp
index 163c9b2..163c9b2 100644
--- a/Tests/QtAutogen/mocPlugin/StyleB.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleB.hpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleC.cpp b/Tests/QtAutogenRerun/mocPlugin/StyleC.cpp
index 37e7564..37e7564 100644
--- a/Tests/QtAutogen/mocPlugin/StyleC.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleC.cpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleC.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleC.hpp
index 52a887a..52a887a 100644
--- a/Tests/QtAutogen/mocPlugin/StyleC.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleC.hpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleCommon.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleCommon.hpp
index f1a7ec6..f1a7ec6 100644
--- a/Tests/QtAutogen/mocPlugin/StyleCommon.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleCommon.hpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleD.cpp b/Tests/QtAutogenRerun/mocPlugin/StyleD.cpp
index 7e4b121..7e4b121 100644
--- a/Tests/QtAutogen/mocPlugin/StyleD.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleD.cpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleD.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleD.hpp
index df8a439..df8a439 100644
--- a/Tests/QtAutogen/mocPlugin/StyleD.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleD.hpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleE.cpp b/Tests/QtAutogenRerun/mocPlugin/StyleE.cpp
index 8fc9a7f..8fc9a7f 100644
--- a/Tests/QtAutogen/mocPlugin/StyleE.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleE.cpp
diff --git a/Tests/QtAutogen/mocPlugin/StyleE.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleE.hpp
index e7915a8..e7915a8 100644
--- a/Tests/QtAutogen/mocPlugin/StyleE.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleE.hpp
diff --git a/Tests/QtAutogen/mocPlugin/jsonIn/StyleB.json b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json
index 129cac4..129cac4 100644
--- a/Tests/QtAutogen/mocPlugin/jsonIn/StyleB.json
+++ b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json
diff --git a/Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB_Custom.json
index 129cac4..129cac4 100644
--- a/Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json
+++ b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB_Custom.json
diff --git a/Tests/QtAutogen/mocPlugin/jsonIn/StyleC.json b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleC.json
index 119aaa4..119aaa4 100644
--- a/Tests/QtAutogen/mocPlugin/jsonIn/StyleC.json
+++ b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleC.json
diff --git a/Tests/QtAutogen/mocPlugin/jsonIn/StyleD.json b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleD.json
index 732c547..732c547 100644
--- a/Tests/QtAutogen/mocPlugin/jsonIn/StyleD.json
+++ b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleD.json
diff --git a/Tests/QtAutogen/mocPlugin/main.cpp b/Tests/QtAutogenRerun/mocPlugin/main.cpp
index 3ba2ddc..3ba2ddc 100644
--- a/Tests/QtAutogen/mocPlugin/main.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/main.cpp
diff --git a/Tests/QtAutogen/mocRerun/CMakeLists.txt b/Tests/QtAutogenRerun/mocRerun/CMakeLists.txt
index 7380bdd..7380bdd 100644
--- a/Tests/QtAutogen/mocRerun/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/mocRerun/CMakeLists.txt
diff --git a/Tests/QtAutogen/mocRerun/input.txt b/Tests/QtAutogenRerun/mocRerun/input.txt
index da62762..da62762 100644
--- a/Tests/QtAutogen/mocRerun/input.txt
+++ b/Tests/QtAutogenRerun/mocRerun/input.txt
diff --git a/Tests/QtAutogen/mocRerun/main.cpp.in b/Tests/QtAutogenRerun/mocRerun/main.cpp.in
index b37ff61..b37ff61 100644
--- a/Tests/QtAutogen/mocRerun/main.cpp.in
+++ b/Tests/QtAutogenRerun/mocRerun/main.cpp.in
diff --git a/Tests/QtAutogen/mocRerun/res1.qrc b/Tests/QtAutogenRerun/mocRerun/res1.qrc
index fb804b5..fb804b5 100644
--- a/Tests/QtAutogen/mocRerun/res1.qrc
+++ b/Tests/QtAutogenRerun/mocRerun/res1.qrc
diff --git a/Tests/QtAutogen/mocRerun/test1a.h.in b/Tests/QtAutogenRerun/mocRerun/test1a.h.in
index a335046..a335046 100644
--- a/Tests/QtAutogen/mocRerun/test1a.h.in
+++ b/Tests/QtAutogenRerun/mocRerun/test1a.h.in
diff --git a/Tests/QtAutogen/mocRerun/test1b.h.in b/Tests/QtAutogenRerun/mocRerun/test1b.h.in
index 6128eeb..6128eeb 100644
--- a/Tests/QtAutogen/mocRerun/test1b.h.in
+++ b/Tests/QtAutogenRerun/mocRerun/test1b.h.in
diff --git a/Tests/QtAutogen/rccDepends/CMakeLists.txt b/Tests/QtAutogenRerun/rccDepends/CMakeLists.txt
index edc0ac3..edc0ac3 100644
--- a/Tests/QtAutogen/rccDepends/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/rccDepends/CMakeLists.txt
diff --git a/Tests/QtAutogen/rccDepends/main.cpp b/Tests/QtAutogenRerun/rccDepends/main.cpp
index 766b775..766b775 100644
--- a/Tests/QtAutogen/rccDepends/main.cpp
+++ b/Tests/QtAutogenRerun/rccDepends/main.cpp
diff --git a/Tests/QtAutogen/rccDepends/res/input1.txt.in b/Tests/QtAutogenRerun/rccDepends/res/input1.txt.in
index da62762..da62762 100644
--- a/Tests/QtAutogen/rccDepends/res/input1.txt.in
+++ b/Tests/QtAutogenRerun/rccDepends/res/input1.txt.in
diff --git a/Tests/QtAutogen/rccDepends/res/input2.txt.in b/Tests/QtAutogenRerun/rccDepends/res/input2.txt.in
index 08e14b7..08e14b7 100644
--- a/Tests/QtAutogen/rccDepends/res/input2.txt.in
+++ b/Tests/QtAutogenRerun/rccDepends/res/input2.txt.in
diff --git a/Tests/QtAutogen/rccDepends/res1a.qrc.in b/Tests/QtAutogenRerun/rccDepends/res1a.qrc.in
index d111ffb..d111ffb 100644
--- a/Tests/QtAutogen/rccDepends/res1a.qrc.in
+++ b/Tests/QtAutogenRerun/rccDepends/res1a.qrc.in
diff --git a/Tests/QtAutogen/rccDepends/res1b.qrc.in b/Tests/QtAutogenRerun/rccDepends/res1b.qrc.in
index 4cb3f04..4cb3f04 100644
--- a/Tests/QtAutogen/rccDepends/res1b.qrc.in
+++ b/Tests/QtAutogenRerun/rccDepends/res1b.qrc.in
diff --git a/Tests/QtAutogen/rccDepends/res2a.qrc.in b/Tests/QtAutogenRerun/rccDepends/res2a.qrc.in
index 19f34ac..19f34ac 100644
--- a/Tests/QtAutogen/rccDepends/res2a.qrc.in
+++ b/Tests/QtAutogenRerun/rccDepends/res2a.qrc.in
diff --git a/Tests/QtAutogen/rccDepends/res2b.qrc.in b/Tests/QtAutogenRerun/rccDepends/res2b.qrc.in
index 19e8ba1..19e8ba1 100644
--- a/Tests/QtAutogen/rccDepends/res2b.qrc.in
+++ b/Tests/QtAutogenRerun/rccDepends/res2b.qrc.in
diff --git a/Tests/RunCMake/GenerateExportHeader/GEH.cmake b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
index e0677a7..cfca8fe 100644
--- a/Tests/RunCMake/GenerateExportHeader/GEH.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
@@ -45,13 +45,6 @@ include(GenerateExportHeader)
set(CMAKE_CXX_STANDARD 98)
-# Those versions of the HP compiler that need a flag to get proper C++98
-# template support also need a flag to use the newer C++ library.
-if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
- CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
- string(APPEND CMAKE_CXX_FLAGS " -AA")
-endif ()
-
# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
index 789b4d0..c8b124a 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
@@ -3,8 +3,8 @@ CMake Error at COMPILE_LANGUAGE-add_custom_command.cmake:6 \(add_custom_command\
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
index 400fbc0..e8cefc7 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
@@ -3,8 +3,8 @@ CMake Error at COMPILE_LANGUAGE-add_custom_target.cmake:4 \(add_custom_target\):
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
index e45bb02..7fa1f25 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
@@ -3,8 +3,8 @@ CMake Error at COMPILE_LANGUAGE-add_executable.cmake:4 \(add_executable\):
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
index c9ee6fe..ee60b58 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
@@ -3,8 +3,8 @@ CMake Error at COMPILE_LANGUAGE-add_library.cmake:4 \(add_library\):
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
index 9955f5d..fd8a731 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
@@ -3,8 +3,8 @@ CMake Error at COMPILE_LANGUAGE-add_test.cmake:5 \(add_test\):
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
index eca700f..bef7f63 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
@@ -3,6 +3,6 @@ CMake Error:
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
index 2d324e2..687d9b7 100644
--- a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
@@ -3,8 +3,8 @@ CMake Error at COMPILE_LANGUAGE-target_sources.cmake:5 \(target_sources\):
\$<COMPILE_LANGUAGE>
- \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
- compile definitions, compile options and to evaluate components of the
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories,
+ compile definitions, compile options, and to evaluate components of the
file\(GENERATE\) command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/PackageRoot-stderr.txt b/Tests/RunCMake/find_package/PackageRoot-stderr.txt
index 409fa89..d97c029 100644
--- a/Tests/RunCMake/find_package/PackageRoot-stderr.txt
+++ b/Tests/RunCMake/find_package/PackageRoot-stderr.txt
@@ -1,383 +1,43 @@
+----------
Foo_ROOT :
ENV{Foo_ROOT} :
+
+find_package\(Foo\)
FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
FOO_TEST_FILE_ZOT :FOO_TEST_FILE_ZOT-NOTFOUND
FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
FOO_TEST_PATH_ZOT :FOO_TEST_PATH_ZOT-NOTFOUND
FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-Foo_ROOT :
-ENV{Foo_ROOT} :
-Bar_ROOT :
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND
-BAR_TEST_FILE_BAR :BAR_TEST_FILE_BAR-NOTFOUND
-BAR_TEST_FILE_ZOT :BAR_TEST_FILE_ZOT-NOTFOUND
-BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND
-BAR_TEST_PATH_BAR :BAR_TEST_PATH_BAR-NOTFOUND
-BAR_TEST_PATH_ZOT :BAR_TEST_PATH_ZOT-NOTFOUND
-BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_PROG_BAR :BAR_TEST_PROG_BAR-NOTFOUND
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
-Bar_ROOT :
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/foo/env_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/foo/env_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/foo/env_root/bin/bar.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-
-Foo_ROOT :
-ENV{Foo_ROOT} :
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-
-Foo_ROOT :
-ENV{Foo_ROOT} :
-Bar_ROOT :
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-
-Foo_ROOT :
-ENV{Foo_ROOT} :
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
-FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
-FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-
+----------
Foo_ROOT :.*/PackageRoot/foo/cmake_root
ENV{Foo_ROOT} :
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
+find_package\(Foo\)
FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
-Bar_ROOT :
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
-
+----------
Foo_ROOT :
ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-Foo_ROOT :
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+find_package\(Foo\)
FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/env_root/include/zot/zot.h
FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/env_root/include/zot
FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+----------
Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-
-Foo_ROOT :
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-
-Foo_ROOT :
ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
+find_package\(Foo\)
FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-
-Foo_ROOT :.*/PackageRoot/foo/cmake_root
-ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root
-Bar_ROOT :.*/PackageRoot/bar/cmake_root
-ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
-FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
-BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
-BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
-BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
-BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
-BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
-BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
-BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
diff --git a/Tests/RunCMake/find_package/PackageRoot.cmake b/Tests/RunCMake/find_package/PackageRoot.cmake
index 421c243..39551c4 100644
--- a/Tests/RunCMake/find_package/PackageRoot.cmake
+++ b/Tests/RunCMake/find_package/PackageRoot.cmake
@@ -5,73 +5,33 @@ set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
macro(CleanUpPackageRootTest)
unset(Foo_ROOT)
unset(ENV{Foo_ROOT})
- unset(Bar_ROOT)
- unset(ENV{Bar_ROOT})
unset(FOO_TEST_FILE_FOO)
+ unset(FOO_TEST_FILE_ZOT)
unset(FOO_TEST_PATH_FOO)
+ unset(FOO_TEST_PATH_ZOT)
unset(FOO_TEST_PROG_FOO)
- unset(BAR_TEST_FILE_FOO)
- unset(BAR_TEST_FILE_BAR)
- unset(BAR_TEST_PATH_FOO)
- unset(BAR_TEST_PATH_BAR)
- unset(BAR_TEST_PROG_FOO)
- unset(BAR_TEST_PROG_BAR)
unset(FOO_TEST_FILE_FOO CACHE)
+ unset(FOO_TEST_FILE_ZOT CACHE)
unset(FOO_TEST_PATH_FOO CACHE)
+ unset(FOO_TEST_PATH_ZOT CACHE)
unset(FOO_TEST_PROG_FOO CACHE)
- unset(BAR_TEST_FILE_FOO CACHE)
- unset(BAR_TEST_FILE_BAR CACHE)
- unset(BAR_TEST_PATH_FOO CACHE)
- unset(BAR_TEST_PATH_BAR CACHE)
- unset(BAR_TEST_PROG_FOO CACHE)
- unset(BAR_TEST_PROG_BAR CACHE)
endmacro()
macro(RunPackageRootTest)
- set(orig_foo_cmake_root ${Foo_ROOT})
- set(orig_foo_env_root $ENV{Foo_ROOT})
- set(orig_bar_cmake_root ${Bar_ROOT})
- set(orig_bar_env_root $ENV{Bar_ROOT})
-
- find_package(Foo)
+ message("----------")
message("Foo_ROOT :${Foo_ROOT}")
message("ENV{Foo_ROOT} :$ENV{Foo_ROOT}")
- message("FOO_TEST_FILE_FOO :${FOO_TEST_FILE_FOO}")
- message("FOO_TEST_FILE_ZOT :${FOO_TEST_FILE_ZOT}")
- message("FOO_TEST_PATH_FOO :${FOO_TEST_PATH_FOO}")
- message("FOO_TEST_PATH_ZOT :${FOO_TEST_PATH_ZOT}")
- message("FOO_TEST_PROG_FOO :${FOO_TEST_PROG_FOO}")
- CleanUpPackageRootTest()
message("")
- set(Foo_ROOT ${orig_foo_cmake_root})
- set(ENV{Foo_ROOT} ${orig_foo_env_root})
- set(Bar_ROOT ${orig_bar_cmake_root})
- set(ENV{Bar_ROOT} ${orig_bar_env_root})
-
- find_package(Foo COMPONENTS Bar)
- message("Foo_ROOT :${Foo_ROOT}")
- message("ENV{Foo_ROOT} :$ENV{Foo_ROOT}")
- message("Bar_ROOT :${Bar_ROOT}")
- message("ENV{Bar_ROOT} :$ENV{Bar_ROOT}")
+ find_package(Foo)
+ message("find_package(Foo)")
message("FOO_TEST_FILE_FOO :${FOO_TEST_FILE_FOO}")
+ message("FOO_TEST_FILE_ZOT :${FOO_TEST_FILE_ZOT}")
message("FOO_TEST_PATH_FOO :${FOO_TEST_PATH_FOO}")
+ message("FOO_TEST_PATH_ZOT :${FOO_TEST_PATH_ZOT}")
message("FOO_TEST_PROG_FOO :${FOO_TEST_PROG_FOO}")
- message("BAR_TEST_FILE_FOO :${BAR_TEST_FILE_FOO}")
- message("BAR_TEST_FILE_BAR :${BAR_TEST_FILE_BAR}")
- message("BAR_TEST_FILE_ZOT :${BAR_TEST_FILE_ZOT}")
- message("BAR_TEST_PATH_FOO :${BAR_TEST_PATH_FOO}")
- message("BAR_TEST_PATH_BAR :${BAR_TEST_PATH_BAR}")
- message("BAR_TEST_PATH_ZOT :${BAR_TEST_PATH_ZOT}")
- message("BAR_TEST_PROG_FOO :${BAR_TEST_PROG_FOO}")
- message("BAR_TEST_PROG_BAR :${BAR_TEST_PROG_BAR}")
CleanUpPackageRootTest()
message("")
-
- unset(orig_foo_cmake_root)
- unset(orig_foo_env_root)
- unset(orig_bar_cmake_root)
- unset(orig_bar_env_root)
endmacro()
RunPackageRootTest()
@@ -85,63 +45,3 @@ RunPackageRootTest()
set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
RunPackageRootTest()
-
-##
-
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-RunPackageRootTest()
-
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-##
-
-set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-RunPackageRootTest()
-
-set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-RunPackageRootTest()
-
-set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
-set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-RunPackageRootTest()
-
-##
-
-set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
-set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-##
-
-set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
-
-set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
-set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
-set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
-set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
-RunPackageRootTest()
diff --git a/Tests/RunCMake/find_package/PackageRoot/BarConfig.cmake b/Tests/RunCMake/find_package/PackageRoot/BarConfig.cmake
new file mode 100644
index 0000000..9eaf386
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRoot/BarConfig.cmake
@@ -0,0 +1,9 @@
+set(BAR_CMAKE_FILE ${CMAKE_CURRENT_LIST_FILE} CACHE FILEPATH "")
+find_file(BAR_TEST_FILE_FOO foo.h)
+find_file(BAR_TEST_FILE_BAR bar.h)
+find_file(BAR_TEST_FILE_ZOT zot.h PATH_SUFFIXES zot)
+find_path(BAR_TEST_PATH_FOO foo.h)
+find_path(BAR_TEST_PATH_BAR bar.h)
+find_path(BAR_TEST_PATH_ZOT zot.h PATH_SUFFIXES zot)
+find_program(BAR_TEST_PROG_FOO foo.exe)
+find_program(BAR_TEST_PROG_BAR bar.exe)
diff --git a/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake b/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake
index 72774a7..9eaf386 100644
--- a/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake
+++ b/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake
@@ -1,3 +1,4 @@
+set(BAR_CMAKE_FILE ${CMAKE_CURRENT_LIST_FILE} CACHE FILEPATH "")
find_file(BAR_TEST_FILE_FOO foo.h)
find_file(BAR_TEST_FILE_BAR bar.h)
find_file(BAR_TEST_FILE_ZOT zot.h PATH_SUFFIXES zot)
diff --git a/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake b/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake
index e160a1d..b929c2a 100644
--- a/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake
+++ b/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake
@@ -4,6 +4,8 @@ find_path(FOO_TEST_PATH_FOO foo.h)
find_path(FOO_TEST_PATH_ZOT zot.h PATH_SUFFIXES zot)
find_program(FOO_TEST_PROG_FOO foo.exe)
-if ("Bar" IN_LIST Foo_FIND_COMPONENTS)
+if ("BarModule" IN_LIST Foo_FIND_COMPONENTS)
find_package(Bar)
+elseif ("BarConfig" IN_LIST Foo_FIND_COMPONENTS)
+ find_package(Bar CONFIG)
endif ()
diff --git a/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake b/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
new file mode 100644
index 0000000..9eaf386
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
@@ -0,0 +1,9 @@
+set(BAR_CMAKE_FILE ${CMAKE_CURRENT_LIST_FILE} CACHE FILEPATH "")
+find_file(BAR_TEST_FILE_FOO foo.h)
+find_file(BAR_TEST_FILE_BAR bar.h)
+find_file(BAR_TEST_FILE_ZOT zot.h PATH_SUFFIXES zot)
+find_path(BAR_TEST_PATH_FOO foo.h)
+find_path(BAR_TEST_PATH_BAR bar.h)
+find_path(BAR_TEST_PATH_ZOT zot.h PATH_SUFFIXES zot)
+find_program(BAR_TEST_PROG_FOO foo.exe)
+find_program(BAR_TEST_PROG_BAR bar.exe)
diff --git a/Tests/RunCMake/find_package/PackageRoot/foo/env_root/cmake/BarConfig.cmake b/Tests/RunCMake/find_package/PackageRoot/foo/env_root/cmake/BarConfig.cmake
new file mode 100644
index 0000000..9eaf386
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRoot/foo/env_root/cmake/BarConfig.cmake
@@ -0,0 +1,9 @@
+set(BAR_CMAKE_FILE ${CMAKE_CURRENT_LIST_FILE} CACHE FILEPATH "")
+find_file(BAR_TEST_FILE_FOO foo.h)
+find_file(BAR_TEST_FILE_BAR bar.h)
+find_file(BAR_TEST_FILE_ZOT zot.h PATH_SUFFIXES zot)
+find_path(BAR_TEST_PATH_FOO foo.h)
+find_path(BAR_TEST_PATH_BAR bar.h)
+find_path(BAR_TEST_PATH_ZOT zot.h PATH_SUFFIXES zot)
+find_program(BAR_TEST_PROG_FOO foo.exe)
+find_program(BAR_TEST_PROG_BAR bar.exe)
diff --git a/Tests/RunCMake/find_package/PackageRootNestedConfig-stderr.txt b/Tests/RunCMake/find_package/PackageRootNestedConfig-stderr.txt
new file mode 100644
index 0000000..79266c3
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRootNestedConfig-stderr.txt
@@ -0,0 +1,298 @@
+----------
+Foo_ROOT :
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT :FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT :FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
+BAR_CMAKE_FILE :
+BAR_TEST_FILE_FOO :
+BAR_TEST_FILE_BAR :
+BAR_TEST_FILE_ZOT :
+BAR_TEST_PATH_FOO :
+BAR_TEST_PATH_BAR :
+BAR_TEST_PATH_ZOT :
+BAR_TEST_PROG_FOO :
+BAR_TEST_PROG_BAR :
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/env_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/env_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/env_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/env_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/env_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/env_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarConfig\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/foo/cmake_root/cmake/BarConfig.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
diff --git a/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake b/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake
new file mode 100644
index 0000000..571739d
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake
@@ -0,0 +1,135 @@
+cmake_policy(SET CMP0057 NEW)
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+
+macro(CleanUpPackageRootTest)
+ unset(Foo_ROOT)
+ unset(ENV{Foo_ROOT})
+ unset(Bar_DIR)
+ unset(BAR_CMAKE_FILE)
+ unset(Bar_ROOT)
+ unset(ENV{Bar_ROOT})
+ unset(FOO_TEST_FILE_FOO)
+ unset(FOO_TEST_FILE_ZOT)
+ unset(FOO_TEST_PATH_FOO)
+ unset(FOO_TEST_PATH_ZOT)
+ unset(FOO_TEST_PROG_FOO)
+ unset(BAR_TEST_FILE_FOO)
+ unset(BAR_TEST_FILE_BAR)
+ unset(BAR_TEST_FILE_ZOT)
+ unset(BAR_TEST_PATH_FOO)
+ unset(BAR_TEST_PATH_BAR)
+ unset(BAR_TEST_PATH_ZOT)
+ unset(BAR_TEST_PROG_FOO)
+ unset(BAR_TEST_PROG_BAR)
+ unset(Bar_DIR CACHE)
+ unset(BAR_CMAKE_FILE CACHE)
+ unset(FOO_TEST_FILE_FOO CACHE)
+ unset(FOO_TEST_FILE_ZOT CACHE)
+ unset(FOO_TEST_PATH_FOO CACHE)
+ unset(FOO_TEST_PATH_ZOT CACHE)
+ unset(FOO_TEST_PROG_FOO CACHE)
+ unset(BAR_TEST_FILE_FOO CACHE)
+ unset(BAR_TEST_FILE_BAR CACHE)
+ unset(BAR_TEST_FILE_ZOT CACHE)
+ unset(BAR_TEST_PATH_FOO CACHE)
+ unset(BAR_TEST_PATH_BAR CACHE)
+ unset(BAR_TEST_PATH_ZOT CACHE)
+ unset(BAR_TEST_PROG_FOO CACHE)
+ unset(BAR_TEST_PROG_BAR CACHE)
+endmacro()
+
+macro(RunPackageRootTest)
+ message("----------")
+ message("Foo_ROOT :${Foo_ROOT}")
+ message("ENV{Foo_ROOT} :$ENV{Foo_ROOT}")
+ message("Bar_DIR :${Bar_DIR}")
+ message("Bar_ROOT :${Bar_ROOT}")
+ message("ENV{Bar_ROOT} :$ENV{Bar_ROOT}")
+ message("")
+
+ find_package(Foo COMPONENTS BarConfig)
+ message("find_package(Foo COMPONENTS BarConfig)")
+ message("FOO_TEST_FILE_FOO :${FOO_TEST_FILE_FOO}")
+ message("FOO_TEST_FILE_ZOT :${FOO_TEST_FILE_ZOT}")
+ message("FOO_TEST_PATH_FOO :${FOO_TEST_PATH_FOO}")
+ message("FOO_TEST_PATH_ZOT :${FOO_TEST_PATH_ZOT}")
+ message("FOO_TEST_PROG_FOO :${FOO_TEST_PROG_FOO}")
+ message("BAR_CMAKE_FILE :${BAR_CMAKE_FILE}")
+ message("BAR_TEST_FILE_FOO :${BAR_TEST_FILE_FOO}")
+ message("BAR_TEST_FILE_BAR :${BAR_TEST_FILE_BAR}")
+ message("BAR_TEST_FILE_ZOT :${BAR_TEST_FILE_ZOT}")
+ message("BAR_TEST_PATH_FOO :${BAR_TEST_PATH_FOO}")
+ message("BAR_TEST_PATH_BAR :${BAR_TEST_PATH_BAR}")
+ message("BAR_TEST_PATH_ZOT :${BAR_TEST_PATH_ZOT}")
+ message("BAR_TEST_PROG_FOO :${BAR_TEST_PROG_FOO}")
+ message("BAR_TEST_PROG_BAR :${BAR_TEST_PROG_BAR}")
+ CleanUpPackageRootTest()
+ message("")
+endmacro()
+
+#
+
+RunPackageRootTest()
+
+#
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+#
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+#
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
diff --git a/Tests/RunCMake/find_package/PackageRootNestedModule-stderr.txt b/Tests/RunCMake/find_package/PackageRootNestedModule-stderr.txt
new file mode 100644
index 0000000..57cab60
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRootNestedModule-stderr.txt
@@ -0,0 +1,298 @@
+----------
+Foo_ROOT :
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT :FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT :FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND
+BAR_TEST_FILE_BAR :BAR_TEST_FILE_BAR-NOTFOUND
+BAR_TEST_FILE_ZOT :BAR_TEST_FILE_ZOT-NOTFOUND
+BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND
+BAR_TEST_PATH_BAR :BAR_TEST_PATH_BAR-NOTFOUND
+BAR_TEST_PATH_ZOT :BAR_TEST_PATH_ZOT-NOTFOUND
+BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND
+BAR_TEST_PROG_BAR :BAR_TEST_PROG_BAR-NOTFOUND
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/env_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/env_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/env_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/env_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/env_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/env_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe
+
+----------
+Foo_ROOT :.*/PackageRoot/foo/cmake_root
+ENV{Foo_ROOT} :.*/PackageRoot/foo/cmake_root
+Bar_DIR :
+Bar_ROOT :.*/PackageRoot/bar/cmake_root
+ENV{Bar_ROOT} :.*/PackageRoot/bar/env_root
+
+find_package\(Foo COMPONENTS BarModule\)
+FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_CMAKE_FILE :.*/PackageRoot/FindBar.cmake
+BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h
+BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h
+BAR_TEST_FILE_ZOT :.*/PackageRoot/bar/cmake_root/include/zot/zot.h
+BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include
+BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include
+BAR_TEST_PATH_ZOT :.*/PackageRoot/bar/cmake_root/include/zot
+BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe
+BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe
diff --git a/Tests/RunCMake/find_package/PackageRootNestedModule.cmake b/Tests/RunCMake/find_package/PackageRootNestedModule.cmake
new file mode 100644
index 0000000..f99db59
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRootNestedModule.cmake
@@ -0,0 +1,135 @@
+cmake_policy(SET CMP0057 NEW)
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+
+macro(CleanUpPackageRootTest)
+ unset(Foo_ROOT)
+ unset(ENV{Foo_ROOT})
+ unset(Bar_DIR)
+ unset(BAR_CMAKE_FILE)
+ unset(Bar_ROOT)
+ unset(ENV{Bar_ROOT})
+ unset(FOO_TEST_FILE_FOO)
+ unset(FOO_TEST_FILE_ZOT)
+ unset(FOO_TEST_PATH_FOO)
+ unset(FOO_TEST_PATH_ZOT)
+ unset(FOO_TEST_PROG_FOO)
+ unset(BAR_TEST_FILE_FOO)
+ unset(BAR_TEST_FILE_BAR)
+ unset(BAR_TEST_FILE_ZOT)
+ unset(BAR_TEST_PATH_FOO)
+ unset(BAR_TEST_PATH_BAR)
+ unset(BAR_TEST_PATH_ZOT)
+ unset(BAR_TEST_PROG_FOO)
+ unset(BAR_TEST_PROG_BAR)
+ unset(Bar_DIR CACHE)
+ unset(BAR_CMAKE_FILE CACHE)
+ unset(FOO_TEST_FILE_FOO CACHE)
+ unset(FOO_TEST_FILE_ZOT CACHE)
+ unset(FOO_TEST_PATH_FOO CACHE)
+ unset(FOO_TEST_PATH_ZOT CACHE)
+ unset(FOO_TEST_PROG_FOO CACHE)
+ unset(BAR_TEST_FILE_FOO CACHE)
+ unset(BAR_TEST_FILE_BAR CACHE)
+ unset(BAR_TEST_FILE_ZOT CACHE)
+ unset(BAR_TEST_PATH_FOO CACHE)
+ unset(BAR_TEST_PATH_BAR CACHE)
+ unset(BAR_TEST_PATH_ZOT CACHE)
+ unset(BAR_TEST_PROG_FOO CACHE)
+ unset(BAR_TEST_PROG_BAR CACHE)
+endmacro()
+
+macro(RunPackageRootTest)
+ message("----------")
+ message("Foo_ROOT :${Foo_ROOT}")
+ message("ENV{Foo_ROOT} :$ENV{Foo_ROOT}")
+ message("Bar_DIR :${Bar_DIR}")
+ message("Bar_ROOT :${Bar_ROOT}")
+ message("ENV{Bar_ROOT} :$ENV{Bar_ROOT}")
+ message("")
+
+ find_package(Foo COMPONENTS BarModule)
+ message("find_package(Foo COMPONENTS BarModule)")
+ message("FOO_TEST_FILE_FOO :${FOO_TEST_FILE_FOO}")
+ message("FOO_TEST_FILE_ZOT :${FOO_TEST_FILE_ZOT}")
+ message("FOO_TEST_PATH_FOO :${FOO_TEST_PATH_FOO}")
+ message("FOO_TEST_PATH_ZOT :${FOO_TEST_PATH_ZOT}")
+ message("FOO_TEST_PROG_FOO :${FOO_TEST_PROG_FOO}")
+ message("BAR_CMAKE_FILE :${BAR_CMAKE_FILE}")
+ message("BAR_TEST_FILE_FOO :${BAR_TEST_FILE_FOO}")
+ message("BAR_TEST_FILE_BAR :${BAR_TEST_FILE_BAR}")
+ message("BAR_TEST_FILE_ZOT :${BAR_TEST_FILE_ZOT}")
+ message("BAR_TEST_PATH_FOO :${BAR_TEST_PATH_FOO}")
+ message("BAR_TEST_PATH_BAR :${BAR_TEST_PATH_BAR}")
+ message("BAR_TEST_PATH_ZOT :${BAR_TEST_PATH_ZOT}")
+ message("BAR_TEST_PROG_FOO :${BAR_TEST_PROG_FOO}")
+ message("BAR_TEST_PROG_BAR :${BAR_TEST_PROG_BAR}")
+ CleanUpPackageRootTest()
+ message("")
+endmacro()
+
+#
+
+RunPackageRootTest()
+
+#
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+#
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+#
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/cmake_root)
+set(Bar_ROOT ${PackageRoot_BASE}/bar/cmake_root)
+set(ENV{Bar_ROOT} ${PackageRoot_BASE}/bar/env_root)
+RunPackageRootTest()
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 7875db6..d548da0 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -14,6 +14,8 @@ run_cmake(MissingConfigRequired)
run_cmake(MissingConfigVersion)
run_cmake(MixedModeOptions)
run_cmake(PackageRoot)
+run_cmake(PackageRootNestedConfig)
+run_cmake(PackageRootNestedModule)
run_cmake(PolicyPush)
run_cmake(PolicyPop)
run_cmake(SetFoundFALSE)
diff --git a/Utilities/Scripts/update-expat.bash b/Utilities/Scripts/update-expat.bash
index 4cc8646..4ac5ef3 100755
--- a/Utilities/Scripts/update-expat.bash
+++ b/Utilities/Scripts/update-expat.bash
@@ -8,7 +8,7 @@ readonly name="expat"
readonly ownership="Expat Upstream <kwrobot@kitware.com>"
readonly subtree="Utilities/cmexpat"
readonly repo="https://github.com/libexpat/libexpat.git"
-readonly tag="R_2_2_1"
+readonly tag="R_2_2_3"
readonly shortlog=false
readonly paths="
expat/lib/asciitab.h
@@ -18,6 +18,7 @@ readonly paths="
expat/lib/xmlrole.h
expat/lib/iasciitab.h
expat/lib/latin1tab.h
+ expat/lib/loadlibrary.c
expat/lib/xmlrole.c
expat/lib/utf8tab.h
expat/lib/nametab.h
@@ -30,9 +31,8 @@ readonly paths="
expat/lib/xmltok.c
expat/lib/xmlparse.c
expat/lib/xmltok_impl.c
- expat/README
+ expat/README.md
expat/ConfigureChecks.cmake
- expat/CMakeLists.txt
expat/expat_config.h.cmake
expat/COPYING
"
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index 41c6a66..7534f94 100755
--- a/Utilities/Scripts/update-libarchive.bash
+++ b/Utilities/Scripts/update-libarchive.bash
@@ -8,7 +8,7 @@ readonly name="LibArchive"
readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
readonly subtree="Utilities/cmlibarchive"
readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.3.1"
+readonly tag="v3.3.2"
readonly shortlog=false
readonly paths="
CMakeLists.txt
diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py
index 6f273f9..cfda2d4 100644
--- a/Utilities/Sphinx/cmake.py
+++ b/Utilities/Sphinx/cmake.py
@@ -46,7 +46,20 @@ from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, ObjType
from sphinx.roles import XRefRole
from sphinx.util.nodes import make_refnode
-from sphinx import addnodes, version_info
+from sphinx import addnodes
+
+# Needed for checking if Sphinx version is >= 1.4.
+# See https://github.com/sphinx-doc/sphinx/issues/2673
+old_sphinx = False
+
+try:
+ from sphinx import version_info
+ if version_info < (1, 4):
+ old_sphinx = True
+except ImportError:
+ # The `sphinx.version_info` tuple was added in Sphinx v1.2:
+ old_sphinx = True
+
class CMakeModule(Directive):
required_arguments = 1
@@ -124,7 +137,7 @@ class _cmake_index_entry:
def __call__(self, title, targetid, main = 'main'):
# See https://github.com/sphinx-doc/sphinx/issues/2673
- if version_info < (1, 4):
+ if old_sphinx:
return ('pair', u'%s ; %s' % (self.desc, title), targetid, main)
else:
return ('pair', u'%s ; %s' % (self.desc, title), targetid, main, None)
diff --git a/Utilities/cmexpat/CMakeLists.txt b/Utilities/cmexpat/CMakeLists.txt
index d294165..470fcba 100644
--- a/Utilities/cmexpat/CMakeLists.txt
+++ b/Utilities/cmexpat/CMakeLists.txt
@@ -7,9 +7,9 @@ ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
ENDIF()
include(ConfigureChecks.cmake)
-if(WIN32)
- add_definitions(-DCOMPILING_FOR_WINDOWS)
-endif(WIN32)
+if(NOT WIN32)
+ add_definitions(-DXML_DEV_URANDOM)
+endif()
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
@@ -17,6 +17,7 @@ include_directories(
)
add_library(cmexpat STATIC
+ lib/loadlibrary.c
lib/xmlparse.c
lib/xmlrole.c
lib/xmltok.c
diff --git a/Utilities/cmexpat/ConfigureChecks.cmake b/Utilities/cmexpat/ConfigureChecks.cmake
index f03faa6..057cfa5 100644
--- a/Utilities/cmexpat/ConfigureChecks.cmake
+++ b/Utilities/cmexpat/ConfigureChecks.cmake
@@ -40,5 +40,5 @@ else(HAVE_SYS_TYPES_H)
set(SIZE_T "unsigned")
endif(HAVE_SYS_TYPES_H)
-configure_file(expat_config.h.cmake expat_config.h)
+configure_file(expat_config.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/expat_config.h")
add_definitions(-DHAVE_EXPAT_CONFIG_H)
diff --git a/Utilities/cmexpat/README b/Utilities/cmexpat/README
deleted file mode 100644
index cd11a22..0000000
--- a/Utilities/cmexpat/README
+++ /dev/null
@@ -1,139 +0,0 @@
-
- Expat, Release 2.2.1
-
-This is Expat, a C library for parsing XML, written by James Clark.
-Expat is a stream-oriented XML parser. This means that you register
-handlers with the parser before starting the parse. These handlers
-are called when the parser discovers the associated structures in the
-document being parsed. A start tag is an example of the kind of
-structures for which you may register handlers.
-
-Windows users should use the expat_win32bin package, which includes
-both precompiled libraries and executables, and source code for
-developers.
-
-Expat is free software. You may copy, distribute, and modify it under
-the terms of the License contained in the file COPYING distributed
-with this package. This license is the same as the MIT/X Consortium
-license.
-
-Versions of Expat that have an odd minor version (the middle number in
-the release above), are development releases and should be considered
-as beta software. Releases with even minor version numbers are
-intended to be production grade software.
-
-If you are building Expat from a check-out from the CVS repository,
-you need to run a script that generates the configure script using the
-GNU autoconf and libtool tools. To do this, you need to have
-autoconf 2.58 or newer. Run the script like this:
-
- ./buildconf.sh
-
-Once this has been done, follow the same instructions as for building
-from a source distribution.
-
-To build Expat from a source distribution, you first run the
-configuration shell script in the top level distribution directory:
-
- ./configure
-
-There are many options which you may provide to configure (which you
-can discover by running configure with the --help option). But the
-one of most interest is the one that sets the installation directory.
-By default, the configure script will set things up to install
-libexpat into /usr/local/lib, expat.h into /usr/local/include, and
-xmlwf into /usr/local/bin. If, for example, you'd prefer to install
-into /home/me/mystuff/lib, /home/me/mystuff/include, and
-/home/me/mystuff/bin, you can tell configure about that with:
-
- ./configure --prefix=/home/me/mystuff
-
-Another interesting option is to enable 64-bit integer support for
-line and column numbers and the over-all byte index:
-
- ./configure CPPFLAGS=-DXML_LARGE_SIZE
-
-However, such a modification would be a breaking change to the ABI
-and is therefore not recommended for general use - e.g. as part of
-a Linux distribution - but rather for builds with special requirements.
-
-After running the configure script, the "make" command will build
-things and "make install" will install things into their proper
-location. Have a look at the "Makefile" to learn about additional
-"make" options. Note that you need to have write permission into
-the directories into which things will be installed.
-
-If you are interested in building Expat to provide document
-information in UTF-16 encoding rather than the default UTF-8, follow
-these instructions (after having run "make distclean"):
-
- 1. For UTF-16 output as unsigned short (and version/error
- strings as char), run:
-
- ./configure CPPFLAGS=-DXML_UNICODE
-
- For UTF-16 output as wchar_t (incl. version/error strings),
- run:
-
- ./configure CFLAGS="-g -O2 -fshort-wchar" \
- CPPFLAGS=-DXML_UNICODE_WCHAR_T
-
- 2. Edit the MakeFile, changing:
-
- LIBRARY = libexpat.la
-
- to:
-
- LIBRARY = libexpatw.la
-
- (Note the additional "w" in the library name.)
-
- 3. Run "make buildlib" (which builds the library only).
- Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".
-
- 4. Run "make installlib" (which installs the library only).
- Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".
-
-Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default
-value for DESTDIR, and the rest of the make file using only DESTDIR.
-It works as follows:
- $ make install DESTDIR=/path/to/image
-overrides the in-makefile set DESTDIR, while both
- $ INSTALL_ROOT=/path/to/image make install
- $ make install INSTALL_ROOT=/path/to/image
-use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the
-environment, because variable-setting priority is
-1) commandline
-2) in-makefile
-3) environment
-
-Note: This only applies to the Expat library itself, building UTF-16 versions
-of xmlwf and the tests is currently not supported.
-
-Note for Solaris users: The "ar" command is usually located in
-"/usr/ccs/bin", which is not in the default PATH. You will need to
-add this to your path for the "make" command, and probably also switch
-to GNU make (the "make" found in /usr/ccs/bin does not seem to work
-properly -- apparently it does not understand .PHONY directives). If
-you're using ksh or bash, use this command to build:
-
- PATH=/usr/ccs/bin:$PATH make
-
-When using Expat with a project using autoconf for configuration, you
-can use the probing macro in conftools/expat.m4 to determine how to
-include Expat. See the comments at the top of that file for more
-information.
-
-A reference manual is available in the file doc/reference.html in this
-distribution.
-
-The homepage for this project is http://www.libexpat.org/. There
-are links there to connect you to the bug reports page. If you need
-to report a bug when you don't have access to a browser, you may also
-send a bug report by email to expat-bugs@mail.libexpat.org.
-
-Discussion related to the direction of future expat development takes
-place on expat-discuss@mail.libexpat.org. Archives of this list and
-other Expat-related lists may be found at:
-
- http://mail.libexpat.org/mailman/listinfo/
diff --git a/Utilities/cmexpat/README.md b/Utilities/cmexpat/README.md
new file mode 100644
index 0000000..0a1777e
--- /dev/null
+++ b/Utilities/cmexpat/README.md
@@ -0,0 +1,126 @@
+# Expat, Release 2.2.3
+
+This is Expat, a C library for parsing XML, started by
+[James Clark](https://en.wikipedia.org/wiki/James_Clark_(programmer)) in 1997.
+Expat is a stream-oriented XML parser. This means that you register
+handlers with the parser before starting the parse. These handlers
+are called when the parser discovers the associated structures in the
+document being parsed. A start tag is an example of the kind of
+structures for which you may register handlers.
+
+Windows users should use the
+[`expat_win32` package](https://sourceforge.net/projects/expat/files/expat_win32/),
+which includes both precompiled libraries and executables, and source code for
+developers.
+
+Expat is [free software](https://www.gnu.org/philosophy/free-sw.en.html).
+You may copy, distribute, and modify it under the terms of the License
+contained in the file
+[`COPYING`](https://github.com/libexpat/libexpat/blob/master/expat/COPYING)
+distributed with this package.
+This license is the same as the MIT/X Consortium license.
+
+If you are building Expat from a check-out from the
+[Git repository](https://github.com/libexpat/libexpat/),
+you need to run a script that generates the configure script using the
+GNU autoconf and libtool tools. To do this, you need to have
+autoconf 2.58 or newer. Run the script like this:
+
+```console
+./buildconf.sh
+```
+
+Once this has been done, follow the same instructions as for building
+from a source distribution.
+
+To build Expat from a source distribution, you first run the
+configuration shell script in the top level distribution directory:
+
+```console
+./configure
+```
+
+There are many options which you may provide to configure (which you
+can discover by running configure with the `--help` option). But the
+one of most interest is the one that sets the installation directory.
+By default, the configure script will set things up to install
+libexpat into `/usr/local/lib`, `expat.h` into `/usr/local/include`, and
+`xmlwf` into `/usr/local/bin`. If, for example, you'd prefer to install
+into `/home/me/mystuff/lib`, `/home/me/mystuff/include`, and
+`/home/me/mystuff/bin`, you can tell `configure` about that with:
+
+```console
+./configure --prefix=/home/me/mystuff
+```
+
+Another interesting option is to enable 64-bit integer support for
+line and column numbers and the over-all byte index:
+
+```console
+./configure CPPFLAGS=-DXML_LARGE_SIZE
+```
+
+However, such a modification would be a breaking change to the ABI
+and is therefore not recommended for general use &mdash; e.g. as part of
+a Linux distribution &mdash; but rather for builds with special requirements.
+
+After running the configure script, the `make` command will build
+things and `make install` will install things into their proper
+location. Have a look at the `Makefile` to learn about additional
+`make` options. Note that you need to have write permission into
+the directories into which things will be installed.
+
+If you are interested in building Expat to provide document
+information in UTF-16 encoding rather than the default UTF-8, follow
+these instructions (after having run `make distclean`):
+
+1. For UTF-16 output as unsigned short (and version/error strings as char),
+ run:<br/>
+ `./configure CPPFLAGS=-DXML_UNICODE`<br/>
+ For UTF-16 output as `wchar_t` (incl. version/error strings), run:<br/>
+ `./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T`
+ <br/>Note: The latter requires libc compiled with `-fshort-wchar`, as well.
+
+1. Edit `Makefile`, changing:<br/>
+ `LIBRARY = libexpat.la`<br/>
+ to:<br/>
+ `LIBRARY = libexpatw.la`<br/>
+ (Note the additional "w" in the library name.)
+
+1. Run `make buildlib` (which builds the library only).
+ Or, to save step 2, run `make buildlib LIBRARY=libexpatw.la`.
+
+1. Run `make installlib` (which installs the library only).
+ Or, if step 2 was omitted, run `make installlib LIBRARY=libexpatw.la`.
+
+Using `DESTDIR` or `INSTALL_ROOT` is enabled, with `INSTALL_ROOT` being the
+default value for `DESTDIR`, and the rest of the make file using only
+`DESTDIR`. It works as follows:
+
+```console
+make install DESTDIR=/path/to/image
+```
+
+overrides the in-makefile set `DESTDIR`, while both
+
+```console
+INSTALL_ROOT=/path/to/image make install
+make install INSTALL_ROOT=/path/to/image
+```
+
+use `DESTDIR=$(INSTALL_ROOT)`, even if `DESTDIR` eventually is defined in the
+environment, because variable-setting priority is
+1. commandline
+2. in-makefile
+3. environment
+
+Note: This only applies to the Expat library itself, building UTF-16 versions
+of xmlwf and the tests is currently not supported.
+
+When using Expat with a project using autoconf for configuration, you
+can use the probing macro in `conftools/expat.m4` to determine how to
+include Expat. See the comments at the top of that file for more
+information.
+
+A reference manual is available in the file `doc/reference.html` in this
+distribution.
diff --git a/Utilities/cmexpat/lib/expat.h b/Utilities/cmexpat/lib/expat.h
index 28b0f95..7e5bbb7 100644
--- a/Utilities/cmexpat/lib/expat.h
+++ b/Utilities/cmexpat/lib/expat.h
@@ -24,7 +24,6 @@ extern "C" {
struct XML_ParserStruct;
typedef struct XML_ParserStruct *XML_Parser;
-/* Should this be defined using stdbool.h when C99 is available? */
typedef unsigned char XML_Bool;
#define XML_TRUE ((XML_Bool) 1)
#define XML_FALSE ((XML_Bool) 0)
@@ -1049,7 +1048,7 @@ XML_GetFeatureList(void);
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 2
-#define XML_MICRO_VERSION 1
+#define XML_MICRO_VERSION 3
#ifdef __cplusplus
}
diff --git a/Utilities/cmexpat/lib/loadlibrary.c b/Utilities/cmexpat/lib/loadlibrary.c
new file mode 100644
index 0000000..ffce868
--- /dev/null
+++ b/Utilities/cmexpat/lib/loadlibrary.c
@@ -0,0 +1,141 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * All rights reserved.
+ *
+ * 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", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+ * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization of the
+ * copyright holder.
+ *
+ ***************************************************************************/
+
+#if defined(_WIN32)
+
+#include <windows.h>
+#include <tchar.h>
+
+
+HMODULE _Expat_LoadLibrary(LPCTSTR filename);
+
+
+#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
+#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008
+#endif
+
+#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
+#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
+#endif
+
+/* We use our own typedef here since some headers might lack these */
+typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
+
+/* See function definitions in winbase.h */
+#ifdef UNICODE
+# ifdef _WIN32_WCE
+# define LOADLIBARYEX L"LoadLibraryExW"
+# else
+# define LOADLIBARYEX "LoadLibraryExW"
+# endif
+#else
+# define LOADLIBARYEX "LoadLibraryExA"
+#endif
+
+
+/*
+ * _Expat_LoadLibrary()
+ *
+ * This is used to dynamically load DLLs using the most secure method available
+ * for the version of Windows that we are running on.
+ *
+ * Parameters:
+ *
+ * filename [in] - The filename or full path of the DLL to load. If only the
+ * filename is passed then the DLL will be loaded from the
+ * Windows system directory.
+ *
+ * Returns the handle of the module on success; otherwise NULL.
+ */
+HMODULE _Expat_LoadLibrary(LPCTSTR filename)
+{
+ HMODULE hModule = NULL;
+ LOADLIBRARYEX_FN pLoadLibraryEx = NULL;
+
+ /* Get a handle to kernel32 so we can access it's functions at runtime */
+ HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
+ if(!hKernel32)
+ return NULL;
+
+ /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
+ and above */
+ pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
+
+ /* Detect if there's already a path in the filename and load the library if
+ there is. Note: Both back slashes and forward slashes have been supported
+ since the earlier days of DOS at an API level although they are not
+ supported by command prompt */
+ if(_tcspbrk(filename, TEXT("\\/"))) {
+ /** !checksrc! disable BANNEDFUNC 1 **/
+ hModule = pLoadLibraryEx ?
+ pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
+ LoadLibrary(filename);
+ }
+ /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only
+ supported on Windows Vista, Windows Server 2008, Windows 7 and Windows
+ Server 2008 R2 with this patch or natively on Windows 8 and above */
+ else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) {
+ /* Load the DLL from the Windows system directory */
+ hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ }
+ else {
+ /* Attempt to get the Windows system path */
+ UINT systemdirlen = GetSystemDirectory(NULL, 0);
+ if(systemdirlen) {
+ /* Allocate space for the full DLL path (Room for the null terminator
+ is included in systemdirlen) */
+ size_t filenamelen = _tcslen(filename);
+ TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen));
+ if(path && GetSystemDirectory(path, systemdirlen)) {
+ /* Calculate the full DLL path */
+ _tcscpy(path + _tcslen(path), TEXT("\\"));
+ _tcscpy(path + _tcslen(path), filename);
+
+ /* Load the DLL from the Windows system directory */
+ /** !checksrc! disable BANNEDFUNC 1 **/
+ hModule = pLoadLibraryEx ?
+ pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
+ LoadLibrary(path);
+
+ }
+ free(path);
+ }
+ }
+
+ return hModule;
+}
+
+#else /* defined(_WIN32) */
+
+/* ISO C requires a translation unit to contain at least one declaration
+ [-Wempty-translation-unit] */
+typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY;
+
+#endif /* defined(_WIN32) */
diff --git a/Utilities/cmexpat/lib/siphash.h b/Utilities/cmexpat/lib/siphash.h
index db17458..1684b25 100644
--- a/Utilities/cmexpat/lib/siphash.h
+++ b/Utilities/cmexpat/lib/siphash.h
@@ -2,9 +2,8 @@
* siphash.h - SipHash-2-4 in a single header file
* --------------------------------------------------------------------------
* Derived by William Ahern from the reference implementation[1] published[2]
- * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind.
* by Jean-Philippe Aumasson and Daniel J. Berstein.
- * Minimal changes by Sebastian Pipping on top, details below.
+ * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below.
* Licensed under the CC0 Public Domain Dedication license.
*
* 1. https://www.131002.net/siphash/siphash24.c
@@ -12,14 +11,25 @@
* --------------------------------------------------------------------------
* HISTORY:
*
- * 2017-06-10 (Sebastian Pipping)
+ * 2017-07-25 (Vadim Zeitlin)
+ * - Fix use of SIPHASH_MAIN macro
+ *
+ * 2017-07-05 (Sebastian Pipping)
+ * - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++
+ * - Add const qualifiers at two places
+ * - Ensure <=80 characters line length (assuming tab width 4)
+ *
+ * 2017-06-23 (Victor Stinner)
+ * - Address Win64 compile warnings
+ *
+ * 2017-06-18 (Sebastian Pipping)
* - Clarify license note in the header
* - Address C89 issues:
* - Stop using inline keyword (and let compiler decide)
- * - Turn integer suffix ULL to UL
* - Replace _Bool by int
* - Turn macro siphash24 into a function
* - Address invalid conversion (void pointer) by explicit cast
+ * - Address lack of stdint.h for Visual Studio 2003 to 2008
* - Always expose sip24_valid (for self-tests)
*
* 2012-11-04 - Born. (William Ahern)
@@ -89,6 +99,15 @@
# define uint8_t KWIML_INT_uint8_t
#endif
+
+/*
+ * Workaround to not require a C++11 compiler for using ULL suffix
+ * if this code is included and compiled as C++; related GCC warning is:
+ * warning: use of C++11 long long integer constant [-Wlong-long]
+ */
+#define _SIP_ULL(high, low) (((uint64_t)high << 32) | low)
+
+
#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))
#define SIP_U32TO8_LE(p, v) \
@@ -168,11 +187,12 @@ static void sip_round(struct siphash *H, const int rounds) {
} /* sip_round() */
-static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) {
- H->v0 = 0x736f6d6570736575UL ^ key->k[0];
- H->v1 = 0x646f72616e646f6dUL ^ key->k[1];
- H->v2 = 0x6c7967656e657261UL ^ key->k[0];
- H->v3 = 0x7465646279746573UL ^ key->k[1];
+static struct siphash *sip24_init(struct siphash *H,
+ const struct sipkey *key) {
+ H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
+ H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
+ H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
+ H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
H->p = H->buf;
H->c = 0;
@@ -183,7 +203,8 @@ static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) {
#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])
-static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) {
+static struct siphash *sip24_update(struct siphash *H, const void *src,
+ size_t len) {
const unsigned char *p = (const unsigned char *)src, *pe = p + len;
uint64_t m;
@@ -208,7 +229,7 @@ static struct siphash *sip24_update(struct siphash *H, const void *src, size_t l
static uint64_t sip24_final(struct siphash *H) {
- char left = H->p - H->buf;
+ const char left = (char)(H->p - H->buf);
uint64_t b = (H->c + left) << 56;
switch (left) {
@@ -232,7 +253,8 @@ static uint64_t sip24_final(struct siphash *H) {
} /* sip24_final() */
-static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) {
+static uint64_t siphash24(const void *src, size_t len,
+ const struct sipkey *key) {
struct siphash state = SIPHASH_INITIALIZER;
return sip24_final(sip24_update(sip24_init(&state, key), src, len));
} /* siphash24() */
@@ -320,10 +342,11 @@ static int sip24_valid(void) {
struct sipkey k;
size_t i;
- sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017");
+ sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
+ "\012\013\014\015\016\017");
for (i = 0; i < sizeof in; ++i) {
- in[i] = i;
+ in[i] = (unsigned char)i;
if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
return 0;
@@ -333,12 +356,12 @@ static int sip24_valid(void) {
} /* sip24_valid() */
-#if SIPHASH_MAIN
+#ifdef SIPHASH_MAIN
#include <stdio.h>
int main(void) {
- int ok = sip24_valid();
+ const int ok = sip24_valid();
if (ok)
puts("OK");
diff --git a/Utilities/cmexpat/lib/xmlparse.c b/Utilities/cmexpat/lib/xmlparse.c
index 76f078e..b703e61 100644
--- a/Utilities/cmexpat/lib/xmlparse.c
+++ b/Utilities/cmexpat/lib/xmlparse.c
@@ -1,10 +1,12 @@
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
- 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
+ 101bfd65d1ff3d1511cf6671e6aae65f82cd97df6f4da137d46d510731830ad9 (2.2.3+)
*/
-#define _GNU_SOURCE /* syscall prototype */
+#if !defined(_GNU_SOURCE)
+# define _GNU_SOURCE 1 /* syscall prototype */
+#endif
#include <stddef.h>
#include <string.h> /* memset(), memcpy() */
@@ -19,6 +21,8 @@
#include <sys/time.h> /* gettimeofday() */
#include <sys/types.h> /* getpid() */
#include <unistd.h> /* getpid() */
+#include <fcntl.h> /* O_RDONLY */
+#include <errno.h>
#endif
#define XML_BUILDING_EXPAT 1
@@ -33,6 +37,57 @@
#include "expat.h"
#include "siphash.h"
+#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+# if defined(HAVE_GETRANDOM)
+# include <sys/random.h> /* getrandom */
+# else
+# include <unistd.h> /* syscall */
+# include <sys/syscall.h> /* SYS_getrandom */
+# endif
+# if ! defined(GRND_NONBLOCK)
+# define GRND_NONBLOCK 0x0001
+# endif /* defined(GRND_NONBLOCK) */
+#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+#if defined(HAVE_LIBBSD) \
+ && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
+# include <bsd/stdlib.h>
+#endif
+
+#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
+# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
+#endif
+
+#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \
+ && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \
+ && !defined(XML_DEV_URANDOM) \
+ && !defined(_WIN32) \
+ && !defined(XML_POOR_ENTROPY)
+# error \
+ You do not have support for any sources of high quality entropy \
+ enabled. For end user security, that is probably not what you want. \
+ \
+ Your options include: \
+ * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
+ * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
+ * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
+ * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \
+ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
+ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
+ * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
+ * Windows (RtlGenRandom): _WIN32. \
+ \
+ If insist on not using any of these, bypass this error by defining \
+ XML_POOR_ENTROPY; you have been warned. \
+ \
+ For CMake, one way to pass the define is: \
+ cmake -DCMAKE_C_FLAGS="-pipe -O2 -DHAVE_SYSCALL_GETRANDOM" . \
+ \
+ If you have reasons to patch this detection code away or need changes \
+ to the build system, please open a bug. Thank you!
+#endif
+
+
#ifdef XML_UNICODE
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
#define XmlConvert XmlUtf16Convert
@@ -436,6 +491,9 @@ static ELEMENT_TYPE *
getElementType(XML_Parser parser, const ENCODING *enc,
const char *ptr, const char *end);
+static XML_Char *copyString(const XML_Char *s,
+ const XML_Memory_Handling_Suite *memsuite);
+
static unsigned long generate_hash_secret_salt(XML_Parser parser);
static XML_Bool startParsing(XML_Parser parser);
@@ -696,21 +754,13 @@ static const XML_Char implicitContext[] = {
#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
-# include <errno.h>
-
-# if defined(HAVE_GETRANDOM)
-# include <sys/random.h> /* getrandom */
-# else
-# include <unistd.h> /* syscall */
-# include <sys/syscall.h> /* SYS_getrandom */
-# endif
/* Obtain entropy on Linux 3.17+ */
static int
-writeRandomBytes_getrandom(void * target, size_t count) {
+writeRandomBytes_getrandom_nonblock(void * target, size_t count) {
int success = 0; /* full count bytes written? */
size_t bytesWrittenTotal = 0;
- const unsigned int getrandomFlags = 0;
+ const unsigned int getrandomFlags = GRND_NONBLOCK;
do {
void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
@@ -728,7 +778,7 @@ writeRandomBytes_getrandom(void * target, size_t count) {
if (bytesWrittenTotal >= count)
success = 1;
}
- } while (! success && (errno == EINTR || errno == EAGAIN));
+ } while (! success && (errno == EINTR));
return success;
}
@@ -736,12 +786,67 @@ writeRandomBytes_getrandom(void * target, size_t count) {
#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+
+/* Extract entropy from /dev/urandom */
+static int
+writeRandomBytes_dev_urandom(void * target, size_t count) {
+ int success = 0; /* full count bytes written? */
+ size_t bytesWrittenTotal = 0;
+
+ const int fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ return 0;
+ }
+
+ do {
+ void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+ const size_t bytesToWrite = count - bytesWrittenTotal;
+
+ const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
+
+ if (bytesWrittenMore > 0) {
+ bytesWrittenTotal += bytesWrittenMore;
+ if (bytesWrittenTotal >= count)
+ success = 1;
+ }
+ } while (! success && (errno == EINTR));
+
+ close(fd);
+ return success;
+}
+
+#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
+
+
+#if defined(HAVE_ARC4RANDOM)
+
+static void
+writeRandomBytes_arc4random(void * target, size_t count) {
+ size_t bytesWrittenTotal = 0;
+
+ while (bytesWrittenTotal < count) {
+ const uint32_t random32 = arc4random();
+ size_t i = 0;
+
+ for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
+ i++, bytesWrittenTotal++) {
+ const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
+ ((uint8_t *)target)[bytesWrittenTotal] = random8;
+ }
+ }
+}
+
+#endif /* defined(HAVE_ARC4RANDOM) */
+
+
#ifdef _WIN32
typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
+HMODULE _Expat_LoadLibrary(LPCTSTR filename); /* see loadlibrary.c */
/* Obtain entropy on Windows XP / Windows Server 2003 and later.
- * Hint on RtlGenRandom and the following article from libsodioum.
+ * Hint on RtlGenRandom and the following article from libsodium.
*
* Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
* https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
@@ -749,7 +854,7 @@ typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
static int
writeRandomBytes_RtlGenRandom(void * target, size_t count) {
int success = 0; /* full count bytes written? */
- const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");
+ const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL"));
if (advapi32) {
const RTLGENRANDOM_FUNC RtlGenRandom
@@ -768,6 +873,8 @@ writeRandomBytes_RtlGenRandom(void * target, size_t count) {
#endif /* _WIN32 */
+#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
+
static unsigned long
gather_time_entropy(void)
{
@@ -780,16 +887,20 @@ gather_time_entropy(void)
int gettimeofday_res;
gettimeofday_res = gettimeofday(&tv, NULL);
+
+#if defined(NDEBUG)
+ (void)gettimeofday_res;
+#else
assert (gettimeofday_res == 0);
+#endif /* defined(NDEBUG) */
/* Microseconds time is <20 bits entropy */
return tv.tv_usec;
#endif
}
-#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)
-# include <bsd/stdlib.h>
-#endif
+#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
+
static unsigned long
ENTROPY_DEBUG(const char * label, unsigned long entropy) {
@@ -808,10 +919,12 @@ generate_hash_secret_salt(XML_Parser parser)
{
unsigned long entropy;
(void)parser;
-#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)
- (void)gather_time_entropy;
+#if defined(HAVE_ARC4RANDOM_BUF)
arc4random_buf(&entropy, sizeof(entropy));
return ENTROPY_DEBUG("arc4random_buf", entropy);
+#elif defined(HAVE_ARC4RANDOM)
+ writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
+ return ENTROPY_DEBUG("arc4random", entropy);
#else
/* Try high quality providers first .. */
#ifdef _WIN32
@@ -819,10 +932,15 @@ generate_hash_secret_salt(XML_Parser parser)
return ENTROPY_DEBUG("RtlGenRandom", entropy);
}
#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
- if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {
+ if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
return ENTROPY_DEBUG("getrandom", entropy);
}
#endif
+#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+ if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
+ return ENTROPY_DEBUG("/dev/urandom", entropy);
+ }
+#endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
/* .. and self-made low quality for backup: */
/* Process ID is 0 bits entropy if attacker has local access */
@@ -833,7 +951,7 @@ generate_hash_secret_salt(XML_Parser parser)
return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
} else {
return ENTROPY_DEBUG("fallback(8)",
- entropy * (unsigned long)2305843009213693951);
+ entropy * (unsigned long)2305843009213693951ULL);
}
#endif
}
@@ -962,6 +1080,8 @@ parserCreate(const XML_Char *encodingName,
nsAttsVersion = 0;
nsAttsPower = 0;
+ protocolEncodingName = NULL;
+
poolInit(&tempPool, &(parser->m_mem));
poolInit(&temp2Pool, &(parser->m_mem));
parserInit(parser, encodingName);
@@ -988,9 +1108,9 @@ parserInit(XML_Parser parser, const XML_Char *encodingName)
{
processor = prologInitProcessor;
XmlPrologStateInit(&prologState);
- protocolEncodingName = (encodingName != NULL
- ? poolCopyString(&tempPool, encodingName)
- : NULL);
+ if (encodingName != NULL) {
+ protocolEncodingName = copyString(encodingName, &(parser->m_mem));
+ }
curBase = NULL;
XmlInitEncoding(&initEncoding, &encoding, 0);
userData = NULL;
@@ -1103,6 +1223,8 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
unknownEncodingRelease(unknownEncodingData);
poolClear(&tempPool);
poolClear(&temp2Pool);
+ FREE((void *)protocolEncodingName);
+ protocolEncodingName = NULL;
parserInit(parser, encodingName);
dtdReset(_dtd, &parser->m_mem);
return XML_TRUE;
@@ -1119,10 +1241,16 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
*/
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return XML_STATUS_ERROR;
+
+ /* Get rid of any previous encoding name */
+ FREE((void *)protocolEncodingName);
+
if (encodingName == NULL)
+ /* No new encoding name */
protocolEncodingName = NULL;
else {
- protocolEncodingName = poolCopyString(&tempPool, encodingName);
+ /* Copy the new encoding name into allocated memory */
+ protocolEncodingName = copyString(encodingName, &(parser->m_mem));
if (!protocolEncodingName)
return XML_STATUS_ERROR;
}
@@ -1357,6 +1485,7 @@ XML_ParserFree(XML_Parser parser)
destroyBindings(inheritedBindings, parser);
poolDestroy(&tempPool);
poolDestroy(&temp2Pool);
+ FREE((void *)protocolEncodingName);
#ifdef XML_DTD
/* external parameter entity parsers share the DTD structure
parser->m_dtd with the root parser, so we must not destroy it
@@ -1748,7 +1877,8 @@ enum XML_Status XMLCALL
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
{
if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
- errorCode = XML_ERROR_INVALID_ARGUMENT;
+ if (parser != NULL)
+ parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
return XML_STATUS_ERROR;
}
switch (ps_parsing) {
@@ -1783,9 +1913,22 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
if (errorCode == XML_ERROR_NONE) {
switch (ps_parsing) {
case XML_SUSPENDED:
+ /* It is hard to be certain, but it seems that this case
+ * cannot occur. This code is cleaning up a previous parse
+ * with no new data (since len == 0). Changing the parsing
+ * state requires getting to execute a handler function, and
+ * there doesn't seem to be an opportunity for that while in
+ * this circumstance.
+ *
+ * Given the uncertainty, we retain the code but exclude it
+ * from coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
positionPtr = bufferPtr;
return XML_STATUS_SUSPENDED;
+ /* LCOV_EXCL_STOP */
case XML_INITIALIZED:
case XML_PARSING:
ps_parsing = XML_FINISHED;
@@ -2974,9 +3117,17 @@ doContent(XML_Parser parser,
return XML_ERROR_NO_MEMORY;
break;
default:
+ /* All of the tokens produced by XmlContentTok() have their own
+ * explicit cases, so this default is not strictly necessary.
+ * However it is a useful safety net, so we retain the code and
+ * simply exclude it from the coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
+ /* LCOV_EXCL_STOP */
}
*eventPP = s = next;
switch (ps_parsing) {
@@ -3067,13 +3218,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
#endif
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
- if (temp == NULL)
+ if (temp == NULL) {
+ attsSize = oldAttsSize;
return XML_ERROR_NO_MEMORY;
+ }
atts = temp;
#ifdef XML_ATTR_INFO
temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
- if (temp2 == NULL)
+ if (temp2 == NULL) {
+ attsSize = oldAttsSize;
return XML_ERROR_NO_MEMORY;
+ }
attInfo = temp2;
#endif
if (n > oldAttsSize)
@@ -3210,6 +3365,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
int j; /* hash table index */
unsigned long version = nsAttsVersion;
int nsAttsSize = (int)1 << nsAttsPower;
+ unsigned char oldNsAttsPower = nsAttsPower;
/* size of hash table must be at least 2 * (# of prefixed attributes) */
if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
NS_ATT *temp;
@@ -3219,8 +3375,11 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
nsAttsPower = 3;
nsAttsSize = (int)1 << nsAttsPower;
temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
- if (!temp)
+ if (!temp) {
+ /* Restore actual size of memory in nsAtts */
+ nsAttsPower = oldNsAttsPower;
return XML_ERROR_NO_MEMORY;
+ }
nsAtts = temp;
version = 0; /* force re-initialization of nsAtts hash table */
}
@@ -3247,8 +3406,23 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
((XML_Char *)s)[-1] = 0; /* clear flag */
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
- if (!id || !id->prefix)
- return XML_ERROR_NO_MEMORY;
+ if (!id || !id->prefix) {
+ /* This code is walking through the appAtts array, dealing
+ * with (in this case) a prefixed attribute name. To be in
+ * the array, the attribute must have already been bound, so
+ * has to have passed through the hash table lookup once
+ * already. That implies that an entry for it already
+ * exists, so the lookup above will return a pointer to
+ * already allocated memory. There is no opportunaity for
+ * the allocator to fail, so the condition above cannot be
+ * fulfilled.
+ *
+ * Since it is difficult to be certain that the above
+ * analysis is complete, we retain the test and merely
+ * remove the code from coverage tests.
+ */
+ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
+ }
b = id->prefix->binding;
if (!b)
return XML_ERROR_UNBOUND_PREFIX;
@@ -3625,8 +3799,16 @@ doCdataSection(XML_Parser parser,
}
return XML_ERROR_UNCLOSED_CDATA_SECTION;
default:
+ /* Every token returned by XmlCdataSectionTok() has its own
+ * explicit case, so this default case will never be executed.
+ * We retain it as a safety net and exclude it from the coverage
+ * statistics.
+ *
+ * LCOV_EXCL_START
+ */
*eventPP = next;
return XML_ERROR_UNEXPECTED_STATE;
+ /* LCOV_EXCL_STOP */
}
*eventPP = s = next;
@@ -3686,8 +3868,20 @@ doIgnoreSection(XML_Parser parser,
eventEndPP = &eventEndPtr;
}
else {
+ /* It's not entirely clear, but it seems the following two lines
+ * of code cannot be executed. The only occasions on which 'enc'
+ * is not 'parser->m_encoding' are when this function is called
+ * from the internal entity processing, and IGNORE sections are an
+ * error in internal entities.
+ *
+ * Since it really isn't clear that this is true, we keep the code
+ * and just remove it from our coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
eventPP = &(openInternalEntities->internalEventPtr);
eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ /* LCOV_EXCL_STOP */
}
*eventPP = s;
*startPtr = NULL;
@@ -3720,8 +3914,16 @@ doIgnoreSection(XML_Parser parser,
}
return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
default:
+ /* All of the tokens that XmlIgnoreSectionTok() returns have
+ * explicit cases to handle them, so this default case is never
+ * executed. We keep it as a safety net anyway, and remove it
+ * from our test coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
*eventPP = next;
return XML_ERROR_UNEXPECTED_STATE;
+ /* LCOV_EXCL_STOP */
}
/* not reached */
}
@@ -3734,6 +3936,7 @@ initializeEncoding(XML_Parser parser)
const char *s;
#ifdef XML_UNICODE
char encodingBuf[128];
+ /* See comments abount `protoclEncodingName` in parserInit() */
if (!protocolEncodingName)
s = NULL;
else {
@@ -3817,7 +4020,14 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
reportDefault(parser, encoding, s, next);
if (protocolEncodingName == NULL) {
if (newEncoding) {
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+ /* Check that the specified encoding does not conflict with what
+ * the parser has already deduced. Do we have the same number
+ * of bytes in the smallest representation of a character? If
+ * this is UTF-16, is it the same endianness?
+ */
+ if (newEncoding->minBytesPerChar != encoding->minBytesPerChar
+ || (newEncoding->minBytesPerChar == 2 &&
+ newEncoding != encoding)) {
eventPtr = encodingName;
return XML_ERROR_INCORRECT_ENCODING;
}
@@ -3962,15 +4172,14 @@ entityValueInitProcessor(XML_Parser parser,
result = processXmlDecl(parser, 0, start, next);
if (result != XML_ERROR_NONE)
return result;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
+ /* At this point, ps_parsing cannot be XML_SUSPENDED. For that
+ * to happen, a parameter entity parsing handler must have
+ * attempted to suspend the parser, which fails and raises an
+ * error. The parser can be aborted, but can't be suspended.
+ */
+ if (ps_parsing == XML_FINISHED)
return XML_ERROR_ABORTED;
- default:
- *nextPtr = next;
- }
+ *nextPtr = next;
/* stop scanning for text declaration - we found one */
processor = entityValueProcessor;
return entityValueProcessor(parser, next, end, nextPtr);
@@ -4293,8 +4502,14 @@ doProlog(XML_Parser parser,
&dtd->paramEntities,
externalSubsetName,
sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
+ if (!entity) {
+ /* The external subset name "#" will have already been
+ * inserted into the hash table at the start of the
+ * external entity parsing, so no allocation will happen
+ * and lookup() cannot fail.
+ */
+ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
+ }
if (useForeignDTD)
entity->base = curBase;
dtd->paramEntityRead = XML_FALSE;
@@ -4773,8 +4988,10 @@ doProlog(XML_Parser parser,
if (prologState.level >= groupSize) {
if (groupSize) {
char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
- if (temp == NULL)
+ if (temp == NULL) {
+ groupSize /= 2;
return XML_ERROR_NO_MEMORY;
+ }
groupConnector = temp;
if (dtd->scaffIndex) {
int *temp = (int *)REALLOC(dtd->scaffIndex,
@@ -4786,8 +5003,10 @@ doProlog(XML_Parser parser,
}
else {
groupConnector = (char *)MALLOC(groupSize = 32);
- if (!groupConnector)
+ if (!groupConnector) {
+ groupSize = 0;
return XML_ERROR_NO_MEMORY;
+ }
}
}
groupConnector[prologState.level] = 0;
@@ -4850,8 +5069,29 @@ doProlog(XML_Parser parser,
: !dtd->hasParamEntityRefs)) {
if (!entity)
return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ else if (!entity->is_internal) {
+ /* It's hard to exhaustively search the code to be sure,
+ * but there doesn't seem to be a way of executing the
+ * following line. There are two cases:
+ *
+ * If 'standalone' is false, the DTD must have no
+ * parameter entities or we wouldn't have passed the outer
+ * 'if' statement. That measn the only entity in the hash
+ * table is the external subset name "#" which cannot be
+ * given as a parameter entity name in XML syntax, so the
+ * lookup must have returned NULL and we don't even reach
+ * the test for an internal entity.
+ *
+ * If 'standalone' is true, it does not seem to be
+ * possible to create entities taking this code path that
+ * are not internal entities, so fail the test above.
+ *
+ * Because this analysis is very uncertain, the code is
+ * being left in place and merely removed from the
+ * coverage test statistics.
+ */
+ return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
+ }
}
else if (!entity) {
dtd->keepProcessing = dtd->standalone;
@@ -5323,11 +5563,15 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
&& (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
break;
n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
+ /* The XmlEncode() functions can never return 0 here. That
+ * error return happens if the code point passed in is either
+ * negative or greater than or equal to 0x110000. The
+ * XmlCharRefNumber() functions will all return a number
+ * strictly less than 0x110000 or a negative value if an error
+ * occurred. The negative value is intercepted above, so
+ * XmlEncode() is never passed a value it might return an
+ * error for.
+ */
for (i = 0; i < n; i++) {
if (!poolAppendChar(pool, buf[i]))
return XML_ERROR_NO_MEMORY;
@@ -5401,8 +5645,26 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
break;
}
if (entity->open) {
- if (enc == encoding)
- eventPtr = ptr;
+ if (enc == encoding) {
+ /* It does not appear that this line can be executed.
+ *
+ * The "if (entity->open)" check catches recursive entity
+ * definitions. In order to be called with an open
+ * entity, it must have gone through this code before and
+ * been through the recursive call to
+ * appendAttributeValue() some lines below. That call
+ * sets the local encoding ("enc") to the parser's
+ * internal encoding (internal_utf8 or internal_utf16),
+ * which can never be the same as the principle encoding.
+ * It doesn't appear there is another code path that gets
+ * here with entity->open being TRUE.
+ *
+ * Since it is not certain that this logic is watertight,
+ * we keep the line and merely exclude it from coverage
+ * tests.
+ */
+ eventPtr = ptr; /* LCOV_EXCL_LINE */
+ }
return XML_ERROR_RECURSIVE_ENTITY_REF;
}
if (entity->notation) {
@@ -5429,9 +5691,21 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
}
break;
default:
+ /* The only token returned by XmlAttributeValueTok() that does
+ * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
+ * Getting that would require an entity name to contain an
+ * incomplete XML character (e.g. \xE2\x82); however previous
+ * tokenisers will have already recognised and rejected such
+ * names before XmlAttributeValueTok() gets a look-in. This
+ * default case should be retained as a safety net, but the code
+ * excluded from coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_UNEXPECTED_STATE;
+ /* LCOV_EXCL_STOP */
}
ptr = next;
}
@@ -5564,12 +5838,15 @@ storeEntityValue(XML_Parser parser,
goto endEntityValue;
}
n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
+ /* The XmlEncode() functions can never return 0 here. That
+ * error return happens if the code point passed in is either
+ * negative or greater than or equal to 0x110000. The
+ * XmlCharRefNumber() functions will all return a number
+ * strictly less than 0x110000 or a negative value if an error
+ * occurred. The negative value is intercepted above, so
+ * XmlEncode() is never passed a value it might return an
+ * error for.
+ */
for (i = 0; i < n; i++) {
if (pool->end == pool->ptr && !poolGrow(pool)) {
result = XML_ERROR_NO_MEMORY;
@@ -5590,10 +5867,18 @@ storeEntityValue(XML_Parser parser,
result = XML_ERROR_INVALID_TOKEN;
goto endEntityValue;
default:
+ /* This default case should be unnecessary -- all the tokens
+ * that XmlEntityValueTok() can return have their own explicit
+ * cases -- but should be retained for safety. We do however
+ * exclude it from the coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
if (enc == encoding)
eventPtr = entityTextPtr;
result = XML_ERROR_UNEXPECTED_STATE;
goto endEntityValue;
+ /* LCOV_EXCL_STOP */
}
entityTextPtr = next;
}
@@ -5691,8 +5976,25 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
eventEndPP = &eventEndPtr;
}
else {
+ /* To get here, two things must be true; the parser must be
+ * using a character encoding that is not the same as the
+ * encoding passed in, and the encoding passed in must need
+ * conversion to the internal format (UTF-8 unless XML_UNICODE
+ * is defined). The only occasions on which the encoding passed
+ * in is not the same as the parser's encoding are when it is
+ * the internal encoding (e.g. a previously defined parameter
+ * entity, already converted to internal format). This by
+ * definition doesn't need conversion, so the whole branch never
+ * gets executed.
+ *
+ * For safety's sake we don't delete these lines and merely
+ * exclude them from coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
eventPP = &(openInternalEntities->internalEventPtr);
eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ /* LCOV_EXCL_STOP */
}
do {
ICHAR *dataPtr = (ICHAR *)dataBuf;
@@ -5861,9 +6163,30 @@ getContext(XML_Parser parser)
len = dtd->defaultPrefix.binding->uriLen;
if (namespaceSeparator)
len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
- return NULL;
+ for (i = 0; i < len; i++) {
+ if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) {
+ /* Because of memory caching, I don't believe this line can be
+ * executed.
+ *
+ * This is part of a loop copying the default prefix binding
+ * URI into the parser's temporary string pool. Previously,
+ * that URI was copied into the same string pool, with a
+ * terminating NUL character, as part of setContext(). When
+ * the pool was cleared, that leaves a block definitely big
+ * enough to hold the URI on the free block list of the pool.
+ * The URI copy in getContext() therefore cannot run out of
+ * memory.
+ *
+ * If the pool is used between the setContext() and
+ * getContext() calls, the worst it can do is leave a bigger
+ * block on the front of the free list. Given that this is
+ * all somewhat inobvious and program logic can be changed, we
+ * don't delete the line but we do exclude it from the test
+ * coverage statistics.
+ */
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ }
needSep = XML_TRUE;
}
@@ -5875,8 +6198,15 @@ getContext(XML_Parser parser)
PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
if (!prefix)
break;
- if (!prefix->binding)
- continue;
+ if (!prefix->binding) {
+ /* This test appears to be (justifiable) paranoia. There does
+ * not seem to be a way of injecting a prefix without a binding
+ * that doesn't get errored long before this function is called.
+ * The test should remain for safety's sake, so we instead
+ * exclude the following line from the coverage statistics.
+ */
+ continue; /* LCOV_EXCL_LINE */
+ }
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
return NULL;
for (s = prefix->name; *s; s++)
@@ -6547,8 +6877,20 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s)
static const XML_Char *
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
{
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
+ if (!pool->ptr && !poolGrow(pool)) {
+ /* The following line is unreachable given the current usage of
+ * poolCopyStringN(). Currently it is called from exactly one
+ * place to copy the text of a simple general entity. By that
+ * point, the name of the entity is already stored in the pool, so
+ * pool->ptr cannot be NULL.
+ *
+ * If poolCopyStringN() is used elsewhere as it well might be,
+ * this line may well become executable again. Regardless, this
+ * sort of check shouldn't be removed lightly, so we just exclude
+ * it from the coverage statistics.
+ */
+ return NULL; /* LCOV_EXCL_LINE */
+ }
for (; n > 0; --n, s++) {
if (!poolAppendChar(pool, *s))
return NULL;
@@ -6641,8 +6983,19 @@ poolGrow(STRING_POOL *pool)
int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
size_t bytesToAllocate;
- if (blockSize < 0)
- return XML_FALSE;
+ // NOTE: Needs to be calculated prior to calling `realloc`
+ // to avoid dangling pointers:
+ const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
+
+ if (blockSize < 0) {
+ /* This condition traps a situation where either more than
+ * INT_MAX/2 bytes have already been allocated. This isn't
+ * readily testable, since it is unlikely that an average
+ * machine will have that much memory, so we exclude it from the
+ * coverage statistics.
+ */
+ return XML_FALSE; /* LCOV_EXCL_LINE */
+ }
bytesToAllocate = poolBytesToAllocateFor(blockSize);
if (bytesToAllocate == 0)
@@ -6654,7 +7007,7 @@ poolGrow(STRING_POOL *pool)
return XML_FALSE;
pool->blocks = temp;
pool->blocks->size = blockSize;
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->ptr = pool->blocks->s + offsetInsideBlock;
pool->start = pool->blocks->s;
pool->end = pool->start + blockSize;
}
@@ -6663,8 +7016,18 @@ poolGrow(STRING_POOL *pool)
int blockSize = (int)(pool->end - pool->start);
size_t bytesToAllocate;
- if (blockSize < 0)
- return XML_FALSE;
+ if (blockSize < 0) {
+ /* This condition traps a situation where either more than
+ * INT_MAX bytes have already been allocated (which is prevented
+ * by various pieces of program logic, not least this one, never
+ * mind the unlikelihood of actually having that much memory) or
+ * the pool control fields have been corrupted (which could
+ * conceivably happen in an extremely buggy user handler
+ * function). Either way it isn't readily testable, so we
+ * exclude it from the coverage statistics.
+ */
+ return XML_FALSE; /* LCOV_EXCL_LINE */
+ }
if (blockSize < INIT_BLOCK_SIZE)
blockSize = INIT_BLOCK_SIZE;
@@ -6827,3 +7190,26 @@ getElementType(XML_Parser parser,
}
return ret;
}
+
+static XML_Char *
+copyString(const XML_Char *s,
+ const XML_Memory_Handling_Suite *memsuite)
+{
+ int charsRequired = 0;
+ XML_Char *result;
+
+ /* First determine how long the string is */
+ while (s[charsRequired] != 0) {
+ charsRequired++;
+ }
+ /* Include the terminator */
+ charsRequired++;
+
+ /* Now allocate space for the copy */
+ result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
+ if (result == NULL)
+ return NULL;
+ /* Copy the original into place */
+ memcpy(result, s, charsRequired * sizeof(XML_Char));
+ return result;
+}
diff --git a/Utilities/cmexpat/lib/xmlrole.c b/Utilities/cmexpat/lib/xmlrole.c
index a7c5630..c809ee5 100644
--- a/Utilities/cmexpat/lib/xmlrole.c
+++ b/Utilities/cmexpat/lib/xmlrole.c
@@ -170,7 +170,14 @@ prolog1(PROLOG_STATE *state,
case XML_TOK_COMMENT:
return XML_ROLE_COMMENT;
case XML_TOK_BOM:
- return XML_ROLE_NONE;
+ /* This case can never arise. To reach this role function, the
+ * parse must have passed through prolog0 and therefore have had
+ * some form of input, even if only a space. At that point, a
+ * byte order mark is no longer a valid character (though
+ * technically it should be interpreted as a non-breaking space),
+ * so will be rejected by the tokenizing stages.
+ */
+ return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
case XML_TOK_DECL_OPEN:
if (!XmlNameMatchesAscii(enc,
ptr + 2 * MIN_BYTES_PER_CHAR(enc),
@@ -1285,6 +1292,26 @@ declClose(PROLOG_STATE *state,
return common(state, tok);
}
+/* This function will only be invoked if the internal logic of the
+ * parser has broken down. It is used in two cases:
+ *
+ * 1: When the XML prolog has been finished. At this point the
+ * processor (the parser level above these role handlers) should
+ * switch from prologProcessor to contentProcessor and reinitialise
+ * the handler function.
+ *
+ * 2: When an error has been detected (via common() below). At this
+ * point again the processor should be switched to errorProcessor,
+ * which will never call a handler.
+ *
+ * The result of this is that error() can only be called if the
+ * processor switch failed to happen, which is an internal error and
+ * therefore we shouldn't be able to provoke it simply by using the
+ * library. It is a necessary backstop, however, so we merely exclude
+ * it from the coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
static int PTRCALL
error(PROLOG_STATE *UNUSED_P(state),
int UNUSED_P(tok),
@@ -1294,6 +1321,7 @@ error(PROLOG_STATE *UNUSED_P(state),
{
return XML_ROLE_NONE;
}
+/* LCOV_EXCL_STOP */
static int FASTCALL
common(PROLOG_STATE *state, int tok)
diff --git a/Utilities/cmexpat/lib/xmltok.c b/Utilities/cmexpat/lib/xmltok.c
index cdf0720..db4a5c8 100644
--- a/Utilities/cmexpat/lib/xmltok.c
+++ b/Utilities/cmexpat/lib/xmltok.c
@@ -1019,7 +1019,11 @@ streqci(const char *s1, const char *s2)
if (ASCII_a <= c1 && c1 <= ASCII_z)
c1 += ASCII_A - ASCII_a;
if (ASCII_a <= c2 && c2 <= ASCII_z)
- c2 += ASCII_A - ASCII_a;
+ /* The following line will never get executed. streqci() is
+ * only called from two places, both of which guarantee to put
+ * upper-case strings into s2.
+ */
+ c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
if (c1 != c2)
return 0;
if (!c1)
@@ -1291,7 +1295,7 @@ XmlUtf8Encode(int c, char *buf)
};
if (c < 0)
- return 0;
+ return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
if (c < min2) {
buf[0] = (char)(c | UTF8_cval1);
return 1;
@@ -1314,7 +1318,7 @@ XmlUtf8Encode(int c, char *buf)
buf[3] = (char)((c & 0x3f) | 0x80);
return 4;
}
- return 0;
+ return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
}
int FASTCALL
@@ -1465,6 +1469,9 @@ XmlInitUnknownEncoding(void *mem,
else if (c < 0) {
if (c < -4)
return 0;
+ /* Multi-byte sequences need a converter function */
+ if (!convert)
+ return 0;
e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
e->utf8[i][0] = 0;
e->utf16[i] = 0;
diff --git a/Utilities/cmexpat/lib/xmltok_impl.c b/Utilities/cmexpat/lib/xmltok_impl.c
index 5f779c0..4fa1ff6 100644
--- a/Utilities/cmexpat/lib/xmltok_impl.c
+++ b/Utilities/cmexpat/lib/xmltok_impl.c
@@ -1198,8 +1198,14 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
const char *start;
if (ptr >= end)
return XML_TOK_NONE;
- else if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_PARTIAL;
+ else if (! HAS_CHAR(enc, ptr, end)) {
+ /* This line cannot be executed. The incoming data has already
+ * been tokenized once, so incomplete characters like this have
+ * already been eliminated from the input. Retaining the paranoia
+ * check is still valuable, however.
+ */
+ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
+ }
start = ptr;
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
@@ -1258,8 +1264,14 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
const char *start;
if (ptr >= end)
return XML_TOK_NONE;
- else if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_PARTIAL;
+ else if (! HAS_CHAR(enc, ptr, end)) {
+ /* This line cannot be executed. The incoming data has already
+ * been tokenized once, so incomplete characters like this have
+ * already been eliminated from the input. Retaining the paranoia
+ * check is still valuable, however.
+ */
+ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
+ }
start = ptr;
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
@@ -1614,6 +1626,14 @@ PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
return 0;
}
+/* This function does not appear to be called from anywhere within the
+ * library code. It is used via the macro XmlSameName(), which is
+ * defined but never used. Since it appears in the encoding function
+ * table, removing it is not a thing to be undertaken lightly. For
+ * the moment, we simply exclude it from coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
static int PTRCALL
PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
{
@@ -1677,14 +1697,21 @@ PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
}
/* not reached */
}
+/* LCOV_EXCL_STOP */
static int PTRCALL
PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
const char *end1, const char *ptr2)
{
for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
- if (end1 - ptr1 < MINBPC(enc))
- return 0;
+ if (end1 - ptr1 < MINBPC(enc)) {
+ /* This line cannot be executed. THe incoming data has already
+ * been tokenized once, so imcomplete characters like this have
+ * already been eliminated from the input. Retaining the
+ * paranoia check is still valuable, however.
+ */
+ return 0; /* LCOV_EXCL_LINE */
+ }
if (!CHAR_MATCHES(enc, ptr1, *ptr2))
return 0;
}
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index bfe6b13..206f3c6 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -422,6 +422,7 @@ int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS)
LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
+LA_CHECK_INCLUDE_FILE("membership.h" HAVE_MEMBERSHIP_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)
@@ -439,11 +440,13 @@ 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/extattr.h" HAVE_SYS_EXTATTR_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/richacl.h" HAVE_SYS_RICHACL_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)
@@ -453,6 +456,7 @@ 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("sys/xattr.h" HAVE_SYS_XATTR_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)
@@ -461,6 +465,9 @@ LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
IF(ENABLE_CNG)
LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
+ IF(HAVE_BCRYPT_H)
+ LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
+ ENDIF(HAVE_BCRYPT_H)
ELSE(ENABLE_CNG)
UNSET(HAVE_BCRYPT_H CACHE)
ENDIF(ENABLE_CNG)
@@ -924,7 +931,6 @@ 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)
@@ -1024,6 +1030,10 @@ 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)
+# dirfd can be either a function or a macro.
+CHECK_C_SOURCE_COMPILES(
+ "#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); return dirfd(d);}"
+ HAVE_DIRFD)
# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
# NOTE: linux requires fcntl.h for AT_FDCWD.
@@ -1256,60 +1266,105 @@ 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)
+ CHECK_SYMBOL_EXISTS(XATTR_NOFOLLOW "sys/xattr.h" HAVE_DECL_XATTR_NOFOLLOW)
+ IF(HAVE_SYS_XATTR_H AND HAVE_DECL_XATTR_NOFOLLOW)
+ CHECK_FUNCTION_EXISTS(fgetxattr HAVE_FGETXATTR)
+ CHECK_FUNCTION_EXISTS(flistxattr HAVE_FLISTXATTR)
+ CHECK_FUNCTION_EXISTS(fsetxattr HAVE_FSETXATTR)
+ CHECK_FUNCTION_EXISTS(getxattr HAVE_GETXATTR)
+ CHECK_FUNCTION_EXISTS(listxattr HAVE_LISTXATTR)
+ CHECK_FUNCTION_EXISTS(setxattr HAVE_SETXATTR)
+ IF(HAVE_FGETXATTR AND
+ HAVE_FLISTXATTR AND
+ HAVE_FSETXATTR AND
+ HAVE_GETXATTR AND
+ HAVE_LISTXATTR AND
+ HAVE_SETXATTR)
+ SET(ARCHIVE_XATTR_DARWIN TRUE)
+ ENDIF()
+ ELSEIF(HAVE_SYS_EXTATTR_H AND HAVE_DECL_EXTATTR_NAMESPACE_USER)
+ # FreeBSD xattr support
+ CHECK_FUNCTION_EXISTS(extattr_get_fd HAVE_EXTATTR_GET_FD)
+ CHECK_FUNCTION_EXISTS(extattr_get_file HAVE_EXTATTR_GET_FILE)
+ CHECK_FUNCTION_EXISTS(extattr_get_link HAVE_EXTATTR_GET_LINK)
+ CHECK_FUNCTION_EXISTS(extattr_list_fd HAVE_EXTATTR_LIST_FD)
+ CHECK_FUNCTION_EXISTS(extattr_list_file HAVE_EXTATTR_LIST_FILE)
+ CHECK_FUNCTION_EXISTS(extattr_list_link HAVE_EXTATTR_LIST_LINK)
+ CHECK_FUNCTION_EXISTS(extattr_set_fd HAVE_EXTATTR_SET_FD)
+ CHECK_FUNCTION_EXISTS(extattr_set_link HAVE_EXTATTR_SET_LINK)
+ IF(HAVE_EXTATTR_GET_FD AND
+ HAVE_EXTATTR_GET_FILE AND
+ HAVE_EXTATTR_GET_LINK AND
+ HAVE_EXTATTR_LIST_FD AND
+ HAVE_EXTATTR_LIST_FILE AND
+ HAVE_EXTATTR_LIST_LINK AND
+ HAVE_EXTATTR_SET_FD AND
+ HAVE_EXTATTR_SET_LINK)
+ SET(ARCHIVE_XATTR_FREEBSD TRUE)
+ ENDIF()
+ ELSEIF(HAVE_SYS_XATTR_H OR HAVE_ATTR_XATTR_H)
+ # Linux xattr support
+ 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)
+ IF(HAVE_FGETXATTR AND
+ HAVE_FLISTXATTR AND
+ HAVE_FSETXATTR AND
+ HAVE_GETXATTR AND
+ HAVE_LGETXATTR AND
+ HAVE_LISTXATTR AND
+ HAVE_LLISTXATTR AND
+ HAVE_LSETXATTR)
+ SET(ARCHIVE_XATTR_LINUX TRUE)
+ ENDIF()
+ ELSEIF(HAVE_SYS_EA_H)
+ # AIX xattr support
+ CHECK_FUNCTION_EXISTS(fgetea HAVE_FGETEA)
+ CHECK_FUNCTION_EXISTS(flistea HAVE_FLISTEA)
+ CHECK_FUNCTION_EXISTS(fsetea HAVE_FSETEA)
+ CHECK_FUNCTION_EXISTS(getea HAVE_GETEA)
+ CHECK_FUNCTION_EXISTS(lgetea HAVE_LGETEA)
+ CHECK_FUNCTION_EXISTS(listea HAVE_LISTEA)
+ CHECK_FUNCTION_EXISTS(llistea HAVE_LLISTEA)
+ CHECK_FUNCTION_EXISTS(lsetea HAVE_LSETEA)
+ IF(HAVE_FGETEA AND
+ HAVE_FLISTEA AND
+ HAVE_FSETEA AND
+ HAVE_GETEA AND
+ HAVE_LGETEA AND
+ HAVE_LISTEA AND
+ HAVE_LLISTEA AND
+ HAVE_LSETEA)
+ SET(ARCHIVE_XATTR_AIX TRUE)
+ ENDIF()
+ ENDIF()
+
+ IF(ARCHIVE_XATTR_DARWIN)
+ MESSAGE(STATUS "Extended attributes support: Darwin")
+ ELSEIF(ARCHIVE_XATTR_FREEBSD)
+ MESSAGE(STATUS "Extended attributes support: FreeBSD")
+ ELSEIF(ARCHIVE_XATTR_LINUX)
+ MESSAGE(STATUS "Extended attributes support: Linux")
+ ELSEIF(ARCHIVE_XATTR_AIX)
+ MESSAGE(STATUS "Extended attributes support: AIX")
+ ELSE()
+ MESSAGE(STATUS "Extended attributes support: none")
+ ENDIF()
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)
+ SET(ARCHIVE_XATTR_DARWIN FALSE)
+ SET(ARCHIVE_XATTR_FREEBSD FALSE)
+ SET(ARCHIVE_XATTR_LINUX FALSE)
+ SET(ARCHIVE_XATTR_AIX FALSE)
ENDIF(ENABLE_XATTR)
#
@@ -1321,78 +1376,212 @@ ENDIF(ENABLE_XATTR)
# which makes the following checks rather more complex than I would like.
#
IF(ENABLE_ACL)
+ # Solaris and derivates ACLs
+ CHECK_FUNCTION_EXISTS(acl HAVE_ACL)
+ CHECK_FUNCTION_EXISTS(facl HAVE_FACL)
+
+ # Libacl
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_fd_np HAVE_ACL_GET_FD_NP)
- CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
- CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
- CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
- CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
- CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
- CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
- CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "${INCLUDES}" HAVE_ACL_TYPE_NFS4)
-
- # 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)
- CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
+
+ CHECK_TYPE_EXISTS(acl_t "sys/types.h;sys/acl.h" HAVE_ACL_T)
+ CHECK_TYPE_EXISTS(acl_entry_t "sys/types.h;sys/acl.h" HAVE_ACL_ENTRY_T)
+ CHECK_TYPE_EXISTS(acl_permset_t "sys/types.h;sys/acl.h" HAVE_ACL_PERMSET_T)
+ CHECK_TYPE_EXISTS(acl_tag_t "sys/types.h;sys/acl.h" HAVE_ACL_TAG_T)
+
+ IF(HAVE_ACL AND HAVE_FACL)
+ CHECK_TYPE_EXISTS(aclent_t "sys/acl.h" HAVE_ACLENT_T)
+ IF(HAVE_ACLENT_T)
+ CHECK_SYMBOL_EXISTS(GETACL "sys/acl.h" HAVE_DECL_GETACL)
+ CHECK_SYMBOL_EXISTS(GETACLCNT "sys/acl.h" HAVE_DECL_GETACLCNT)
+ CHECK_SYMBOL_EXISTS(SETACL "sys/acl.h" HAVE_DECL_SETACL)
+ IF(HAVE_DECL_GETACL AND
+ HAVE_DECL_GETACLCNT AND
+ HAVE_DECL_SETACL)
+ SET(ARCHIVE_ACL_SUNOS TRUE)
+ ENDIF()
+ CHECK_TYPE_EXISTS(ace_t "sys/acl.h" HAVE_ACE_T)
+ IF(HAVE_ACE_T)
+ CHECK_SYMBOL_EXISTS(ACE_GETACL "sys/acl.h" HAVE_DECL_ACE_GETACL)
+ CHECK_SYMBOL_EXISTS(ACE_GETACLCNT "sys/acl.h" HAVE_DECL_ACE_GETACLCNT)
+ CHECK_SYMBOL_EXISTS(ACE_SETACL "sys/acl.h" HAVE_DECL_ACE_SETACL)
+ IF(HAVE_DECL_ACE_GETACL AND
+ HAVE_DECL_ACE_GETACLCNT AND
+ HAVE_DECL_ACE_SETACL)
+ SET(ARCHIVE_ACL_SUNOS_NFS4 TRUE)
+ ENDIF()
+ ENDIF(HAVE_ACE_T)
+ ENDIF(HAVE_ACLENT_T)
+ ENDIF(HAVE_ACL AND HAVE_FACL)
+
+ IF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND HAVE_ACL_TAG_T)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_add_perm HAVE_ACL_ADD_PERM)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_clear_perms HAVE_ACL_CLEAR_PERMS)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_delete_def_file HAVE_ACL_DELETE_DEF_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_free HAVE_ACL_FREE)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_entry HAVE_ACL_GET_ENTRY)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_fd HAVE_ACL_GET_FD)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_file HAVE_ACL_GET_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_permset HAVE_ACL_GET_PERMSET)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_qualifier HAVE_ACL_GET_QUALIFIER)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_tag_type HAVE_ACL_GET_TAG_TYPE)
+ 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_file HAVE_ACL_SET_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_set_qualifier HAVE_ACL_SET_QUALIFIER)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_set_tag_type HAVE_ACL_SET_TAG_TYPE)
+ IF(HAVE_ACL_ADD_PERM AND
+ HAVE_ACL_CLEAR_PERMS AND
+ HAVE_ACL_CREATE_ENTRY AND
+ HAVE_ACL_DELETE_DEF_FILE AND
+ HAVE_ACL_FREE AND
+ HAVE_ACL_GET_ENTRY AND
+ HAVE_ACL_GET_FD AND
+ HAVE_ACL_GET_FILE AND
+ HAVE_ACL_GET_PERMSET AND
+ HAVE_ACL_GET_QUALIFIER AND
+ HAVE_ACL_GET_TAG_TYPE AND
+ HAVE_ACL_INIT AND
+ HAVE_ACL_SET_FD AND
+ HAVE_ACL_SET_FILE AND
+ HAVE_ACL_SET_QUALIFIER AND
+ HAVE_ACL_SET_TAG_TYPE)
+ SET(HAVE_POSIX_ACL_FUNCS 1)
+ ENDIF()
+
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_get_perm HAVE_ACL_GET_PERM)
+
+ IF(HAVE_POSIX_ACL_FUNCS AND HAVE_ACL_LIBACL_H AND HAVE_LIBACL AND
+ HAVE_ACL_GET_PERM)
+ SET(ARCHIVE_ACL_LIBACL TRUE)
+ ELSE()
+ CHECK_FUNCTION_EXISTS(acl_add_flag_np HAVE_ACL_ADD_FLAG_NP)
+ CHECK_FUNCTION_EXISTS(acl_clear_flags_np HAVE_ACL_CLEAR_FLAGS_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_brand_np HAVE_ACL_GET_BRAND_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_entry_type_np HAVE_ACL_GET_ENTRY_TYPE_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_flag_np HAVE_ACL_GET_FLAG_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_flagset_np HAVE_ACL_GET_FLAGSET_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_fd_np HAVE_ACL_GET_FD_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
+ CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
+ CHECK_FUNCTION_EXISTS(acl_set_entry_type_np HAVE_ACL_SET_ENTRY_TYPE_NP)
+ CHECK_FUNCTION_EXISTS(acl_set_fd_np HAVE_ACL_SET_FD_NP)
+ CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
+ CHECK_FUNCTION_EXISTS(mbr_gid_to_uuid HAVE_MBR_GID_TO_UUID)
+ CHECK_FUNCTION_EXISTS(mbr_uid_to_uuid HAVE_MBR_UID_TO_UUID)
+ CHECK_FUNCTION_EXISTS(mbr_uuid_to_id HAVE_MBR_UUID_TO_ID)
+
+ CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
#include <sys/acl.h>
-int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_ACL_TYPE_EXTENDED)
+int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_DECL_ACL_TYPE_EXTENDED)
+ CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
+#include <sys/acl.h>
+int main(void) { return ACL_SYNCHRONIZE; }" HAVE_DECL_ACL_SYNCHRONIZE)
+ CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "sys/acl.h" HAVE_DECL_ACL_TYPE_NFS4)
+ CHECK_SYMBOL_EXISTS(ACL_USER "sys/acl.h" HAVE_DECL_ACL_USER)
+
+ IF(HAVE_POSIX_ACL_FUNCS AND
+ HAVE_ACL_GET_FD_NP AND
+ HAVE_ACL_GET_PERM_NP AND
+ NOT HAVE_ACL_GET_PERM AND
+ HAVE_ACL_SET_FD_NP)
+ IF(HAVE_DECL_ACL_USER)
+ SET(ARCHIVE_ACL_FREEBSD TRUE)
+ IF(HAVE_DECL_ACL_TYPE_NFS4 AND
+ HAVE_ACL_ADD_FLAG_NP AND
+ HAVE_ACL_CLEAR_FLAGS_NP AND
+ HAVE_ACL_GET_BRAND_NP AND
+ HAVE_ACL_GET_ENTRY_TYPE_NP AND
+ HAVE_ACL_GET_FLAGSET_NP AND
+ HAVE_ACL_SET_ENTRY_TYPE_NP)
+ SET(ARCHIVE_ACL_FREEBSD_NFS4 TRUE)
+ ENDIF()
+ ELSEIF(HAVE_DECL_ACL_TYPE_EXTENDED AND
+ HAVE_MEMBERSHIP_H AND
+ HAVE_ACL_ADD_FLAG_NP AND
+ HAVE_ACL_CLEAR_FLAGS_NP AND
+ HAVE_ACL_GET_FLAGSET_NP AND
+ HAVE_ACL_GET_LINK_NP AND
+ HAVE_ACL_SET_LINK_NP AND
+ HAVE_MBR_UID_TO_UUID AND
+ HAVE_MBR_GID_TO_UUID AND
+ HAVE_MBR_UUID_TO_ID)
+ SET(ARCHIVE_ACL_DARWIN TRUE)
+ ENDIF()
+ ENDIF()
+ ENDIF()
+ ENDIF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND
+ HAVE_ACL_TAG_T)
+
+ # Richacl
+ CHECK_LIBRARY_EXISTS(richacl "richacl_get_file" "" HAVE_LIBRICHACL)
+ IF(HAVE_LIBRICHACL)
+ SET(CMAKE_REQUIRED_LIBRARIES "richacl")
+ FIND_LIBRARY(RICHACL_LIBRARY NAMES richacl)
+ LIST(APPEND ADDITIONAL_LIBS ${RICHACL_LIBRARY})
+ ENDIF(HAVE_LIBRICHACL)
+
+ CHECK_STRUCT_HAS_MEMBER("struct richace" e_type "sys/richacl.h"
+ HAVE_STRUCT_RICHACE)
+ CHECK_STRUCT_HAS_MEMBER("struct richacl" a_flags "sys/richacl.h"
+ HAVE_STRUCT_RICHACL)
+
+ IF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_alloc HAVE_RICHACL_ALLOC)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_equiv_mode HAVE_RICHACL_EQUIV_MODE)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_free HAVE_RICHACL_FREE)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_fd HAVE_RICHACL_GET_FD)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_file HAVE_RICHACL_GET_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_fd HAVE_RICHACL_SET_FD)
+ CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_file HAVE_RICHACL_SET_FILE)
+ IF(HAVE_RICHACL_ALLOC AND
+ HAVE_RICHACL_EQUIV_MODE AND
+ HAVE_RICHACL_FREE AND
+ HAVE_RICHACL_GET_FD AND
+ HAVE_RICHACL_GET_FILE AND
+ HAVE_RICHACL_SET_FD AND
+ HAVE_RICHACL_SET_FILE)
+ SET(ARCHIVE_ACL_LIBRICHACL TRUE)
+ ENDIF()
+ ENDIF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE)
+
+ IF(ARCHIVE_ACL_DARWIN)
+ MESSAGE(STATUS "ACL support: Darwin (limited NFSv4)")
+ ELSEIF(ARCHIVE_ACL_FREEBSD_NFS4)
+ MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e and NFSv4)")
+ ELSEIF(ARCHIVE_ACL_FREEBSD)
+ MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e)")
+ ELSEIF(ARCHIVE_ACL_LIBACL OR ARCHIVE_ACL_LIBRICHACL)
+ IF(ARCHIVE_ACL_LIBACL AND ARCHIVE_ACL_LIBRICHACL)
+ MESSAGE(STATUS "ACL support: libacl (POSIX.1e) + librichacl (NFSv4)")
+ ELSEIF(ARCHIVE_ACL_LIBRICHACL)
+ MESSAGE(STATUS "ACL support: librichacl (NFSv4)")
+ ELSE()
+ MESSAGE(STATUS "ACL support: libacl (POSIX.1e)")
+ ENDIF()
+ ELSEIF(ARCHIVE_ACL_SUNOS_NFS4)
+ MESSAGE(STATUS "ACL support: Solaris (POSIX.1e and NFSv4)")
+ ELSEIF(ARCHIVE_ACL_SUNOS)
+ MESSAGE(STATUS "ACL support: Solaris (POSIX.1e)")
+ ELSE()
+ MESSAGE(STATUS "ACL support: none")
+ ENDIF()
- # Solaris and derivates ACLs
- CHECK_LIBRARY_EXISTS(sec "acl_get" "" HAVE_LIBSEC)
- IF(HAVE_LIBSEC)
- SET(CMAKE_REQUIRED_LIBRARIES "sec")
- FIND_LIBRARY(SEC_LIBRARY NAMES sec)
- LIST(APPEND ADDITIONAL_LIBS ${SEC_LIBRARY})
- ENDIF(HAVE_LIBSEC)
- #
- CHECK_TYPE_EXISTS(aclent_t "${INCLUDES}" HAVE_ACLENT_T)
- CHECK_TYPE_EXISTS(ace_t "${INCLUDES}" HAVE_ACE_T)
- CHECK_FUNCTION_EXISTS(acl_get HAVE_FACL_GET)
- CHECK_FUNCTION_EXISTS(facl_get HAVE_FACL_GET)
- CHECK_FUNCTION_EXISTS(acl_set HAVE_FACL_SET)
- CHECK_FUNCTION_EXISTS(facl_set HAVE_FACL_SET)
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_TYPE_NFS4 FALSE)
- SET(HAVE_ACL_USER FALSE)
- SET(HAVE_ACL_TYPE_EXTENDED FALSE)
- SET(HAVE_ACL_GET FALSE)
- SET(HAVE_ACLENT_T FALSE)
- SET(HAVE_ACE_T FALSE)
- SET(HAVE_FACL_GET FALSE)
- SET(HAVE_ACL_SET FALSE)
- SET(HAVE_FACL_SET FALSE)
+ SET(ARCHIVE_ACL_DARWIN FALSE)
+ SET(ARCHIVE_ACL_FREEBSD FALSE)
+ SET(ARCHIVE_ACL_FREEBSD_NFS4 FALSE)
+ SET(ARCHIVE_ACL_LIBACL FALSE)
+ SET(ARCHIVE_ACL_SUNOS FALSE)
+ SET(ARCHIVE_ACL_SUNOS_NFS4 FALSE)
ENDIF(ENABLE_ACL)
#
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 55e04b9..368a451 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -182,6 +182,27 @@ typedef uint64_t uintmax_t;
/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
#cmakedefine ZLIB_WINAPI 1
+/* Darwin ACL support */
+#cmakedefine ARCHIVE_ACL_DARWIN 1
+
+/* FreeBSD ACL support */
+#cmakedefine ARCHIVE_ACL_FREEBSD 1
+
+/* FreeBSD NFSv4 ACL support */
+#cmakedefine ARCHIVE_ACL_FREEBSD_NFS4 1
+
+/* Linux POSIX.1e ACL support via libacl */
+#cmakedefine ARCHIVE_ACL_LIBACL 1
+
+/* Linux NFSv4 ACL support via librichacl */
+#cmakedefine ARCHIVE_ACL_LIBRICHACL 1
+
+/* Solaris ACL support */
+#cmakedefine ARCHIVE_ACL_SUNOS 1
+
+/* Solaris NFSv4 ACL support */
+#cmakedefine ARCHIVE_ACL_SUNOS_NFS4 1
+
/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
@@ -284,6 +305,18 @@ typedef uint64_t uintmax_t;
/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_WIN 1
+/* AIX xattr support */
+#cmakedefine ARCHIVE_XATTR_AIX 1
+
+/* Darwin xattr support */
+#cmakedefine ARCHIVE_XATTR_DARWIN 1
+
+/* FreeBSD xattr support */
+#cmakedefine ARCHIVE_XATTR_FREEBSD 1
+
+/* Linux xattr support */
+#cmakedefine ARCHIVE_XATTR_LINUX 1
+
/* Version number of bsdcpio */
#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
@@ -329,15 +362,6 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `acl_set_file' function. */
#cmakedefine HAVE_ACL_SET_FILE 1
-/* True for FreeBSD with NFSv4 ACL support */
-#cmakedefine HAVE_ACL_TYPE_NFS4 1
-
-/* True for MacOS ACL support */
-#cmakedefine HAVE_ACL_TYPE_EXTENDED 1
-
-/* True for systems with POSIX ACL support */
-#cmakedefine HAVE_ACL_USER 1
-
/* Define to 1 if you have the `arc4random_buf' function. */
#cmakedefine HAVE_ARC4RANDOM_BUF 1
@@ -374,6 +398,34 @@ typedef uint64_t uintmax_t;
/* 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 `ACE_GETACL', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_ACE_GETACL 1
+
+/* Define to 1 if you have the declaration of `ACE_GETACLCNT', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_ACE_GETACLCNT 1
+
+/* Define to 1 if you have the declaration of `ACE_SETACL', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_ACE_SETACL 1
+
+/* Define to 1 if you have the declaration of `ACL_SYNCHRONIZE', and to 0 if
+ you don't. */
+#cmakedefine HAVE_DECL_ACL_SYNCHRONIZE 1
+
+/* Define to 1 if you have the declaration of `ACL_TYPE_EXTENDED', and to 0 if
+ you don't. */
+#cmakedefine HAVE_DECL_ACL_TYPE_EXTENDED 1
+
+/* Define to 1 if you have the declaration of `ACL_TYPE_NFS4', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_ACL_TYPE_NFS4 1
+
+/* Define to 1 if you have the declaration of `ACL_USER', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_ACL_USER 1
+
/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you
don't. */
#cmakedefine HAVE_DECL_INT32_MAX 1
@@ -398,6 +450,10 @@ typedef uint64_t uintmax_t;
don't. */
#cmakedefine HAVE_DECL_INTMAX_MIN 1
+/* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't.
+ */
+#cmakedefine HAVE_DECL_SETACL 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
@@ -422,6 +478,10 @@ typedef uint64_t uintmax_t;
don't. */
#cmakedefine HAVE_DECL_UINTMAX_MAX 1
+/* Define to 1 if you have the declaration of `XATTR_NOFOLLOW', and to 0 if
+ you don't. */
+#cmakedefine HAVE_DECL_XATTR_NOFOLLOW 1
+
/* Define to 1 if you have the <direct.h> header file. */
#cmakedefine HAVE_DIRECT_H 1
@@ -471,6 +531,14 @@ typedef uint64_t uintmax_t;
/* 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 declaration of `GETACL', and to 0 if you don't.
+ */
+#cmakedefine HAVE_DECL_GETACL 1
+
+/* Define to 1 if you have the declaration of `GETACLCNT', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_GETACLCNT 1
+
/* Define to 1 if you have the `fchdir' function. */
#cmakedefine HAVE_FCHDIR 1
@@ -748,6 +816,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `mbrtowc' function. */
#cmakedefine HAVE_MBRTOWC 1
+/* Define to 1 if you have the <membership.h> header file. */
+#cmakedefine HAVE_MEMBERSHIP_H 1
+
/* Define to 1 if you have the `memmove' function. */
#cmakedefine HAVE_MEMMOVE 1
@@ -985,6 +1056,9 @@ typedef uint64_t uintmax_t;
/* 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/richacl.h> header file. */
+#cmakedefine HAVE_SYS_RICHACL_H 1
+
/* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H 1
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index ef83457..2dd0839 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3003001
+3003002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index d412c80..b02ae82 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -14,6 +14,7 @@ SET(include_HEADERS
# Sources and private headers
SET(libarchive_SOURCES
archive_acl.c
+ archive_acl_private.h
archive_check_magic.c
archive_cmdline.c
archive_cmdline_private.h
@@ -47,6 +48,8 @@ SET(libarchive_SOURCES
archive_pathmatch.c
archive_pathmatch.h
archive_platform.h
+ archive_platform_acl.h
+ archive_platform_xattr.h
archive_ppmd_private.h
archive_ppmd7.c
archive_ppmd7_private.h
@@ -106,9 +109,9 @@ SET(libarchive_SOURCES
archive_string_composition.h
archive_string_sprintf.c
archive_util.c
+ archive_version_details.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
@@ -210,6 +213,16 @@ IF(WIN32 AND NOT CYGWIN)
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
ENDIF(WIN32 AND NOT CYGWIN)
+IF(ARCHIVE_ACL_DARWIN)
+ LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c)
+ELSEIF(ARCHIVE_ACL_FREEBSD)
+ LIST(APPEND libarchive_SOURCES archive_disk_acl_freebsd.c)
+ELSEIF(ARCHIVE_ACL_LIBACL)
+ LIST(APPEND libarchive_SOURCES archive_disk_acl_linux.c)
+ELSEIF(ARCHIVE_ACL_SUNOS)
+ LIST(APPEND libarchive_SOURCES archive_disk_acl_sunos.c)
+ENDIF()
+
# CMake needs just one static "cmlibarchive" library.
ADD_LIBRARY(cmlibarchive STATIC ${libarchive_SOURCES} ${include_HEADERS})
TARGET_LINK_LIBRARIES(cmlibarchive ${ADDITIONAL_LIBS})
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index cfb5c48..0f94d2e 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3003001
+#define ARCHIVE_VERSION_NUMBER 3003002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -152,7 +152,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.3.1"
+#define ARCHIVE_VERSION_ONLY_STRING "3.3.2"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
diff --git a/Utilities/cmlibarchive/libarchive/archive_check_magic.c b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
index c695e58..288ce23 100644
--- a/Utilities/cmlibarchive/libarchive/archive_check_magic.c
+++ b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
@@ -62,7 +62,7 @@ errmsg(const char *m)
}
}
-static void
+static __LA_DEAD void
diediedie(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
diff --git a/Utilities/cmlibarchive/libarchive/archive_disk_acl_darwin.c b/Utilities/cmlibarchive/libarchive/archive_disk_acl_darwin.c
new file mode 100644
index 0000000..48ad016
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_disk_acl_darwin.c
@@ -0,0 +1,559 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * 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 ARCHIVE_ACL_DARWIN
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_MEMBERSHIP_H
+#include <membership.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#define _ACL_PRIVATE /* For debugging */
+#include <sys/acl.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+ const int a_perm; /* Libarchive permission or flag */
+ const int p_perm; /* Platform permission or flag */
+} acl_perm_map_t;
+
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
+ {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
+ {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
+ {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+ {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
+ {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
+ {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
+ {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
+ {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
+ {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
+#if HAVE_DECL_ACL_SYNCHRONIZE
+ {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
+};
+
+static const int acl_nfs4_perm_map_size =
+ (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
+ {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
+ {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
+ {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
+};
+
+static const int acl_nfs4_flag_map_size =
+ (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+
+static int translate_guid(struct archive *a, acl_entry_t acl_entry,
+ int *ae_id, int *ae_tag, const char **ae_name)
+{
+ void *q;
+ uid_t ugid;
+ int r, idtype;
+
+ q = acl_get_qualifier(acl_entry);
+ if (q == NULL)
+ return (1);
+ r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
+ if (r != 0) {
+ acl_free(q);
+ return (1);
+ }
+ if (idtype == ID_TYPE_UID) {
+ *ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ *ae_id = ugid;
+ *ae_name = archive_read_disk_uname(a, *ae_id);
+ } else if (idtype == ID_TYPE_GID) {
+ *ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ *ae_id = ugid;
+ *ae_name = archive_read_disk_gname(a, *ae_id);
+ } else
+ r = 1;
+
+ acl_free(q);
+ return (r);
+}
+
+static void
+add_trivial_nfs4_acl(struct archive_entry *entry)
+{
+ mode_t mode;
+ int i;
+ const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
+ const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
+ ARCHIVE_ENTRY_ACL_APPEND_DATA;
+ const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
+ const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+ ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+ ARCHIVE_ENTRY_ACL_READ_ACL |
+ ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
+ const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
+ ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
+ ARCHIVE_ENTRY_ACL_WRITE_ACL |
+ ARCHIVE_ENTRY_ACL_WRITE_OWNER;
+
+ struct {
+ const int type;
+ const int tag;
+ int permset;
+ } tacl_entry[] = {
+ {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
+ {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
+ {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
+ {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
+ {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
+ {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
+ };
+
+ mode = archive_entry_mode(entry);
+
+ /* Permissions for everyone@ */
+ if (mode & 0004)
+ tacl_entry[5].permset |= rperm;
+ if (mode & 0002)
+ tacl_entry[5].permset |= wperm;
+ if (mode & 0001)
+ tacl_entry[5].permset |= eperm;
+
+ /* Permissions for group@ */
+ if (mode & 0040)
+ tacl_entry[4].permset |= rperm;
+ else if (mode & 0004)
+ tacl_entry[2].permset |= rperm;
+ if (mode & 0020)
+ tacl_entry[4].permset |= wperm;
+ else if (mode & 0002)
+ tacl_entry[2].permset |= wperm;
+ if (mode & 0010)
+ tacl_entry[4].permset |= eperm;
+ else if (mode & 0001)
+ tacl_entry[2].permset |= eperm;
+
+ /* Permissions for owner@ */
+ if (mode & 0400) {
+ tacl_entry[3].permset |= rperm;
+ if (!(mode & 0040) && (mode & 0004))
+ tacl_entry[0].permset |= rperm;
+ } else if ((mode & 0040) || (mode & 0004))
+ tacl_entry[1].permset |= rperm;
+ if (mode & 0200) {
+ tacl_entry[3].permset |= wperm;
+ if (!(mode & 0020) && (mode & 0002))
+ tacl_entry[0].permset |= wperm;
+ } else if ((mode & 0020) || (mode & 0002))
+ tacl_entry[1].permset |= wperm;
+ if (mode & 0100) {
+ tacl_entry[3].permset |= eperm;
+ if (!(mode & 0010) && (mode & 0001))
+ tacl_entry[0].permset |= eperm;
+ } else if ((mode & 0010) || (mode & 0001))
+ tacl_entry[1].permset |= eperm;
+
+ for (i = 0; i < 6; i++) {
+ if (tacl_entry[i].permset != 0) {
+ archive_entry_acl_add_entry(entry,
+ tacl_entry[i].type, tacl_entry[i].permset,
+ tacl_entry[i].tag, -1, NULL);
+ }
+ }
+
+ return;
+}
+
+static int
+translate_acl(struct archive_read_disk *a,
+ struct archive_entry *entry, acl_t acl)
+{
+ acl_tag_t acl_tag;
+ acl_flagset_t acl_flagset;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+ int i, entry_acl_type;
+ int r, s, ae_id, ae_tag, ae_perm;
+ const char *ae_name;
+
+ s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
+ if (s == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get first ACL entry");
+ return (ARCHIVE_WARN);
+ }
+
+ while (s == 0) {
+ ae_id = -1;
+ ae_name = NULL;
+ ae_perm = 0;
+
+ if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get ACL tag type");
+ return (ARCHIVE_WARN);
+ }
+ switch (acl_tag) {
+ case ACL_EXTENDED_ALLOW:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+ r = translate_guid(&a->archive, acl_entry,
+ &ae_id, &ae_tag, &ae_name);
+ break;
+ case ACL_EXTENDED_DENY:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
+ r = translate_guid(&a->archive, acl_entry,
+ &ae_id, &ae_tag, &ae_name);
+ break;
+ default:
+ /* Skip types that libarchive can't support. */
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ continue;
+ }
+
+ /* Skip if translate_guid() above failed */
+ if (r != 0) {
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ continue;
+ }
+
+ /*
+ * Libarchive stores "flag" (NFSv4 inheritance bits)
+ * in the ae_perm bitmap.
+ *
+ * acl_get_flagset_np() fails with non-NFSv4 ACLs
+ */
+ if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get flagset from a NFSv4 ACL entry");
+ return (ARCHIVE_WARN);
+ }
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ r = acl_get_flag_np(acl_flagset,
+ acl_nfs4_flag_map[i].p_perm);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to check flag in a NFSv4 "
+ "ACL flagset");
+ return (ARCHIVE_WARN);
+ } else if (r)
+ ae_perm |= acl_nfs4_flag_map[i].a_perm;
+ }
+
+ if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get ACL permission set");
+ return (ARCHIVE_WARN);
+ }
+
+ for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+ /*
+ * acl_get_perm() is spelled differently on different
+ * platforms; see above.
+ */
+ r = acl_get_perm_np(acl_permset,
+ acl_nfs4_perm_map[i].p_perm);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to check permission in an ACL "
+ "permission set");
+ return (ARCHIVE_WARN);
+ } else if (r)
+ ae_perm |= acl_nfs4_perm_map[i].a_perm;
+ }
+
+#if !HAVE_DECL_ACL_SYNCHRONIZE
+ /* On Mac OS X without ACL_SYNCHRONIZE assume it is set */
+ ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
+#endif
+
+ archive_entry_acl_add_entry(entry, entry_acl_type,
+ ae_perm, ae_tag,
+ ae_id, ae_name);
+
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+set_acl(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl,
+ int ae_requested_type, const char *tname)
+{
+ acl_t acl;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+ acl_flagset_t acl_flagset;
+ int ret;
+ int ae_type, ae_permset, ae_tag, ae_id;
+ uuid_t ae_uuid;
+ uid_t ae_uid;
+ gid_t ae_gid;
+ const char *ae_name;
+ int entries;
+ int i;
+
+ ret = ARCHIVE_OK;
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
+ if (entries == 0)
+ return (ARCHIVE_OK);
+
+ if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ errno = ENOENT;
+ archive_set_error(a, errno, "Unsupported ACL type");
+ return (ARCHIVE_FAILED);
+ }
+
+ acl = acl_init(entries);
+ if (acl == (acl_t)NULL) {
+ archive_set_error(a, errno,
+ "Failed to initialize ACL working storage");
+ return (ARCHIVE_FAILED);
+ }
+
+ while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+ &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+ /*
+ * Mac OS doesn't support NFSv4 ACLs for
+ * owner@, group@ and everyone@.
+ * We skip any of these ACLs found.
+ */
+ if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
+ ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
+ ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
+ continue;
+
+ if (acl_create_entry(&acl, &acl_entry) != 0) {
+ archive_set_error(a, errno,
+ "Failed to create a new ACL entry");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ switch (ae_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
+ break;
+ default:
+ /* We don't support any other types on MacOS */
+ continue;
+ }
+
+ switch (ae_tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+ if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0)
+ continue;
+ if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
+ continue;
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+ if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0)
+ continue;
+ if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
+ continue;
+ break;
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL tag");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to get ACL permission set");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ if (acl_clear_perms(acl_permset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to clear ACL permissions");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+ if (ae_permset & acl_nfs4_perm_map[i].a_perm) {
+ if (acl_add_perm(acl_permset,
+ acl_nfs4_perm_map[i].p_perm) != 0) {
+ archive_set_error(a, errno,
+ "Failed to add ACL permission");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ }
+ }
+
+ /*
+ * acl_get_flagset_np() fails with non-NFSv4 ACLs
+ */
+ if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to get flagset from an NFSv4 ACL entry");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ if (acl_clear_flags_np(acl_flagset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to clear flags from an NFSv4 ACL flagset");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
+ if (acl_add_flag_np(acl_flagset,
+ acl_nfs4_flag_map[i].p_perm) != 0) {
+ archive_set_error(a, errno,
+ "Failed to add flag to "
+ "NFSv4 ACL flagset");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ }
+ }
+ }
+
+ if (fd >= 0) {
+ if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 0)
+ ret = ARCHIVE_OK;
+ else {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno,
+ "Failed to set acl on fd: %s", tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+ } else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno, "Failed to set acl: %s",
+ tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+exit_free:
+ acl_free(acl);
+ return (ret);
+}
+
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ const char *accpath;
+ acl_t acl;
+ int r;
+
+ accpath = NULL;
+
+ if (*fd < 0) {
+ accpath = archive_read_disk_entry_setup_path(a, entry, fd);
+ if (accpath == NULL)
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_acl_clear(entry);
+
+ acl = NULL;
+
+ if (*fd >= 0)
+ acl = acl_get_fd_np(*fd, ACL_TYPE_EXTENDED);
+ else if (!a->follow_symlinks)
+ acl = acl_get_link_np(accpath, ACL_TYPE_EXTENDED);
+ else
+ acl = acl_get_file(accpath, ACL_TYPE_EXTENDED);
+
+ if (acl != NULL) {
+ r = translate_acl(a, entry, acl);
+ acl_free(acl);
+ acl = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate NFSv4 ACLs");
+ }
+
+ /*
+ * Because Mac OS doesn't support owner@, group@ and everyone@
+ * ACLs we need to add NFSv4 ACLs mirroring the file mode to
+ * the archive entry. Otherwise extraction on non-Mac platforms
+ * would lead to an invalid file mode.
+ */
+ if ((archive_entry_acl_types(entry) &
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
+ add_trivial_nfs4_acl(entry);
+
+ return (r);
+ }
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode)
+{
+ int ret = ARCHIVE_OK;
+
+ (void)mode; /* UNUSED */
+
+ if ((archive_acl_types(abstract_acl) &
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+ }
+ return (ret);
+}
+#endif /* ARCHIVE_ACL_DARWIN */
diff --git a/Utilities/cmlibarchive/libarchive/archive_disk_acl_freebsd.c b/Utilities/cmlibarchive/libarchive/archive_disk_acl_freebsd.c
new file mode 100644
index 0000000..07d08ff
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_disk_acl_freebsd.c
@@ -0,0 +1,700 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2017 Martin Matuska
+ * 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 ARCHIVE_ACL_FREEBSD
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#define _ACL_PRIVATE /* For debugging */
+#include <sys/acl.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+ const int a_perm; /* Libarchive permission or flag */
+ const int p_perm; /* Platform permission or flag */
+} acl_perm_map_t;
+
+static const acl_perm_map_t acl_posix_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+ {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
+ {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+};
+
+static const int acl_posix_perm_map_size =
+ (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+ {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
+ {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
+ {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
+ {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
+ {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
+ {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
+ {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
+ {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
+ {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
+ {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
+ {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
+ {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+};
+
+static const int acl_nfs4_perm_map_size =
+ (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+ {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
+ {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
+ {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
+ {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
+ {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
+};
+
+static const int acl_nfs4_flag_map_size =
+ (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */
+
+static int
+translate_acl(struct archive_read_disk *a,
+ struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
+{
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ int brand;
+ acl_flagset_t acl_flagset;
+ acl_entry_type_t acl_type;
+#endif
+ acl_tag_t acl_tag;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+ int i, entry_acl_type, perm_map_size;
+ const acl_perm_map_t *perm_map;
+ int r, s, ae_id, ae_tag, ae_perm;
+ void *q;
+ const char *ae_name;
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ // FreeBSD "brands" ACLs as POSIX.1e or NFSv4
+ // Make sure the "brand" on this ACL is consistent
+ // with the default_entry_acl_type bits provided.
+ if (acl_get_brand_np(acl, &brand) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to read ACL brand");
+ return (ARCHIVE_WARN);
+ }
+ switch (brand) {
+ case ACL_BRAND_POSIX:
+ switch (default_entry_acl_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid ACL entry type for POSIX.1e ACL");
+ return (ARCHIVE_WARN);
+ }
+ break;
+ case ACL_BRAND_NFS4:
+ if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid ACL entry type for NFSv4 ACL");
+ return (ARCHIVE_WARN);
+ }
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unknown ACL brand");
+ return (ARCHIVE_WARN);
+ }
+#endif
+
+ s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
+ if (s == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get first ACL entry");
+ return (ARCHIVE_WARN);
+ }
+
+ while (s == 1) {
+ ae_id = -1;
+ ae_name = NULL;
+ ae_perm = 0;
+
+ if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get ACL tag type");
+ return (ARCHIVE_WARN);
+ }
+ switch (acl_tag) {
+ case ACL_USER:
+ q = acl_get_qualifier(acl_entry);
+ if (q != NULL) {
+ ae_id = (int)*(uid_t *)q;
+ acl_free(q);
+ ae_name = archive_read_disk_uname(&a->archive,
+ ae_id);
+ }
+ ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ break;
+ case ACL_GROUP:
+ q = acl_get_qualifier(acl_entry);
+ if (q != NULL) {
+ ae_id = (int)*(gid_t *)q;
+ acl_free(q);
+ ae_name = archive_read_disk_gname(&a->archive,
+ ae_id);
+ }
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ break;
+ case ACL_MASK:
+ ae_tag = ARCHIVE_ENTRY_ACL_MASK;
+ break;
+ case ACL_USER_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ break;
+ case ACL_GROUP_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ break;
+ case ACL_OTHER:
+ ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
+ break;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ case ACL_EVERYONE:
+ ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
+ break;
+#endif
+ default:
+ /* Skip types that libarchive can't support. */
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ continue;
+ }
+
+ // XXX acl_type maps to allow/deny/audit/YYYY bits
+ entry_acl_type = default_entry_acl_type;
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ /*
+ * acl_get_entry_type_np() fails with non-NFSv4 ACLs
+ */
+ if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
+ archive_set_error(&a->archive, errno, "Failed "
+ "to get ACL type from a NFSv4 ACL entry");
+ return (ARCHIVE_WARN);
+ }
+ switch (acl_type) {
+ case ACL_ENTRY_TYPE_ALLOW:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+ break;
+ case ACL_ENTRY_TYPE_DENY:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
+ break;
+ case ACL_ENTRY_TYPE_AUDIT:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
+ break;
+ case ACL_ENTRY_TYPE_ALARM:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
+ break;
+ default:
+ archive_set_error(&a->archive, errno,
+ "Invalid NFSv4 ACL entry type");
+ return (ARCHIVE_WARN);
+ }
+
+ /*
+ * Libarchive stores "flag" (NFSv4 inheritance bits)
+ * in the ae_perm bitmap.
+ *
+ * acl_get_flagset_np() fails with non-NFSv4 ACLs
+ */
+ if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get flagset from a NFSv4 "
+ "ACL entry");
+ return (ARCHIVE_WARN);
+ }
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ r = acl_get_flag_np(acl_flagset,
+ acl_nfs4_flag_map[i].p_perm);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to check flag in a NFSv4 "
+ "ACL flagset");
+ return (ARCHIVE_WARN);
+ } else if (r)
+ ae_perm |= acl_nfs4_flag_map[i].a_perm;
+ }
+ }
+#endif
+
+ if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get ACL permission set");
+ return (ARCHIVE_WARN);
+ }
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ perm_map_size = acl_nfs4_perm_map_size;
+ perm_map = acl_nfs4_perm_map;
+ } else {
+#endif
+ perm_map_size = acl_posix_perm_map_size;
+ perm_map = acl_posix_perm_map;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ }
+#endif
+
+ for (i = 0; i < perm_map_size; ++i) {
+ r = acl_get_perm_np(acl_permset, perm_map[i].p_perm);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to check permission in an ACL "
+ "permission set");
+ return (ARCHIVE_WARN);
+ } else if (r)
+ ae_perm |= perm_map[i].a_perm;
+ }
+
+ archive_entry_acl_add_entry(entry, entry_acl_type,
+ ae_perm, ae_tag,
+ ae_id, ae_name);
+
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ if (s == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get next ACL entry");
+ return (ARCHIVE_WARN);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+set_acl(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl,
+ int ae_requested_type, const char *tname)
+{
+ int acl_type = 0;
+ acl_t acl;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ acl_flagset_t acl_flagset;
+ int r;
+#endif
+ int ret;
+ int ae_type, ae_permset, ae_tag, ae_id;
+ int perm_map_size;
+ const acl_perm_map_t *perm_map;
+ uid_t ae_uid;
+ gid_t ae_gid;
+ const char *ae_name;
+ int entries;
+ int i;
+
+ ret = ARCHIVE_OK;
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
+ if (entries == 0)
+ return (ARCHIVE_OK);
+
+
+ switch (ae_requested_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+ acl_type = ACL_TYPE_ACCESS;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+ acl_type = ACL_TYPE_DEFAULT;
+ break;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
+ acl_type = ACL_TYPE_NFS4;
+ break;
+#endif
+ default:
+ errno = ENOENT;
+ archive_set_error(a, errno, "Unsupported ACL type");
+ return (ARCHIVE_FAILED);
+ }
+
+ acl = acl_init(entries);
+ if (acl == (acl_t)NULL) {
+ archive_set_error(a, errno,
+ "Failed to initialize ACL working storage");
+ return (ARCHIVE_FAILED);
+ }
+
+ while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+ &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+ if (acl_create_entry(&acl, &acl_entry) != 0) {
+ archive_set_error(a, errno,
+ "Failed to create a new ACL entry");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ switch (ae_tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+ acl_set_tag_type(acl_entry, ACL_USER);
+ acl_set_qualifier(acl_entry, &ae_uid);
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+ acl_set_tag_type(acl_entry, ACL_GROUP);
+ acl_set_qualifier(acl_entry, &ae_gid);
+ break;
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ acl_set_tag_type(acl_entry, ACL_USER_OBJ);
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ acl_set_tag_type(acl_entry, ACL_MASK);
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ acl_set_tag_type(acl_entry, ACL_OTHER);
+ break;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ acl_set_tag_type(acl_entry, ACL_EVERYONE);
+ break;
+#endif
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL tag");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ r = 0;
+ switch (ae_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ r = acl_set_entry_type_np(acl_entry,
+ ACL_ENTRY_TYPE_ALLOW);
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ r = acl_set_entry_type_np(acl_entry,
+ ACL_ENTRY_TYPE_DENY);
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+ r = acl_set_entry_type_np(acl_entry,
+ ACL_ENTRY_TYPE_AUDIT);
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+ r = acl_set_entry_type_np(acl_entry,
+ ACL_ENTRY_TYPE_ALARM);
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+ // These don't translate directly into the system ACL.
+ break;
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL entry type");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ if (r != 0) {
+ archive_set_error(a, errno,
+ "Failed to set ACL entry type");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+#endif
+
+ if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to get ACL permission set");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ if (acl_clear_perms(acl_permset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to clear ACL permissions");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ perm_map_size = acl_nfs4_perm_map_size;
+ perm_map = acl_nfs4_perm_map;
+ } else {
+#endif
+ perm_map_size = acl_posix_perm_map_size;
+ perm_map = acl_posix_perm_map;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ }
+#endif
+
+ for (i = 0; i < perm_map_size; ++i) {
+ if (ae_permset & perm_map[i].a_perm) {
+ if (acl_add_perm(acl_permset,
+ perm_map[i].p_perm) != 0) {
+ archive_set_error(a, errno,
+ "Failed to add ACL permission");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ }
+ }
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ /*
+ * acl_get_flagset_np() fails with non-NFSv4 ACLs
+ */
+ if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to get flagset from an NFSv4 "
+ "ACL entry");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ if (acl_clear_flags_np(acl_flagset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to clear flags from an NFSv4 "
+ "ACL flagset");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
+ if (acl_add_flag_np(acl_flagset,
+ acl_nfs4_flag_map[i].p_perm) != 0) {
+ archive_set_error(a, errno,
+ "Failed to add flag to "
+ "NFSv4 ACL flagset");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ }
+ }
+ }
+#endif
+ }
+
+ /* Try restoring the ACL through 'fd' if we can. */
+ if (fd >= 0) {
+ if (acl_set_fd_np(fd, acl, acl_type) == 0)
+ ret = ARCHIVE_OK;
+ else {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno,
+ "Failed to set acl on fd: %s", tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+ }
+#if HAVE_ACL_SET_LINK_NP
+ else if (acl_set_link_np(name, acl_type, acl) != 0)
+#else
+ /* FreeBSD older than 8.0 */
+ else if (acl_set_file(name, acl_type, acl) != 0)
+#endif
+ {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno, "Failed to set acl: %s",
+ tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+exit_free:
+ acl_free(acl);
+ return (ret);
+}
+
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ const char *accpath;
+ acl_t acl;
+ int r;
+
+ accpath = NULL;
+
+ if (*fd < 0) {
+ accpath = archive_read_disk_entry_setup_path(a, entry, fd);
+ if (accpath == NULL)
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_acl_clear(entry);
+
+ acl = NULL;
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ /* Try NFSv4 ACL first. */
+ if (*fd >= 0)
+ acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
+ else if (!a->follow_symlinks)
+ acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
+ else
+ acl = acl_get_file(accpath, ACL_TYPE_NFS4);
+
+ /* Ignore "trivial" ACLs that just mirror the file mode. */
+ if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
+ acl_free(acl);
+ acl = NULL;
+ return (ARCHIVE_OK);
+ }
+
+ if (acl != NULL) {
+ r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+ acl_free(acl);
+ acl = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate NFSv4 ACLs");
+ }
+
+ return (r);
+ }
+#endif
+
+ /* Retrieve access ACL from file. */
+ if (*fd >= 0)
+ acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS);
+#if HAVE_ACL_GET_LINK_NP
+ else if (!a->follow_symlinks)
+ acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
+#else
+ else if ((!a->follow_symlinks)
+ && (archive_entry_filetype(entry) == AE_IFLNK))
+ /* We can't get the ACL of a symlink, so we assume it can't
+ have one. */
+ acl = NULL;
+#endif
+ else
+ acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
+
+#if HAVE_ACL_IS_TRIVIAL_NP
+ /* Ignore "trivial" ACLs that just mirror the file mode. */
+ if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
+ acl_free(acl);
+ acl = NULL;
+ }
+#endif
+
+ if (acl != NULL) {
+ r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ acl_free(acl);
+ acl = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate access ACLs");
+ return (r);
+ }
+ }
+
+ /* Only directories can have default ACLs. */
+ if (S_ISDIR(archive_entry_mode(entry))) {
+ if (*fd >= 0)
+ acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
+ else
+ acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
+ if (acl != NULL) {
+ r = translate_acl(a, entry, acl,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
+ acl_free(acl);
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate default ACLs");
+ return (r);
+ }
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode)
+{
+ int ret = ARCHIVE_OK;
+
+ (void)mode; /* UNUSED */
+
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
+
+ /* Simultaneous POSIX.1e and NFSv4 is not supported */
+ return (ret);
+ }
+#if ARCHIVE_ACL_FREEBSD_NFS4
+ else if ((archive_acl_types(abstract_acl) &
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+ }
+#endif
+ return (ret);
+}
+#endif /* ARCHIVE_ACL_FREEBSD */
diff --git a/Utilities/cmlibarchive/libarchive/archive_disk_acl_linux.c b/Utilities/cmlibarchive/libarchive/archive_disk_acl_linux.c
new file mode 100644
index 0000000..3928f3d
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_disk_acl_linux.c
@@ -0,0 +1,743 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2017 Martin Matuska
+ * 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 ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_LIBRICHACL
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_ACL_LIBACL_H
+#include <acl/libacl.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+#ifdef HAVE_SYS_RICHACL_H
+#include <sys/richacl.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+ const int a_perm; /* Libarchive permission or flag */
+ const int p_perm; /* Platform permission or flag */
+} acl_perm_map_t;
+
+#if ARCHIVE_ACL_LIBACL
+static const acl_perm_map_t acl_posix_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+ {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
+ {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+};
+
+static const int acl_posix_perm_map_size =
+ (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
+#endif /* ARCHIVE_ACL_LIBACL */
+
+#if ARCHIVE_ACL_LIBRICHACL
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE},
+ {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA},
+ {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY},
+ {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE},
+ {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY},
+ {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS},
+ {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS},
+ {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD},
+ {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE},
+ {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL},
+ {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL},
+ {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER},
+ {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE}
+};
+
+static const int acl_nfs4_perm_map_size =
+ (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+ {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE}
+};
+
+static const int acl_nfs4_flag_map_size =
+ (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+
+#if ARCHIVE_ACL_LIBACL
+/*
+ * Translate POSIX.1e ACLs into libarchive internal structure
+ */
+static int
+translate_acl(struct archive_read_disk *a,
+ struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
+{
+ acl_tag_t acl_tag;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+ int i, entry_acl_type;
+ int r, s, ae_id, ae_tag, ae_perm;
+ void *q;
+ const char *ae_name;
+
+ s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
+ if (s == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get first ACL entry");
+ return (ARCHIVE_WARN);
+ }
+
+ while (s == 1) {
+ ae_id = -1;
+ ae_name = NULL;
+ ae_perm = 0;
+
+ if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get ACL tag type");
+ return (ARCHIVE_WARN);
+ }
+ switch (acl_tag) {
+ case ACL_USER:
+ q = acl_get_qualifier(acl_entry);
+ if (q != NULL) {
+ ae_id = (int)*(uid_t *)q;
+ acl_free(q);
+ ae_name = archive_read_disk_uname(&a->archive,
+ ae_id);
+ }
+ ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ break;
+ case ACL_GROUP:
+ q = acl_get_qualifier(acl_entry);
+ if (q != NULL) {
+ ae_id = (int)*(gid_t *)q;
+ acl_free(q);
+ ae_name = archive_read_disk_gname(&a->archive,
+ ae_id);
+ }
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ break;
+ case ACL_MASK:
+ ae_tag = ARCHIVE_ENTRY_ACL_MASK;
+ break;
+ case ACL_USER_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ break;
+ case ACL_GROUP_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ break;
+ case ACL_OTHER:
+ ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
+ break;
+ default:
+ /* Skip types that libarchive can't support. */
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ continue;
+ }
+
+ // XXX acl_type maps to allow/deny/audit/YYYY bits
+ entry_acl_type = default_entry_acl_type;
+
+ if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get ACL permission set");
+ return (ARCHIVE_WARN);
+ }
+
+ for (i = 0; i < acl_posix_perm_map_size; ++i) {
+ r = acl_get_perm(acl_permset,
+ acl_posix_perm_map[i].p_perm);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to check permission in an ACL "
+ "permission set");
+ return (ARCHIVE_WARN);
+ } else if (r)
+ ae_perm |= acl_posix_perm_map[i].a_perm;
+ }
+
+ archive_entry_acl_add_entry(entry, entry_acl_type,
+ ae_perm, ae_tag,
+ ae_id, ae_name);
+
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ if (s == -1) {
+ archive_set_error(&a->archive, errno,
+ "Failed to get next ACL entry");
+ return (ARCHIVE_WARN);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+#endif /* ARCHIVE_ACL_LIBACL */
+
+#if ARCHIVE_ACL_LIBRICHACL
+/*
+ * Translate RichACL into libarchive internal ACL
+ */
+static int
+translate_richacl(struct archive_read_disk *a, struct archive_entry *entry,
+ struct richacl *richacl)
+{
+ int ae_id, ae_tag, ae_perm;
+ int entry_acl_type, i;
+ const char *ae_name;
+
+ struct richace *richace;
+
+ richacl_for_each_entry(richace, richacl) {
+ ae_name = NULL;
+ ae_tag = 0;
+ ae_perm = 0;
+ ae_id = -1;
+
+ switch (richace->e_type) {
+ case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+ break;
+ case RICHACE_ACCESS_DENIED_ACE_TYPE:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
+ break;
+ default: /* Unknown entry type, skip */
+ continue;
+ }
+
+ /* Unsupported */
+ if (richace->e_flags & RICHACE_UNMAPPED_WHO)
+ continue;
+
+ if (richace->e_flags & RICHACE_SPECIAL_WHO) {
+ switch (richace->e_id) {
+ case RICHACE_OWNER_SPECIAL_ID:
+ ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ break;
+ case RICHACE_GROUP_SPECIAL_ID:
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ break;
+ case RICHACE_EVERYONE_SPECIAL_ID:
+ ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
+ break;
+ default: /* Unknown special ID type */
+ continue;
+ }
+ } else {
+ ae_id = richace->e_id;
+ if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ ae_name = archive_read_disk_gname(&a->archive,
+ (gid_t)(richace->e_id));
+ } else {
+ ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ ae_name = archive_read_disk_uname(&a->archive,
+ (uid_t)(richace->e_id));
+ }
+ }
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ if ((richace->e_flags &
+ acl_nfs4_flag_map[i].p_perm) != 0)
+ ae_perm |= acl_nfs4_flag_map[i].a_perm;
+ }
+ for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+ if ((richace->e_mask &
+ acl_nfs4_perm_map[i].p_perm) != 0)
+ ae_perm |=
+ acl_nfs4_perm_map[i].a_perm;
+ }
+
+ archive_entry_acl_add_entry(entry, entry_acl_type,
+ ae_perm, ae_tag, ae_id, ae_name);
+ }
+ return (ARCHIVE_OK);
+}
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+
+#if ARCHIVE_ACL_LIBRICHACL
+static int
+_richacl_mode_to_mask(short mode)
+{
+ int mask = 0;
+
+ if (mode & S_IROTH)
+ mask |= RICHACE_POSIX_MODE_READ;
+ if (mode & S_IWOTH)
+ mask |= RICHACE_POSIX_MODE_WRITE;
+ if (mode & S_IXOTH)
+ mask |= RICHACE_POSIX_MODE_EXEC;
+
+ return (mask);
+}
+
+static void
+_richacl_mode_to_masks(struct richacl *richacl, __LA_MODE_T mode)
+{
+ richacl->a_owner_mask = _richacl_mode_to_mask((mode & 0700) >> 6);
+ richacl->a_group_mask = _richacl_mode_to_mask((mode & 0070) >> 3);
+ richacl->a_other_mask = _richacl_mode_to_mask(mode & 0007);
+}
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+
+#if ARCHIVE_ACL_LIBRICHACL
+static int
+set_richacl(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
+ int ae_requested_type, const char *tname)
+{
+ int ae_type, ae_permset, ae_tag, ae_id;
+ uid_t ae_uid;
+ gid_t ae_gid;
+ const char *ae_name;
+ int entries;
+ int i;
+ int ret;
+ int e = 0;
+ struct richacl *richacl = NULL;
+ struct richace *richace;
+
+ ret = ARCHIVE_OK;
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
+ if (entries == 0)
+ return (ARCHIVE_OK);
+
+ if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ errno = ENOENT;
+ archive_set_error(a, errno, "Unsupported ACL type");
+ return (ARCHIVE_FAILED);
+ }
+
+ richacl = richacl_alloc(entries);
+ if (richacl == NULL) {
+ archive_set_error(a, errno,
+ "Failed to initialize RichACL working storage");
+ return (ARCHIVE_FAILED);
+ }
+
+ e = 0;
+
+ while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+ &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+ richace = &(richacl->a_entries[e]);
+
+ richace->e_flags = 0;
+ richace->e_mask = 0;
+
+ switch (ae_tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+ richace->e_id = ae_uid;
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+ richace->e_id = ae_gid;
+ richace->e_flags |= RICHACE_IDENTIFIER_GROUP;
+ break;
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ richace->e_flags |= RICHACE_SPECIAL_WHO;
+ richace->e_id = RICHACE_OWNER_SPECIAL_ID;
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ richace->e_flags |= RICHACE_SPECIAL_WHO;
+ richace->e_id = RICHACE_GROUP_SPECIAL_ID;
+ break;
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ richace->e_flags |= RICHACE_SPECIAL_WHO;
+ richace->e_id = RICHACE_EVERYONE_SPECIAL_ID;
+ break;
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL tag");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ switch (ae_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ richace->e_type =
+ RICHACE_ACCESS_ALLOWED_ACE_TYPE;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ richace->e_type =
+ RICHACE_ACCESS_DENIED_ACE_TYPE;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+ break;
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL entry type");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+ if (ae_permset & acl_nfs4_perm_map[i].a_perm)
+ richace->e_mask |= acl_nfs4_perm_map[i].p_perm;
+ }
+
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ if (ae_permset &
+ acl_nfs4_flag_map[i].a_perm)
+ richace->e_flags |= acl_nfs4_flag_map[i].p_perm;
+ }
+ e++;
+ }
+
+ /* Fill RichACL masks */
+ _richacl_mode_to_masks(richacl, mode);
+
+ if (fd >= 0) {
+ if (richacl_set_fd(fd, richacl) == 0)
+ ret = ARCHIVE_OK;
+ else {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno,
+ "Failed to set richacl on fd: %s", tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+ } else if (richacl_set_file(name, richacl) != 0) {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno, "Failed to set richacl: %s",
+ tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+exit_free:
+ richacl_free(richacl);
+ return (ret);
+}
+#endif /* ARCHIVE_ACL_RICHACL */
+
+#if ARCHIVE_ACL_LIBACL
+static int
+set_acl(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl,
+ int ae_requested_type, const char *tname)
+{
+ int acl_type = 0;
+ int ae_type, ae_permset, ae_tag, ae_id;
+ uid_t ae_uid;
+ gid_t ae_gid;
+ const char *ae_name;
+ int entries;
+ int i;
+ int ret;
+ acl_t acl = NULL;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+
+ ret = ARCHIVE_OK;
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
+ if (entries == 0)
+ return (ARCHIVE_OK);
+
+ switch (ae_requested_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+ acl_type = ACL_TYPE_ACCESS;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+ acl_type = ACL_TYPE_DEFAULT;
+ break;
+ default:
+ errno = ENOENT;
+ archive_set_error(a, errno, "Unsupported ACL type");
+ return (ARCHIVE_FAILED);
+ }
+
+ acl = acl_init(entries);
+ if (acl == (acl_t)NULL) {
+ archive_set_error(a, errno,
+ "Failed to initialize ACL working storage");
+ return (ARCHIVE_FAILED);
+ }
+
+ while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+ &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+
+ if (acl_create_entry(&acl, &acl_entry) != 0) {
+ archive_set_error(a, errno,
+ "Failed to create a new ACL entry");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ switch (ae_tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+ acl_set_tag_type(acl_entry, ACL_USER);
+ acl_set_qualifier(acl_entry, &ae_uid);
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+ acl_set_tag_type(acl_entry, ACL_GROUP);
+ acl_set_qualifier(acl_entry, &ae_gid);
+ break;
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ acl_set_tag_type(acl_entry, ACL_USER_OBJ);
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ acl_set_tag_type(acl_entry, ACL_MASK);
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ acl_set_tag_type(acl_entry, ACL_OTHER);
+ break;
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL tag");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to get ACL permission set");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ if (acl_clear_perms(acl_permset) != 0) {
+ archive_set_error(a, errno,
+ "Failed to clear ACL permissions");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ for (i = 0; i < acl_posix_perm_map_size; ++i) {
+ if (ae_permset & acl_posix_perm_map[i].a_perm) {
+ if (acl_add_perm(acl_permset,
+ acl_posix_perm_map[i].p_perm) != 0) {
+ archive_set_error(a, errno,
+ "Failed to add ACL permission");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+ }
+ }
+
+ }
+
+ if (fd >= 0 && ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
+ if (acl_set_fd(fd, acl) == 0)
+ ret = ARCHIVE_OK;
+ else {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno,
+ "Failed to set acl on fd: %s", tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+ } else if (acl_set_file(name, acl_type, acl) != 0) {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno, "Failed to set acl: %s",
+ tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+exit_free:
+ acl_free(acl);
+ return (ret);
+}
+#endif /* ARCHIVE_ACL_LIBACL */
+
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ const char *accpath;
+ int r;
+#if ARCHIVE_ACL_LIBACL
+ acl_t acl;
+#endif
+#if ARCHIVE_ACL_LIBRICHACL
+ struct richacl *richacl;
+ mode_t mode;
+#endif
+
+ accpath = NULL;
+ r = ARCHIVE_OK;
+
+ /* For default ACLs we need reachable accpath */
+ if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) {
+ accpath = archive_read_disk_entry_setup_path(a, entry, fd);
+ if (accpath == NULL)
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_acl_clear(entry);
+
+#if ARCHIVE_ACL_LIBACL
+ acl = NULL;
+#endif
+#if ARCHIVE_ACL_LIBRICHACL
+ richacl = NULL;
+#endif
+
+#if ARCHIVE_ACL_LIBRICHACL
+ /* Try NFSv4 ACL first. */
+ if (*fd >= 0)
+ richacl = richacl_get_fd(*fd);
+ else if ((!a->follow_symlinks)
+ && (archive_entry_filetype(entry) == AE_IFLNK))
+ /* We can't get the ACL of a symlink, so we assume it can't
+ have one */
+ richacl = NULL;
+ else
+ richacl = richacl_get_file(accpath);
+
+ /* Ignore "trivial" ACLs that just mirror the file mode. */
+ if (richacl != NULL) {
+ mode = archive_entry_mode(entry);
+ if (richacl_equiv_mode(richacl, &mode) == 0) {
+ richacl_free(richacl);
+ richacl = NULL;
+ return (ARCHIVE_OK);
+ }
+ }
+
+ if (richacl != NULL) {
+ r = translate_richacl(a, entry, richacl);
+ richacl_free(richacl);
+ richacl = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate NFSv4 ACLs");
+ }
+
+ return (r);
+ }
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+
+#if ARCHIVE_ACL_LIBACL
+ /* Retrieve access ACL from file. */
+ if (*fd >= 0)
+ acl = acl_get_fd(*fd);
+ else if ((!a->follow_symlinks)
+ && (archive_entry_filetype(entry) == AE_IFLNK))
+ /* We can't get the ACL of a symlink, so we assume it can't
+ have one. */
+ acl = NULL;
+ else
+ acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
+
+ if (acl != NULL) {
+ r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ acl_free(acl);
+ acl = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate access ACLs");
+ return (r);
+ }
+ }
+
+ /* Only directories can have default ACLs. */
+ if (S_ISDIR(archive_entry_mode(entry))) {
+ acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
+ if (acl != NULL) {
+ r = translate_acl(a, entry, acl,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
+ acl_free(acl);
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate default ACLs");
+ return (r);
+ }
+ }
+ }
+#endif /* ARCHIVE_ACL_LIBACL */
+ return (r);
+}
+
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode)
+{
+ int ret = ARCHIVE_OK;
+
+#if !ARCHIVE_ACL_LIBRICHACL
+ (void)mode; /* UNUSED */
+#endif
+
+#if ARCHIVE_ACL_LIBRICHACL
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ ret = set_richacl(a, fd, name, abstract_acl, mode,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+ }
+#if ARCHIVE_ACL_LIBACL
+ else
+#endif
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+#if ARCHIVE_ACL_LIBACL
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
+ }
+#endif /* ARCHIVE_ACL_LIBACL */
+ return (ret);
+}
+#endif /* ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_LIBRICHACL */
diff --git a/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c b/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c
new file mode 100644
index 0000000..bc84fd6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c
@@ -0,0 +1,821 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * 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 ARCHIVE_ACL_SUNOS
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#define _ACL_PRIVATE /* For debugging */
+#include <sys/acl.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+ const int a_perm; /* Libarchive permission or flag */
+ const int p_perm; /* Platform permission or flag */
+} acl_perm_map_t;
+
+static const acl_perm_map_t acl_posix_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_EXECUTE, S_IXOTH },
+ {ARCHIVE_ENTRY_ACL_WRITE, S_IWOTH },
+ {ARCHIVE_ENTRY_ACL_READ, S_IROTH }
+};
+
+static const int acl_posix_perm_map_size =
+ (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+ {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
+ {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
+ {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
+ {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
+ {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
+ {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
+ {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
+ {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
+ {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
+ {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
+ {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
+ {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
+ {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
+ {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
+ {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
+};
+
+static const int acl_nfs4_perm_map_size =
+ (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+ {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
+ {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
+ {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
+#ifdef ACE_INHERITED_ACE
+ {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
+#endif
+};
+
+const int acl_nfs4_flag_map_size =
+ (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+
+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
+
+static void *
+sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
+{
+ int cnt, cntcmd;
+ size_t size;
+ void *aclp;
+
+ if (cmd == GETACL) {
+ cntcmd = GETACLCNT;
+ size = sizeof(aclent_t);
+ }
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else if (cmd == ACE_GETACL) {
+ cntcmd = ACE_GETACLCNT;
+ size = sizeof(ace_t);
+ }
+#endif
+ else {
+ errno = EINVAL;
+ *aclcnt = -1;
+ return (NULL);
+ }
+
+ aclp = NULL;
+ cnt = -2;
+
+ while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
+ if (path != NULL)
+ cnt = acl(path, cntcmd, 0, NULL);
+ else
+ cnt = facl(fd, cntcmd, 0, NULL);
+
+ if (cnt > 0) {
+ if (aclp == NULL)
+ aclp = malloc(cnt * size);
+ else
+ aclp = realloc(NULL, cnt * size);
+ if (aclp != NULL) {
+ if (path != NULL)
+ cnt = acl(path, cmd, cnt, aclp);
+ else
+ cnt = facl(fd, cmd, cnt, aclp);
+ }
+ } else {
+ if (aclp != NULL) {
+ free(aclp);
+ aclp = NULL;
+ }
+ break;
+ }
+ }
+
+ *aclcnt = cnt;
+ return (aclp);
+}
+
+/*
+ * Check if acl is trivial
+ * This is a FreeBSD acl_is_trivial_np() implementation for Solaris
+ */
+static int
+sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4,
+ int is_dir, int *trivialp)
+{
+#if ARCHIVE_ACL_SUNOS_NFS4
+ int i, p;
+ const uint32_t rperm = ACE_READ_DATA;
+ const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
+ const uint32_t eperm = ACE_EXECUTE;
+ const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
+ ACE_READ_ACL | ACE_SYNCHRONIZE;
+ const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
+ ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
+
+ ace_t *ace;
+ ace_t tace[6];
+#endif
+
+ if (aclp == NULL || trivialp == NULL)
+ return (-1);
+
+ *trivialp = 0;
+
+ /*
+ * POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
+ * FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
+ * including mask.
+ */
+ if (!is_nfs4) {
+ if (aclcnt == 4)
+ *trivialp = 1;
+ return (0);
+ }
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+ /*
+ * Continue with checking NFSv4 ACLs
+ *
+ * Create list of trivial ace's to be compared
+ */
+
+ /* owner@ allow pre */
+ tace[0].a_flags = ACE_OWNER;
+ tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+ tace[0].a_access_mask = 0;
+
+ /* owner@ deny */
+ tace[1].a_flags = ACE_OWNER;
+ tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+ tace[1].a_access_mask = 0;
+
+ /* group@ deny */
+ tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
+ tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+ tace[2].a_access_mask = 0;
+
+ /* owner@ allow */
+ tace[3].a_flags = ACE_OWNER;
+ tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+ tace[3].a_access_mask = ownset;
+
+ /* group@ allow */
+ tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
+ tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+ tace[4].a_access_mask = pubset;
+
+ /* everyone@ allow */
+ tace[5].a_flags = ACE_EVERYONE;
+ tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+ tace[5].a_access_mask = pubset;
+
+ /* Permissions for everyone@ */
+ if (mode & 0004)
+ tace[5].a_access_mask |= rperm;
+ if (mode & 0002)
+ tace[5].a_access_mask |= wperm;
+ if (mode & 0001)
+ tace[5].a_access_mask |= eperm;
+
+ /* Permissions for group@ */
+ if (mode & 0040)
+ tace[4].a_access_mask |= rperm;
+ else if (mode & 0004)
+ tace[2].a_access_mask |= rperm;
+ if (mode & 0020)
+ tace[4].a_access_mask |= wperm;
+ else if (mode & 0002)
+ tace[2].a_access_mask |= wperm;
+ if (mode & 0010)
+ tace[4].a_access_mask |= eperm;
+ else if (mode & 0001)
+ tace[2].a_access_mask |= eperm;
+
+ /* Permissions for owner@ */
+ if (mode & 0400) {
+ tace[3].a_access_mask |= rperm;
+ if (!(mode & 0040) && (mode & 0004))
+ tace[0].a_access_mask |= rperm;
+ } else if ((mode & 0040) || (mode & 0004))
+ tace[1].a_access_mask |= rperm;
+ if (mode & 0200) {
+ tace[3].a_access_mask |= wperm;
+ if (!(mode & 0020) && (mode & 0002))
+ tace[0].a_access_mask |= wperm;
+ } else if ((mode & 0020) || (mode & 0002))
+ tace[1].a_access_mask |= wperm;
+ if (mode & 0100) {
+ tace[3].a_access_mask |= eperm;
+ if (!(mode & 0010) && (mode & 0001))
+ tace[0].a_access_mask |= eperm;
+ } else if ((mode & 0010) || (mode & 0001))
+ tace[1].a_access_mask |= eperm;
+
+ /* Check if the acl count matches */
+ p = 3;
+ for (i = 0; i < 3; i++) {
+ if (tace[i].a_access_mask != 0)
+ p++;
+ }
+ if (aclcnt != p)
+ return (0);
+
+ p = 0;
+ for (i = 0; i < 6; i++) {
+ if (tace[i].a_access_mask != 0) {
+ ace = &((ace_t *)aclp)[p];
+ /*
+ * Illumos added ACE_DELETE_CHILD to write perms for
+ * directories. We have to check against that, too.
+ */
+ if (ace->a_flags != tace[i].a_flags ||
+ ace->a_type != tace[i].a_type ||
+ (ace->a_access_mask != tace[i].a_access_mask &&
+ (!is_dir || (tace[i].a_access_mask & wperm) == 0 ||
+ ace->a_access_mask !=
+ (tace[i].a_access_mask | ACE_DELETE_CHILD))))
+ return (0);
+ p++;
+ }
+ }
+
+ *trivialp = 1;
+#else /* !ARCHIVE_ACL_SUNOS_NFS4 */
+ (void)is_dir; /* UNUSED */
+ (void)aclp; /* UNUSED */
+#endif /* !ARCHIVE_ACL_SUNOS_NFS4 */
+ return (0);
+}
+
+/*
+ * Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
+ */
+static int
+translate_acl(struct archive_read_disk *a,
+ struct archive_entry *entry, void *aclp, int aclcnt,
+ int default_entry_acl_type)
+{
+ int e, i;
+ int ae_id, ae_tag, ae_perm;
+ int entry_acl_type;
+ const char *ae_name;
+ aclent_t *aclent;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ ace_t *ace;
+#endif
+
+ if (aclcnt <= 0)
+ return (ARCHIVE_OK);
+
+ for (e = 0; e < aclcnt; e++) {
+ ae_name = NULL;
+ ae_tag = 0;
+ ae_perm = 0;
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+ if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ ace = &((ace_t *)aclp)[e];
+ ae_id = ace->a_who;
+
+ switch(ace->a_type) {
+ case ACE_ACCESS_ALLOWED_ACE_TYPE:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+ break;
+ case ACE_ACCESS_DENIED_ACE_TYPE:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
+ break;
+ case ACE_SYSTEM_AUDIT_ACE_TYPE:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ break;
+ case ACE_SYSTEM_ALARM_ACE_TYPE:
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
+ break;
+ default:
+ /* Unknown entry type, skip */
+ continue;
+ }
+
+ if ((ace->a_flags & ACE_OWNER) != 0)
+ ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ else if ((ace->a_flags & ACE_GROUP) != 0)
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ else if ((ace->a_flags & ACE_EVERYONE) != 0)
+ ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
+ else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ ae_name = archive_read_disk_gname(&a->archive,
+ ae_id);
+ } else {
+ ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ ae_name = archive_read_disk_uname(&a->archive,
+ ae_id);
+ }
+
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ if ((ace->a_flags &
+ acl_nfs4_flag_map[i].p_perm) != 0)
+ ae_perm |= acl_nfs4_flag_map[i].a_perm;
+ }
+
+ for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+ if ((ace->a_access_mask &
+ acl_nfs4_perm_map[i].p_perm) != 0)
+ ae_perm |= acl_nfs4_perm_map[i].a_perm;
+ }
+ } else
+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
+ if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
+ aclent = &((aclent_t *)aclp)[e];
+ if ((aclent->a_type & ACL_DEFAULT) != 0)
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+ else
+ entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ ae_id = aclent->a_id;
+
+ switch(aclent->a_type) {
+ case DEF_USER:
+ case USER:
+ ae_name = archive_read_disk_uname(&a->archive,
+ ae_id);
+ ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ break;
+ case DEF_GROUP:
+ case GROUP:
+ ae_name = archive_read_disk_gname(&a->archive,
+ ae_id);
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ break;
+ case DEF_CLASS_OBJ:
+ case CLASS_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_MASK;
+ break;
+ case DEF_USER_OBJ:
+ case USER_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ break;
+ case DEF_GROUP_OBJ:
+ case GROUP_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ break;
+ case DEF_OTHER_OBJ:
+ case OTHER_OBJ:
+ ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
+ break;
+ default:
+ /* Unknown tag type, skip */
+ continue;
+ }
+
+ for (i = 0; i < acl_posix_perm_map_size; ++i) {
+ if ((aclent->a_perm &
+ acl_posix_perm_map[i].p_perm) != 0)
+ ae_perm |= acl_posix_perm_map[i].a_perm;
+ }
+ } else
+ return (ARCHIVE_WARN);
+
+ archive_entry_acl_add_entry(entry, entry_acl_type,
+ ae_perm, ae_tag, ae_id, ae_name);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+set_acl(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl,
+ int ae_requested_type, const char *tname)
+{
+ aclent_t *aclent;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ ace_t *ace;
+#endif
+ int cmd, e, r;
+ void *aclp;
+ int ret;
+ int ae_type, ae_permset, ae_tag, ae_id;
+ int perm_map_size;
+ const acl_perm_map_t *perm_map;
+ uid_t ae_uid;
+ gid_t ae_gid;
+ const char *ae_name;
+ int entries;
+ int i;
+
+ ret = ARCHIVE_OK;
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
+ if (entries == 0)
+ return (ARCHIVE_OK);
+
+
+ switch (ae_requested_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
+ cmd = SETACL;
+ aclp = malloc(entries * sizeof(aclent_t));
+ break;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
+ cmd = ACE_SETACL;
+ aclp = malloc(entries * sizeof(ace_t));
+
+ break;
+#endif
+ default:
+ errno = ENOENT;
+ archive_set_error(a, errno, "Unsupported ACL type");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (aclp == NULL) {
+ archive_set_error(a, errno,
+ "Can't allocate memory for acl buffer");
+ return (ARCHIVE_FAILED);
+ }
+
+ e = 0;
+
+ while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+ &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+ aclent = NULL;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ ace = NULL;
+#endif
+ if (cmd == SETACL) {
+ aclent = &((aclent_t *)aclp)[e];
+ aclent->a_id = -1;
+ aclent->a_type = 0;
+ aclent->a_perm = 0;
+ }
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else { /* cmd == ACE_SETACL */
+ ace = &((ace_t *)aclp)[e];
+ ace->a_who = -1;
+ ace->a_access_mask = 0;
+ ace->a_flags = 0;
+ }
+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
+
+ switch (ae_tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+ if (aclent != NULL) {
+ aclent->a_id = ae_uid;
+ aclent->a_type |= USER;
+ }
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else {
+ ace->a_who = ae_uid;
+ }
+#endif
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+ if (aclent != NULL) {
+ aclent->a_id = ae_gid;
+ aclent->a_type |= GROUP;
+ }
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else {
+ ace->a_who = ae_gid;
+ ace->a_flags |= ACE_IDENTIFIER_GROUP;
+ }
+#endif
+ break;
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ if (aclent != NULL)
+ aclent->a_type |= USER_OBJ;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else {
+ ace->a_flags |= ACE_OWNER;
+ }
+#endif
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ if (aclent != NULL)
+ aclent->a_type |= GROUP_OBJ;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else {
+ ace->a_flags |= ACE_GROUP;
+ ace->a_flags |= ACE_IDENTIFIER_GROUP;
+ }
+#endif
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ if (aclent != NULL)
+ aclent->a_type |= CLASS_OBJ;
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ if (aclent != NULL)
+ aclent->a_type |= OTHER_OBJ;
+ break;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ if (ace != NULL)
+ ace->a_flags |= ACE_EVERYONE;
+ break;
+#endif
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL tag");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ r = 0;
+ switch (ae_type) {
+#if ARCHIVE_ACL_SUNOS_NFS4
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ if (ace != NULL)
+ ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+ else
+ r = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ if (ace != NULL)
+ ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+ else
+ r = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+ if (ace != NULL)
+ ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
+ else
+ r = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+ if (ace != NULL)
+ ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
+ else
+ r = -1;
+ break;
+#endif
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+ if (aclent == NULL)
+ r = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+ if (aclent != NULL)
+ aclent->a_type |= ACL_DEFAULT;
+ else
+ r = -1;
+ break;
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unsupported ACL entry type");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+ if (r != 0) {
+ errno = EINVAL;
+ archive_set_error(a, errno,
+ "Failed to set ACL entry type");
+ ret = ARCHIVE_FAILED;
+ goto exit_free;
+ }
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+ if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ perm_map_size = acl_nfs4_perm_map_size;
+ perm_map = acl_nfs4_perm_map;
+ } else {
+#endif
+ perm_map_size = acl_posix_perm_map_size;
+ perm_map = acl_posix_perm_map;
+#if ARCHIVE_ACL_SUNOS_NFS4
+ }
+#endif
+ for (i = 0; i < perm_map_size; ++i) {
+ if (ae_permset & perm_map[i].a_perm) {
+#if ARCHIVE_ACL_SUNOS_NFS4
+ if (ae_requested_type ==
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4)
+ ace->a_access_mask |=
+ perm_map[i].p_perm;
+ else
+#endif
+ aclent->a_perm |= perm_map[i].p_perm;
+ }
+ }
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+ if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+ if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
+ ace->a_flags |=
+ acl_nfs4_flag_map[i].p_perm;
+ }
+ }
+ }
+#endif
+ e++;
+ }
+
+ /* Try restoring the ACL through 'fd' if we can. */
+ if (fd >= 0) {
+ if (facl(fd, cmd, entries, aclp) == 0)
+ ret = ARCHIVE_OK;
+ else {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno,
+ "Failed to set acl on fd: %s", tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+ } else if (acl(name, cmd, entries, aclp) != 0) {
+ if (errno == EOPNOTSUPP) {
+ /* Filesystem doesn't support ACLs */
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(a, errno, "Failed to set acl: %s",
+ tname);
+ ret = ARCHIVE_WARN;
+ }
+ }
+exit_free:
+ free(aclp);
+ return (ret);
+}
+
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ const char *accpath;
+ void *aclp;
+ int aclcnt;
+ int r;
+
+ accpath = NULL;
+
+ if (*fd < 0) {
+ accpath = archive_read_disk_entry_setup_path(a, entry, fd);
+ if (accpath == NULL)
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_acl_clear(entry);
+
+ aclp = NULL;
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+ if (*fd >= 0)
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
+ else if ((!a->follow_symlinks)
+ && (archive_entry_filetype(entry) == AE_IFLNK))
+ /* We can't get the ACL of a symlink, so we assume it can't
+ have one. */
+ aclp = NULL;
+ else
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);
+
+ if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
+ archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
+ &r) == 0 && r == 1) {
+ free(aclp);
+ aclp = NULL;
+ return (ARCHIVE_OK);
+ }
+
+ if (aclp != NULL) {
+ r = translate_acl(a, entry, aclp, aclcnt,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+ free(aclp);
+ aclp = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate NFSv4 ACLs");
+ }
+ return (r);
+ }
+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
+
+ /* Retrieve POSIX.1e ACLs from file. */
+ if (*fd >= 0)
+ aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
+ else if ((!a->follow_symlinks)
+ && (archive_entry_filetype(entry) == AE_IFLNK))
+ /* We can't get the ACL of a symlink, so we assume it can't
+ have one. */
+ aclp = NULL;
+ else
+ aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);
+
+ /* Ignore "trivial" ACLs that just mirror the file mode. */
+ if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
+ archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
+ &r) == 0 && r == 1) {
+ free(aclp);
+ aclp = NULL;
+ }
+
+ if (aclp != NULL)
+ {
+ r = translate_acl(a, entry, aclp, aclcnt,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ free(aclp);
+ aclp = NULL;
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate access ACLs");
+ return (r);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode)
+{
+ int ret = ARCHIVE_OK;
+
+ (void)mode; /* UNUSED */
+
+ if ((archive_acl_types(abstract_acl)
+ & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
+ /* Solaris writes POSIX.1e access and default ACLs together */
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
+
+ /* Simultaneous POSIX.1e and NFSv4 is not supported */
+ return (ret);
+ }
+#if ARCHIVE_ACL_SUNOS_NFS4
+ else if ((archive_acl_types(abstract_acl) &
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ ret = set_acl(a, fd, name, abstract_acl,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+ }
+#endif
+ return (ret);
+}
+#endif /* ARCHIVE_ACL_SUNOS */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.3 b/Utilities/cmlibarchive/libarchive/archive_entry.3
index f5e22af..f75916c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.3
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd Feburary 2, 2012
+.Dd February 2, 2012
.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index 10eff11..30fb456 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -401,7 +401,7 @@ archive_entry_fflags_text(struct archive_entry *entry)
return (NULL);
}
-int64_t
+la_int64_t
archive_entry_gid(struct archive_entry *entry)
{
return (entry->ae_stat.aest_gid);
@@ -502,7 +502,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
}
-int64_t
+la_int64_t
archive_entry_ino(struct archive_entry *entry)
{
return (entry->ae_stat.aest_ino);
@@ -514,7 +514,7 @@ archive_entry_ino_is_set(struct archive_entry *entry)
return (entry->ae_set & AE_SET_INO);
}
-int64_t
+la_int64_t
archive_entry_ino64(struct archive_entry *entry)
{
return (entry->ae_stat.aest_ino);
@@ -627,7 +627,7 @@ archive_entry_rdevminor(struct archive_entry *entry)
return minor(entry->ae_stat.aest_rdev);
}
-int64_t
+la_int64_t
archive_entry_size(struct archive_entry *entry)
{
return (entry->ae_stat.aest_size);
@@ -715,7 +715,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
}
-int64_t
+la_int64_t
archive_entry_uid(struct archive_entry *entry)
{
return (entry->ae_stat.aest_uid);
@@ -819,7 +819,7 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
}
void
-archive_entry_set_gid(struct archive_entry *entry, int64_t g)
+archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
{
entry->stat_valid = 0;
entry->ae_stat.aest_gid = g;
@@ -868,7 +868,7 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
}
void
-archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
+archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
{
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
@@ -876,7 +876,7 @@ archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
}
void
-archive_entry_set_ino64(struct archive_entry *entry, int64_t ino)
+archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
{
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
@@ -1209,7 +1209,7 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
}
void
-archive_entry_set_size(struct archive_entry *entry, int64_t s)
+archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
{
entry->stat_valid = 0;
entry->ae_stat.aest_size = s;
@@ -1306,7 +1306,7 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
}
void
-archive_entry_set_uid(struct archive_entry *entry, int64_t u)
+archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
{
entry->stat_valid = 0;
entry->ae_stat.aest_uid = u;
@@ -1638,7 +1638,7 @@ _archive_entry_acl_text_l(struct archive_entry *entry, int flags,
* SUCH DAMAGE.
*/
-static struct flag {
+static const struct flag {
const char *name;
const wchar_t *wname;
unsigned long set;
@@ -1708,6 +1708,9 @@ static struct flag {
#ifdef UF_COMPRESSED
{ "nocompressed",L"nocompressed", UF_COMPRESSED, 0 },
#endif
+#ifdef UF_HIDDEN
+ { "nohidden", L"nohidden", UF_HIDDEN, 0 },
+#endif
#if defined(FS_UNRM_FL)
{ "nouunlink", L"nouunlink", FS_UNRM_FL, 0},
#elif defined(EXT2_UNRM_FL)
@@ -1840,7 +1843,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
char *string, *dp;
const char *sp;
unsigned long bits;
- struct flag *flag;
+ const struct flag *flag;
size_t length;
bits = bitset | bitclear;
@@ -1892,7 +1895,7 @@ static const char *
ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
{
const char *start, *end;
- struct flag *flag;
+ const struct flag *flag;
unsigned long set, clear;
const char *failed;
@@ -1960,7 +1963,7 @@ static const wchar_t *
ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
{
const wchar_t *start, *end;
- struct flag *flag;
+ const struct flag *flag;
unsigned long set, clear;
const wchar_t *failed;
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 6e0225b..8c8e75a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3003001
+#define ARCHIVE_VERSION_NUMBER 3003002
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3 b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
index c5115f7..534dbfa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
@@ -32,7 +32,7 @@
.Nm archive_entry_acl_clear ,
.Nm archive_entry_acl_count ,
.Nm archive_entry_acl_from_text ,
-.Nm archive_entry_acl_from_text_w,
+.Nm archive_entry_acl_from_text_w ,
.Nm archive_entry_acl_next ,
.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,
@@ -267,7 +267,7 @@ Only inherit, do not apply the permission on the directory itself.
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
Do not propagate inherit flags. Only first-level entries inherit ACLs.
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
-Trigger alarm or audit on succesful access.
+Trigger alarm or audit on successful access.
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
Trigger alarm or audit on failed access.
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I )
@@ -279,7 +279,7 @@ and
.Fn archive_entry_acl_add_entry_w
add a single ACL entry.
For the access ACL and non-extended principals, the classic Unix permissions
-are updated. An archive enry cannot contain both POSIX.1e and NFSv4 ACL
+are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL
entries.
.Pp
.Fn archive_entry_acl_clear
@@ -303,7 +303,7 @@ for POSIX.1e ACLs and
for NFSv4 ACLs. For POSIX.1e ACLs if
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
is included and at least one extended ACL entry is found,
-the three non-extened ACLs are added.
+the three non-extended ACLs are added.
.Pp
.Fn archive_entry_acl_from_text
and
@@ -367,7 +367,7 @@ and
.Fn archive_entry_acl_to_text_w
convert the ACL entries for the given type into a
.Pq wide
-string of ACL entries separated by newline. If the the pointer
+string of ACL entries separated by newline. If the pointer
.Fa len_p
is not NULL, then the function shall return the length of the string
.Pq not including the NULL terminator
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3 b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
index fd22cf7..f647212 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
@@ -31,25 +31,25 @@
.Nm archive_entry_set_hardlink ,
.Nm archive_entry_copy_hardlink ,
.Nm archive_entry_copy_hardlink_w ,
-.Nm archve_entry_update_hardlink_utf8 ,
+.Nm archive_entry_update_hardlink_utf8 ,
.Nm archive_entry_set_link ,
.Nm archive_entry_copy_link ,
.Nm archive_entry_copy_link_w ,
-.Nm archve_entry_update_link_utf8 ,
+.Nm archive_entry_update_link_utf8 ,
.Nm archive_entry_pathname ,
.Nm archive_entry_pathname_w ,
.Nm archive_entry_set_pathname ,
.Nm archive_entry_copy_pathname ,
.Nm archive_entry_copy_pathname_w ,
-.Nm archve_entry_update_pathname_utf8 ,
+.Nm archive_entry_update_pathname_utf8 ,
.Nm archive_entry_sourcepath ,
.Nm archive_entry_copy_sourcepath ,
-.Nm archive_entry_symlink,
-.Nm archive_entry_symlink_w,
+.Nm archive_entry_symlink ,
+.Nm archive_entry_symlink_w ,
.Nm archive_entry_set_symlink ,
.Nm archive_entry_copy_symlink ,
.Nm archive_entry_copy_symlink_w ,
-.Nm archve_entry_update_symlink_utf8
+.Nm archive_entry_update_symlink_utf8
.Nd functions for manipulating path names in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3 b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
index 340c5ea..aae3648 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
@@ -34,8 +34,8 @@
.Nm archive_entry_perm ,
.Nm archive_entry_set_perm ,
.Nm archive_entry_strmode ,
-.Nm archive_entry_uname
-.Nm archive_entry_uname_w
+.Nm archive_entry_uname ,
+.Nm archive_entry_uname_w ,
.Nm archive_entry_set_uname ,
.Nm archive_entry_copy_uname ,
.Nm archive_entry_copy_uname_w ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
index fed74f5..74917b3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
@@ -51,7 +51,7 @@ archive_entry_sparse_clear(struct archive_entry *entry)
void
archive_entry_sparse_add_entry(struct archive_entry *entry,
- int64_t offset, int64_t length)
+ la_int64_t offset, la_int64_t length)
{
struct ae_sparse *sp;
@@ -135,7 +135,7 @@ archive_entry_sparse_reset(struct archive_entry * entry)
int
archive_entry_sparse_next(struct archive_entry * entry,
- int64_t *offset, int64_t *length)
+ la_int64_t *offset, la_int64_t *length)
{
if (entry->sparse_p) {
*offset = entry->sparse_p->offset;
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.c b/Utilities/cmlibarchive/libarchive/archive_getdate.c
index beb0cba..030c083 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.c
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.c
@@ -691,7 +691,7 @@ Convert(time_t Month, time_t Day, time_t Year,
time_t Hours, time_t Minutes, time_t Seconds,
time_t Timezone, enum DSTMODE DSTmode)
{
- static int DaysInMonth[12] = {
+ signed char DaysInMonth[12] = {
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
time_t Julian;
diff --git a/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
index 2deeb5f..59f95b8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
@@ -28,7 +28,7 @@
#include <openssl/hmac.h>
#include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
static inline HMAC_CTX *HMAC_CTX_new(void)
diff --git a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
index 6b7b472..098881b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
+++ b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
@@ -280,7 +280,7 @@ pack_bsdos(int n, unsigned long numbers[], const char **error)
/* list of formats and pack functions */
/* this list must be sorted lexically */
-static struct format {
+static const struct format {
const char *name;
pack_t *pack;
} formats[] = {
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index 47d144b..4cb8f81 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -148,32 +148,6 @@
#endif
/*
- * If this platform has <sys/acl.h>, acl_create(), acl_init(),
- * acl_set_file(), and ACL_USER, we assume it has the rest of the
- * POSIX.1e draft functions used in archive_read_extract.c.
- */
-#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
-#if HAVE_ACL_USER
-#define HAVE_POSIX_ACL 1
-#elif HAVE_ACL_TYPE_EXTENDED
-#define HAVE_DARWIN_ACL 1
-#endif
-#endif
-
-/*
- * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
- * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
- */
-#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
-#define HAVE_SUN_ACL 1
-#endif
-
-/* Define if platform supports NFSv4 ACLs */
-#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
-#define HAVE_NFS4_ACL 1
-#endif
-
-/*
* If we can't restore metadata using a file descriptor, then
* for compatibility's sake, close files before trying to restore metadata.
*/
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_acl.h b/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
new file mode 100644
index 0000000..3498f78
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * 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$
+ */
+
+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
+
+#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
+#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
+
+/*
+ * Determine what ACL types are supported
+ */
+#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL
+#define ARCHIVE_ACL_POSIX1E 1
+#endif
+
+#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \
+ ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
+#define ARCHIVE_ACL_NFS4 1
+#endif
+
+#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4
+#define ARCHIVE_ACL_SUPPORT 1
+#endif
+
+#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h b/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
new file mode 100644
index 0000000..4edfecf
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * 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$
+ */
+
+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
+
+#ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED
+#define ARCHIVE_PLATFORM_XATTR_H_INCLUDED
+
+/*
+ * Determine if we support extended attributes
+ */
+#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_FREEBSD || \
+ ARCHIVE_XATTR_AIX
+#define ARCHIVE_XATTR_SUPPORT 1
+#endif
+
+#endif /* ARCHIVE_PLATFORM_XATTR_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_random.c b/Utilities/cmlibarchive/libarchive/archive_random.c
index 90ee7c6..65ea691 100644
--- a/Utilities/cmlibarchive/libarchive/archive_random.c
+++ b/Utilities/cmlibarchive/libarchive/archive_random.c
@@ -221,7 +221,10 @@ arc4_stir(void)
/*
* Discard early keystream, as per recommendations in:
* "(Not So) Random Shuffles of RC4" by Ilya Mironov.
+ * As per the Network Operations Division, cryptographic requirements
+ * published on wikileaks on March 2017.
*/
+
for (i = 0; i < 3072; i++)
(void)arc4_getbyte();
arc4_count = 1600000;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index d1feceb..a642a33 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -881,7 +881,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
len = a->read_data_remaining;
if (len > s)
len = s;
- memcpy(dest, a->read_data_block, len);
+ if (len)
+ memcpy(dest, a->read_data_block, len);
s -= len;
a->read_data_block += len;
a->read_data_remaining -= len;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk.3 b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
index 2a5c130..027f63c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
@@ -24,11 +24,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 30, 2016
+.Dd April 3, 2017
.Dt ARCHIVE_READ_DISK 3
.Os
.Sh NAME
.Nm archive_read_disk_new ,
+.Nm archive_read_disk_set_behavior ,
.Nm archive_read_disk_set_symlink_logical ,
.Nm archive_read_disk_set_symlink_physical ,
.Nm archive_read_disk_set_symlink_hybrid ,
@@ -37,10 +38,7 @@
.Nm archive_read_disk_uname ,
.Nm archive_read_disk_set_uname_lookup ,
.Nm archive_read_disk_set_gname_lookup ,
-.Nm archive_read_disk_set_standard_lookup ,
-.Nm archive_read_close ,
-.Nm archive_read_finish ,
-.Nm archive_read_free
+.Nm archive_read_disk_set_standard_lookup
.Nd functions for reading objects from disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -49,6 +47,8 @@ Streaming Archive Library (libarchive, -larchive)
.Ft struct archive *
.Fn archive_read_disk_new "void"
.Ft int
+.Fn archive_read_disk_set_behavior "struct archive *" "int"
+.Ft int
.Fn archive_read_disk_set_symlink_logical "struct archive *"
.Ft int
.Fn archive_read_disk_set_symlink_physical "struct archive *"
@@ -81,12 +81,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "int fd"
.Fa "const struct stat *"
.Fc
-.Ft int
-.Fn archive_read_close "struct archive *"
-.Ft int
-.Fn archive_read_finish "struct archive *"
-.Ft int
-.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide an API for reading information about
objects on disk.
@@ -98,6 +92,51 @@ objects.
Allocates and initializes a
.Tn struct archive
object suitable for reading object information from disk.
+.It Fn archive_read_disk_set_behavior
+Configures various behavior options when reading entries from disk.
+The flags field consists of a bitwise OR of one or more of the
+following values:
+.Bl -tag -compact -width "indent"
+.It Cm ARCHIVE_READDISK_HONOR_NODUMP
+Skip files and directories with the nodump file attribute (file flag) set.
+By default, the nodump file atrribute is ignored.
+.It Cm ARCHIVE_READDISK_MAC_COPYFILE
+Mac OS X specific. Read metadata (ACLs and extended attributes) with
+.Xr copyfile 3 .
+By default, metadata is read using
+.Xr copyfile 3 .
+.It Cm ARCHIVE_READDISK_NO_ACL
+Do not read Access Control Lists.
+By default, ACLs are read from disk.
+.It Cm ARCHIVE_READDISK_NO_FFLAGS
+Do not read file attributes (file flags).
+By default, file attributes are read from disk.
+See
+.Xr chattr 1
+.Pq Linux
+or
+.Xr chflags 1
+.Pq FreeBSD, Mac OS X
+for more information on file attributes.
+.It Cm ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
+Do not traverse mount points.
+By defaut, moint points are traversed.
+.It Cm ARCHIVE_READDISK_NO_XATTR
+Do not read extended file attributes (xattrs).
+By default, extended file attributes are read from disk.
+See
+.Xr xattr 7
+.Pq Linux ,
+.Xr xattr 2
+.Pq Mac OS X ,
+or
+.Xr getextattr 8
+.Pq FreeBSD
+for more information on extended file attributes.
+.It Cm ARCHIVE_READDISK_RESTORE_ATIME
+Restore access time of traversed files.
+By default, access time of traversed files is not restored.
+.El
.It Xo
.Fn archive_read_disk_set_symlink_logical ,
.Fn archive_read_disk_set_symlink_physical ,
@@ -181,17 +220,6 @@ using the currently registered lookup functions above.
This affects the file ownership fields and ACL values in the
.Tn struct archive_entry
object.
-.It Fn archive_read_close
-Does nothing for
-.Tn archive_read_disk
-handles.
-.It Fn archive_read_finish
-This is a deprecated synonym for
-.Fn archive_read_free .
-.It Fn archive_read_free
-Invokes
-.Fn archive_read_close
-if it was not invoked manually, then releases all resources.
.El
More information about the
.Va struct archive
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
index b2f1d17..548ba89 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -26,23 +26,14 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 201084 2009-12-28 02:14:09Z kientzle $");
+__FBSDID("$FreeBSD");
/* This is the tree-walking code for POSIX systems. */
#if !defined(_WIN32) || defined(__CYGWIN__)
#ifdef HAVE_SYS_TYPES_H
-/* Mac OSX requires sys/types.h before sys/acl.h. */
#include <sys/types.h>
#endif
-#ifdef HAVE_SYS_ACL_H
-#include <sys/acl.h>
-#endif
-#ifdef HAVE_DARWIN_ACL
-#include <membership.h>
-#include <grp.h>
-#include <pwd.h>
-#endif
#ifdef HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
@@ -63,9 +54,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#ifdef HAVE_SYS_EA_H
#include <sys/ea.h>
#endif
-#ifdef HAVE_ACL_LIBACL_H
-#include <acl/libacl.h>
-#endif
#ifdef HAVE_COPYFILE_H
#include <copyfile.h>
#endif
@@ -113,27 +101,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#define O_CLOEXEC 0
#endif
-/*
- * Linux and FreeBSD plug this obvious hole in POSIX.1e in
- * different ways.
- */
-#if HAVE_ACL_GET_PERM
-#define ACL_GET_PERM acl_get_perm
-#elif HAVE_ACL_GET_PERM_NP
-#define ACL_GET_PERM acl_get_perm_np
-#endif
-
-/* NFSv4 platform ACL type */
-#if HAVE_SUN_ACL
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
-#elif HAVE_DARWIN_ACL
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
-#elif HAVE_ACL_TYPE_NFS4
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
-#endif
-
-static int setup_acls(struct archive_read_disk *,
- struct archive_entry *, int *fd);
static int setup_mac_metadata(struct archive_read_disk *,
struct archive_entry *, int *fd);
static int setup_xattrs(struct archive_read_disk *,
@@ -145,6 +112,45 @@ static int setup_sparse_fiemap(struct archive_read_disk *,
struct archive_entry *, int *fd);
#endif
+#if !ARCHIVE_ACL_SUPPORT
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#endif
+
+/*
+ * Enter working directory and return working pathname of archive_entry.
+ * If a pointer to an integer is provided and its value is below zero
+ * open a file descriptor on this pahtname.
+ */
+const char *
+archive_read_disk_entry_setup_path(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ const char *path;
+
+ path = archive_entry_sourcepath(entry);
+
+ if (path == NULL || (a->tree != NULL &&
+ a->tree_enter_working_dir(a->tree) != 0))
+ path = archive_entry_pathname(entry);
+ if (path == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't determine path");
+ } else if (fd != NULL && *fd < 0 && a->tree != NULL &&
+ (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) {
+ *fd = a->open_on_current_dir(a->tree, path,
+ O_RDONLY | O_NONBLOCK);
+ }
+ return (path);
+}
+
int
archive_read_disk_entry_from_file(struct archive *_a,
struct archive_entry *entry,
@@ -279,7 +285,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
r = 0;
if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
- r = setup_acls(a, entry, &fd);
+ r = archive_read_disk_entry_setup_acls(a, entry, &fd);
if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
r1 = setup_xattrs(a, entry, &fd);
if (r1 < r)
@@ -328,19 +334,10 @@ setup_mac_metadata(struct archive_read_disk *a,
struct archive_string tempfile;
(void)fd; /* UNUSED */
- name = archive_entry_sourcepath(entry);
+
+ name = archive_read_disk_entry_setup_path(a, entry, NULL);
if (name == NULL)
- name = archive_entry_pathname(entry);
- else if (a->tree != NULL && a->tree_enter_working_dir(a->tree) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't change dir to read extended attributes");
- return (ARCHIVE_FAILED);
- }
- if (name == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't open file to read extended attributes: No name");
return (ARCHIVE_WARN);
- }
/* Short-circuit if there's nothing to do. */
have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
@@ -426,996 +423,10 @@ setup_mac_metadata(struct archive_read_disk *a,
}
#endif
-#if HAVE_DARWIN_ACL
-static int translate_guid(struct archive *, acl_entry_t,
- int *, int *, const char **);
-
-static void add_trivial_nfs4_acl(struct archive_entry *);
-#endif
-
-#if HAVE_SUN_ACL
-static int
-sun_acl_is_trivial(acl_t *, mode_t, int *trivialp);
-#endif
-
-#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
-static int translate_acl(struct archive_read_disk *a,
- struct archive_entry *entry,
-#if HAVE_SUN_ACL
- acl_t *acl,
-#else
- acl_t acl,
-#endif
- int archive_entry_acl_type);
-
-static int
-setup_acls(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- const char *accpath;
-#if HAVE_SUN_ACL
- acl_t *acl;
-#else
- acl_t acl;
-#endif
- int r;
-
- accpath = NULL;
-
-#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP
- if (*fd < 0)
-#else
- /* For default ACLs on Linux we need reachable accpath */
- if (*fd < 0 || S_ISDIR(archive_entry_mode(entry)))
-#endif
- {
- accpath = archive_entry_sourcepath(entry);
- if (accpath == NULL || (a->tree != NULL &&
- a->tree_enter_working_dir(a->tree) != 0))
- accpath = archive_entry_pathname(entry);
- if (accpath == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't determine file path to read ACLs");
- return (ARCHIVE_WARN);
- }
- if (a->tree != NULL &&
-#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP
- *fd < 0 &&
-#endif
- (a->follow_symlinks ||
- archive_entry_filetype(entry) != AE_IFLNK)) {
- *fd = a->open_on_current_dir(a->tree,
- accpath, O_RDONLY | O_NONBLOCK);
- }
- }
-
- archive_entry_acl_clear(entry);
-
- acl = NULL;
-
-#if HAVE_NFS4_ACL
- /* Try NFSv4 ACL first. */
- if (*fd >= 0)
-#if HAVE_SUN_ACL
- /* Solaris reads both POSIX.1e and NFSv4 ACL here */
- facl_get(*fd, 0, &acl);
-#elif HAVE_ACL_GET_FD_NP
- acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
-#else
- acl = acl_get_fd(*fd);
-#endif
-#if HAVE_ACL_GET_LINK_NP
- else if (!a->follow_symlinks)
- acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
-#else
- else if ((!a->follow_symlinks)
- && (archive_entry_filetype(entry) == AE_IFLNK))
- /* We can't get the ACL of a symlink, so we assume it can't
- have one. */
- acl = NULL;
-#endif
- else
-#if HAVE_SUN_ACL
- /* Solaris reads both POSIX.1e and NFSv4 ACLs here */
- acl_get(accpath, 0, &acl);
-#else
- acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
-#endif
-
-
-#if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL
- /* Ignore "trivial" ACLs that just mirror the file mode. */
- if (acl != NULL) {
-#if HAVE_SUN_ACL
- if (sun_acl_is_trivial(acl, archive_entry_mode(entry),
- &r) == 0 && r == 1)
-#elif HAVE_ACL_IS_TRIVIAL_NP
- if (acl_is_trivial_np(acl, &r) == 0 && r == 1)
-#endif
- {
- acl_free(acl);
- acl = NULL;
- /*
- * Simultaneous NFSv4 and POSIX.1e ACLs for the same
- * entry are not allowed, so we should return here
- */
- return (ARCHIVE_OK);
- }
- }
-#endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */
- if (acl != NULL) {
- r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
- acl_free(acl);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, errno,
- "Couldn't translate "
-#if !HAVE_SUN_ACL
- "NFSv4 "
-#endif
- "ACLs");
- }
-#if HAVE_DARWIN_ACL
- /*
- * Because Mac OS doesn't support owner@, group@ and everyone@
- * ACLs we need to add NFSv4 ACLs mirroring the file mode to
- * the archive entry. Otherwise extraction on non-Mac platforms
- * would lead to an invalid file mode.
- */
- if ((archive_entry_acl_types(entry) &
- ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
- add_trivial_nfs4_acl(entry);
-#endif
- return (r);
- }
-#endif /* HAVE_NFS4_ACL */
-
-#if HAVE_POSIX_ACL
- /* This code path is skipped on MacOS and Solaris */
+#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX
- /* Retrieve access ACL from file. */
- if (*fd >= 0)
- acl = acl_get_fd(*fd);
-#if HAVE_ACL_GET_LINK_NP
- else if (!a->follow_symlinks)
- acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
-#else
- else if ((!a->follow_symlinks)
- && (archive_entry_filetype(entry) == AE_IFLNK))
- /* We can't get the ACL of a symlink, so we assume it can't
- have one. */
- acl = NULL;
-#endif
- else
- acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
-
-#if HAVE_ACL_IS_TRIVIAL_NP
- /* Ignore "trivial" ACLs that just mirror the file mode. */
- if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) {
- if (r) {
- acl_free(acl);
- acl = NULL;
- }
- }
-#endif
-
- if (acl != NULL) {
- r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
- acl_free(acl);
- acl = NULL;
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, errno,
- "Couldn't translate access ACLs");
- return (r);
- }
- }
-
- /* Only directories can have default ACLs. */
- if (S_ISDIR(archive_entry_mode(entry))) {
-#if HAVE_ACL_GET_FD_NP
- if (*fd >= 0)
- acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
- else
-#endif
- acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
- if (acl != NULL) {
- r = translate_acl(a, entry, acl,
- ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
- acl_free(acl);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, errno,
- "Couldn't translate default ACLs");
- return (r);
- }
- }
- }
-#endif /* HAVE_POSIX_ACL */
- return (ARCHIVE_OK);
-}
-
-/*
- * Translate system ACL permissions into libarchive internal structure
- */
-static const struct {
- const int archive_perm;
- const int platform_perm;
-} acl_perm_map[] = {
-#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
- {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
- {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
- {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
- {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
- {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
- {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
- {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
- {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
- {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
-#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
- {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
- {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
- {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
- {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
- {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
- {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
- {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
- {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
- {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
- {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
- {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
-#else /* POSIX.1e ACL permissions */
- {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
- {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
- {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
- {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
- {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
- {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
- {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
- {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
- {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
- {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
- {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
-#endif
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
-};
-
-#if HAVE_NFS4_ACL
-/*
- * Translate system NFSv4 inheritance flags into libarchive internal structure
- */
-static const struct {
- const int archive_inherit;
- const int platform_inherit;
-} acl_inherit_map[] = {
-#if HAVE_SUN_ACL /* Solaris ACL inheritance flags */
- {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
- {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
-#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
- {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
-#else /* FreeBSD NFSv4 ACL inheritance flags */
- {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
- {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
- {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
-};
-#endif /* HAVE_NFS4_ACL */
-
-#if HAVE_DARWIN_ACL
-static int translate_guid(struct archive *a, acl_entry_t acl_entry,
- int *ae_id, int *ae_tag, const char **ae_name)
-{
- void *q;
- uid_t ugid;
- int r, idtype;
- struct passwd *pwd;
- struct group *grp;
-
- q = acl_get_qualifier(acl_entry);
- if (q == NULL)
- return (1);
- r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
- if (r != 0) {
- acl_free(q);
- return (1);
- }
- if (idtype == ID_TYPE_UID) {
- *ae_tag = ARCHIVE_ENTRY_ACL_USER;
- pwd = getpwuuid(q);
- if (pwd == NULL) {
- *ae_id = ugid;
- *ae_name = NULL;
- } else {
- *ae_id = pwd->pw_uid;
- *ae_name = archive_read_disk_uname(a, *ae_id);
- }
- } else if (idtype == ID_TYPE_GID) {
- *ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
- grp = getgruuid(q);
- if (grp == NULL) {
- *ae_id = ugid;
- *ae_name = NULL;
- } else {
- *ae_id = grp->gr_gid;
- *ae_name = archive_read_disk_gname(a, *ae_id);
- }
- } else
- r = 1;
-
- acl_free(q);
- return (r);
-}
-
-/*
- * Add trivial NFSv4 ACL entries from mode
- */
-static void
-add_trivial_nfs4_acl(struct archive_entry *entry)
-{
- mode_t mode;
- int i;
- const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
- const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
- ARCHIVE_ENTRY_ACL_APPEND_DATA;
- const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
- const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
- ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
- ARCHIVE_ENTRY_ACL_READ_ACL |
- ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
- const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
- ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
- ARCHIVE_ENTRY_ACL_WRITE_ACL |
- ARCHIVE_ENTRY_ACL_WRITE_OWNER;
-
- struct {
- const int type;
- const int tag;
- int permset;
- } tacl_entry[] = {
- {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
- {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
- {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
- {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
- {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
- {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
- };
-
- mode = archive_entry_mode(entry);
-
- /* Permissions for everyone@ */
- if (mode & 0004)
- tacl_entry[5].permset |= rperm;
- if (mode & 0002)
- tacl_entry[5].permset |= wperm;
- if (mode & 0001)
- tacl_entry[5].permset |= eperm;
-
- /* Permissions for group@ */
- if (mode & 0040)
- tacl_entry[4].permset |= rperm;
- else if (mode & 0004)
- tacl_entry[2].permset |= rperm;
- if (mode & 0020)
- tacl_entry[4].permset |= wperm;
- else if (mode & 0002)
- tacl_entry[2].permset |= wperm;
- if (mode & 0010)
- tacl_entry[4].permset |= eperm;
- else if (mode & 0001)
- tacl_entry[2].permset |= eperm;
-
- /* Permissions for owner@ */
- if (mode & 0400) {
- tacl_entry[3].permset |= rperm;
- if (!(mode & 0040) && (mode & 0004))
- tacl_entry[0].permset |= rperm;
- } else if ((mode & 0040) || (mode & 0004))
- tacl_entry[1].permset |= rperm;
- if (mode & 0200) {
- tacl_entry[3].permset |= wperm;
- if (!(mode & 0020) && (mode & 0002))
- tacl_entry[0].permset |= wperm;
- } else if ((mode & 0020) || (mode & 0002))
- tacl_entry[1].permset |= wperm;
- if (mode & 0100) {
- tacl_entry[3].permset |= eperm;
- if (!(mode & 0010) && (mode & 0001))
- tacl_entry[0].permset |= eperm;
- } else if ((mode & 0010) || (mode & 0001))
- tacl_entry[1].permset |= eperm;
-
- for (i = 0; i < 6; i++) {
- if (tacl_entry[i].permset != 0) {
- archive_entry_acl_add_entry(entry,
- tacl_entry[i].type, tacl_entry[i].permset,
- tacl_entry[i].tag, -1, NULL);
- }
- }
-
- return;
-}
-#elif HAVE_SUN_ACL
-/*
- * Check if acl is trivial
- * This is a FreeBSD acl_is_trivial_np() implementation for Solaris
- */
-static int
-sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
-{
- int i, p;
- const uint32_t rperm = ACE_READ_DATA;
- const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
- const uint32_t eperm = ACE_EXECUTE;
- const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
- ACE_READ_ACL | ACE_SYNCHRONIZE;
- const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
- ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
-
- ace_t *ace;
- ace_t tace[6];
-
- if (acl == NULL || trivialp == NULL)
- return (-1);
-
- *trivialp = 0;
-
- /* ACL_IS_TRIVIAL flag must be set for both POSIX.1e and NFSv4 ACLs */
- if ((acl->acl_flags & ACL_IS_TRIVIAL) == 0)
- return (0);
-
- /*
- * POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
- * FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
- * including mask.
- */
- if (acl->acl_type == ACLENT_T) {
- if (acl->acl_cnt == 4)
- *trivialp = 1;
- return (0);
- }
-
- if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
- return (-1);
-
- /*
- * Continue with checking NFSv4 ACLs
- *
- * Create list of trivial ace's to be compared
- */
-
- /* owner@ allow pre */
- tace[0].a_flags = ACE_OWNER;
- tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
- tace[0].a_access_mask = 0;
-
- /* owner@ deny */
- tace[1].a_flags = ACE_OWNER;
- tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
- tace[1].a_access_mask = 0;
-
- /* group@ deny */
- tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
- tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
- tace[2].a_access_mask = 0;
-
- /* owner@ allow */
- tace[3].a_flags = ACE_OWNER;
- tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
- tace[3].a_access_mask = ownset;
-
- /* group@ allow */
- tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
- tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
- tace[4].a_access_mask = pubset;
-
- /* everyone@ allow */
- tace[5].a_flags = ACE_EVERYONE;
- tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
- tace[5].a_access_mask = pubset;
-
- /* Permissions for everyone@ */
- if (mode & 0004)
- tace[5].a_access_mask |= rperm;
- if (mode & 0002)
- tace[5].a_access_mask |= wperm;
- if (mode & 0001)
- tace[5].a_access_mask |= eperm;
-
- /* Permissions for group@ */
- if (mode & 0040)
- tace[4].a_access_mask |= rperm;
- else if (mode & 0004)
- tace[2].a_access_mask |= rperm;
- if (mode & 0020)
- tace[4].a_access_mask |= wperm;
- else if (mode & 0002)
- tace[2].a_access_mask |= wperm;
- if (mode & 0010)
- tace[4].a_access_mask |= eperm;
- else if (mode & 0001)
- tace[2].a_access_mask |= eperm;
-
- /* Permissions for owner@ */
- if (mode & 0400) {
- tace[3].a_access_mask |= rperm;
- if (!(mode & 0040) && (mode & 0004))
- tace[0].a_access_mask |= rperm;
- } else if ((mode & 0040) || (mode & 0004))
- tace[1].a_access_mask |= rperm;
- if (mode & 0200) {
- tace[3].a_access_mask |= wperm;
- if (!(mode & 0020) && (mode & 0002))
- tace[0].a_access_mask |= wperm;
- } else if ((mode & 0020) || (mode & 0002))
- tace[1].a_access_mask |= wperm;
- if (mode & 0100) {
- tace[3].a_access_mask |= eperm;
- if (!(mode & 0010) && (mode & 0001))
- tace[0].a_access_mask |= eperm;
- } else if ((mode & 0010) || (mode & 0001))
- tace[1].a_access_mask |= eperm;
-
- /* Check if the acl count matches */
- p = 3;
- for (i = 0; i < 3; i++) {
- if (tace[i].a_access_mask != 0)
- p++;
- }
- if (acl->acl_cnt != p)
- return (0);
-
- p = 0;
- for (i = 0; i < 6; i++) {
- if (tace[i].a_access_mask != 0) {
- ace = &((ace_t *)acl->acl_aclp)[p];
- /*
- * Illumos added ACE_DELETE_CHILD to write perms for
- * directories. We have to check against that, too.
- */
- if (ace->a_flags != tace[i].a_flags ||
- ace->a_type != tace[i].a_type ||
- (ace->a_access_mask != tace[i].a_access_mask &&
- ((acl->acl_flags & ACL_IS_DIR) == 0 ||
- (tace[i].a_access_mask & wperm) == 0 ||
- ace->a_access_mask !=
- (tace[i].a_access_mask | ACE_DELETE_CHILD))))
- return (0);
- p++;
- }
- }
-
- *trivialp = 1;
- return (0);
-}
-#endif /* HAVE_SUN_ACL */
-
-#if HAVE_SUN_ACL
/*
- * Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
- */
-static int
-translate_acl(struct archive_read_disk *a,
- struct archive_entry *entry, acl_t *acl, int default_entry_acl_type)
-{
- int e, i;
- int ae_id, ae_tag, ae_perm;
- int entry_acl_type;
- const char *ae_name;
- aclent_t *aclent;
- ace_t *ace;
-
- (void)default_entry_acl_type;
-
- if (acl->acl_cnt <= 0)
- return (ARCHIVE_OK);
-
- for (e = 0; e < acl->acl_cnt; e++) {
- ae_name = NULL;
- ae_tag = 0;
- ae_perm = 0;
-
- if (acl->acl_type == ACE_T) {
- ace = &((ace_t *)acl->acl_aclp)[e];
- ae_id = ace->a_who;
-
- switch(ace->a_type) {
- case ACE_ACCESS_ALLOWED_ACE_TYPE:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
- break;
- case ACE_ACCESS_DENIED_ACE_TYPE:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
- break;
- case ACE_SYSTEM_AUDIT_ACE_TYPE:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- break;
- case ACE_SYSTEM_ALARM_ACE_TYPE:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
- break;
- default:
- /* Unknown entry type, skip */
- continue;
- }
-
- if ((ace->a_flags & ACE_OWNER) != 0)
- ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- else if ((ace->a_flags & ACE_GROUP) != 0)
- ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- else if ((ace->a_flags & ACE_EVERYONE) != 0)
- ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
- else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
- ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
- ae_name = archive_read_disk_gname(&a->archive,
- ae_id);
- } else {
- ae_tag = ARCHIVE_ENTRY_ACL_USER;
- ae_name = archive_read_disk_uname(&a->archive,
- ae_id);
- }
-
- for (i = 0; i < (int)(sizeof(acl_inherit_map) /
- sizeof(acl_inherit_map[0])); ++i) {
- if ((ace->a_flags &
- acl_inherit_map[i].platform_inherit) != 0)
- ae_perm |=
- acl_inherit_map[i].archive_inherit;
- }
-
- for (i = 0; i < (int)(sizeof(acl_perm_map) /
- sizeof(acl_perm_map[0])); ++i) {
- if ((ace->a_access_mask &
- acl_perm_map[i].platform_perm) != 0)
- ae_perm |=
- acl_perm_map[i].archive_perm;
- }
- } else {
- aclent = &((aclent_t *)acl->acl_aclp)[e];
- if ((aclent->a_type & ACL_DEFAULT) != 0)
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
- else
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- ae_id = aclent->a_id;
-
- switch(aclent->a_type) {
- case DEF_USER:
- case USER:
- ae_name = archive_read_disk_uname(&a->archive,
- ae_id);
- ae_tag = ARCHIVE_ENTRY_ACL_USER;
- break;
- case DEF_GROUP:
- case GROUP:
- ae_name = archive_read_disk_gname(&a->archive,
- ae_id);
- ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
- break;
- case DEF_CLASS_OBJ:
- case CLASS_OBJ:
- ae_tag = ARCHIVE_ENTRY_ACL_MASK;
- break;
- case DEF_USER_OBJ:
- case USER_OBJ:
- ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- break;
- case DEF_GROUP_OBJ:
- case GROUP_OBJ:
- ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- break;
- case DEF_OTHER_OBJ:
- case OTHER_OBJ:
- ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
- break;
- default:
- /* Unknown tag type, skip */
- continue;
- }
-
- if ((aclent->a_perm & 1) != 0)
- ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
- if ((aclent->a_perm & 2) != 0)
- ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
- if ((aclent->a_perm & 4) != 0)
- ae_perm |= ARCHIVE_ENTRY_ACL_READ;
- } /* default_entry_acl_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4 */
-
- archive_entry_acl_add_entry(entry, entry_acl_type,
- ae_perm, ae_tag, ae_id, ae_name);
- }
- return (ARCHIVE_OK);
-}
-#else /* !HAVE_SUN_ACL */
-/*
- * Translate POSIX.1e (Linux), FreeBSD (both POSIX.1e and NFSv4) and
- * MacOS (NFSv4 only) ACLs into libarchive internal structure
- */
-static int
-translate_acl(struct archive_read_disk *a,
- struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
-{
- acl_tag_t acl_tag;
-#if HAVE_ACL_TYPE_NFS4
- acl_entry_type_t acl_type;
- int brand;
-#endif
-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
- acl_flagset_t acl_flagset;
-#endif
- acl_entry_t acl_entry;
- acl_permset_t acl_permset;
- int i, entry_acl_type;
- int r, s, ae_id, ae_tag, ae_perm;
-#if !HAVE_DARWIN_ACL
- void *q;
-#endif
- const char *ae_name;
-
-#if HAVE_ACL_TYPE_NFS4
- // FreeBSD "brands" ACLs as POSIX.1e or NFSv4
- // Make sure the "brand" on this ACL is consistent
- // with the default_entry_acl_type bits provided.
- if (acl_get_brand_np(acl, &brand) != 0) {
- archive_set_error(&a->archive, errno,
- "Failed to read ACL brand");
- return (ARCHIVE_WARN);
- }
- switch (brand) {
- case ACL_BRAND_POSIX:
- switch (default_entry_acl_type) {
- case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
- case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid ACL entry type for POSIX.1e ACL");
- return (ARCHIVE_WARN);
- }
- break;
- case ACL_BRAND_NFS4:
- if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid ACL entry type for NFSv4 ACL");
- return (ARCHIVE_WARN);
- }
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unknown ACL brand");
- return (ARCHIVE_WARN);
- }
-#endif
-
- s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
- if (s == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to get first ACL entry");
- return (ARCHIVE_WARN);
- }
-
-#if HAVE_DARWIN_ACL
- while (s == 0)
-#else /* FreeBSD, Linux */
- while (s == 1)
-#endif
- {
- ae_id = -1;
- ae_name = NULL;
- ae_perm = 0;
-
- if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
- archive_set_error(&a->archive, errno,
- "Failed to get ACL tag type");
- return (ARCHIVE_WARN);
- }
- switch (acl_tag) {
-#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
- case ACL_USER:
- q = acl_get_qualifier(acl_entry);
- if (q != NULL) {
- ae_id = (int)*(uid_t *)q;
- acl_free(q);
- ae_name = archive_read_disk_uname(&a->archive,
- ae_id);
- }
- ae_tag = ARCHIVE_ENTRY_ACL_USER;
- break;
- case ACL_GROUP:
- q = acl_get_qualifier(acl_entry);
- if (q != NULL) {
- ae_id = (int)*(gid_t *)q;
- acl_free(q);
- ae_name = archive_read_disk_gname(&a->archive,
- ae_id);
- }
- ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
- break;
- case ACL_MASK:
- ae_tag = ARCHIVE_ENTRY_ACL_MASK;
- break;
- case ACL_USER_OBJ:
- ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- break;
- case ACL_GROUP_OBJ:
- ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- break;
- case ACL_OTHER:
- ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
- break;
-#if HAVE_ACL_TYPE_NFS4
- case ACL_EVERYONE:
- ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
- break;
-#endif
-#else /* HAVE_DARWIN_ACL */
- case ACL_EXTENDED_ALLOW:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
- r = translate_guid(&a->archive, acl_entry, &ae_id,
- &ae_tag, &ae_name);
- break;
- case ACL_EXTENDED_DENY:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
- r = translate_guid(&a->archive, acl_entry, &ae_id,
- &ae_tag, &ae_name);
- break;
-#endif /* HAVE_DARWIN_ACL */
- default:
- /* Skip types that libarchive can't support. */
- s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
- continue;
- }
-
-#if HAVE_DARWIN_ACL
- /* Skip if translate_guid() above failed */
- if (r != 0) {
- s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
- continue;
- }
-#endif
-
-#if !HAVE_DARWIN_ACL
- // XXX acl_type maps to allow/deny/audit/YYYY bits
- entry_acl_type = default_entry_acl_type;
-#endif
-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
- if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
-#if HAVE_ACL_TYPE_NFS4
- /*
- * acl_get_entry_type_np() fails with non-NFSv4 ACLs
- */
- if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
- archive_set_error(&a->archive, errno, "Failed "
- "to get ACL type from a NFSv4 ACL entry");
- return (ARCHIVE_WARN);
- }
- switch (acl_type) {
- case ACL_ENTRY_TYPE_ALLOW:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
- break;
- case ACL_ENTRY_TYPE_DENY:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
- break;
- case ACL_ENTRY_TYPE_AUDIT:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
- break;
- case ACL_ENTRY_TYPE_ALARM:
- entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
- break;
- default:
- archive_set_error(&a->archive, errno,
- "Invalid NFSv4 ACL entry type");
- return (ARCHIVE_WARN);
- }
-#endif /* HAVE_ACL_TYPE_NFS4 */
-
- /*
- * Libarchive stores "flag" (NFSv4 inheritance bits)
- * in the ae_perm bitmap.
- *
- * acl_get_flagset_np() fails with non-NFSv4 ACLs
- */
- if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
- archive_set_error(&a->archive, errno,
- "Failed to get flagset from a NFSv4 ACL entry");
- return (ARCHIVE_WARN);
- }
- for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
- r = acl_get_flag_np(acl_flagset,
- acl_inherit_map[i].platform_inherit);
- if (r == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to check flag in a NFSv4 "
- "ACL flagset");
- return (ARCHIVE_WARN);
- } else if (r)
- ae_perm |= acl_inherit_map[i].archive_inherit;
- }
- }
-#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL */
-
- if (acl_get_permset(acl_entry, &acl_permset) != 0) {
- archive_set_error(&a->archive, errno,
- "Failed to get ACL permission set");
- return (ARCHIVE_WARN);
- }
- for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
- /*
- * acl_get_perm() is spelled differently on different
- * platforms; see above.
- */
- r = ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm);
- if (r == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to check permission in an ACL permission set");
- return (ARCHIVE_WARN);
- } else if (r)
- ae_perm |= acl_perm_map[i].archive_perm;
- }
-
- archive_entry_acl_add_entry(entry, entry_acl_type,
- ae_perm, ae_tag,
- ae_id, ae_name);
-
- s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
-#if !HAVE_DARWIN_ACL
- if (s == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to get next ACL entry");
- return (ARCHIVE_WARN);
- }
-#endif
- }
- return (ARCHIVE_OK);
-}
-#endif /* !HAVE_SUN_ACL */
-#else /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
-static int
-setup_acls(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- (void)a; /* UNUSED */
- (void)entry; /* UNUSED */
- (void)fd; /* UNUSED */
- return (ARCHIVE_OK);
-}
-#endif /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
-
-#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
- HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
- (HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA)
-
-/*
- * Linux and AIX extended attribute support.
+ * Linux, Darwin and AIX extended attribute support.
*
* TODO: By using a stack-allocated buffer for the first
* call to getxattr(), we might be able to avoid the second
@@ -1433,21 +444,32 @@ setup_xattr(struct archive_read_disk *a,
ssize_t size;
void *value = NULL;
-#if HAVE_FGETXATTR
- if (fd >= 0)
+
+ if (fd >= 0) {
+#if ARCHIVE_XATTR_LINUX
size = fgetxattr(fd, name, NULL, 0);
- else if (!a->follow_symlinks)
- size = lgetxattr(accpath, name, NULL, 0);
- else
- size = getxattr(accpath, name, NULL, 0);
-#elif HAVE_FGETEA
- if (fd >= 0)
+#elif ARCHIVE_XATTR_DARWIN
+ size = fgetxattr(fd, name, NULL, 0, 0, 0);
+#elif ARCHIVE_XATTR_AIX
size = fgetea(fd, name, NULL, 0);
- else if (!a->follow_symlinks)
+#endif
+ } else if (!a->follow_symlinks) {
+#if ARCHIVE_XATTR_LINUX
+ size = lgetxattr(accpath, name, NULL, 0);
+#elif ARCHIVE_XATTR_DARWIN
+ size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW);
+#elif ARCHIVE_XATTR_AIX
size = lgetea(accpath, name, NULL, 0);
- else
+#endif
+ } else {
+#if ARCHIVE_XATTR_LINUX
+ size = getxattr(accpath, name, NULL, 0);
+#elif ARCHIVE_XATTR_DARWIN
+ size = getxattr(accpath, name, NULL, 0, 0, 0);
+#elif ARCHIVE_XATTR_AIX
size = getea(accpath, name, NULL, 0);
#endif
+ }
if (size == -1) {
archive_set_error(&a->archive, errno,
@@ -1460,21 +482,32 @@ setup_xattr(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
-#if HAVE_FGETXATTR
- if (fd >= 0)
+
+ if (fd >= 0) {
+#if ARCHIVE_XATTR_LINUX
size = fgetxattr(fd, name, value, size);
- else if (!a->follow_symlinks)
- size = lgetxattr(accpath, name, value, size);
- else
- size = getxattr(accpath, name, value, size);
-#elif HAVE_FGETEA
- if (fd >= 0)
+#elif ARCHIVE_XATTR_DARWIN
+ size = fgetxattr(fd, name, value, size, 0, 0);
+#elif ARCHIVE_XATTR_AIX
size = fgetea(fd, name, value, size);
- else if (!a->follow_symlinks)
+#endif
+ } else if (!a->follow_symlinks) {
+#if ARCHIVE_XATTR_LINUX
+ size = lgetxattr(accpath, name, value, size);
+#elif ARCHIVE_XATTR_DARWIN
+ size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW);
+#elif ARCHIVE_XATTR_AIX
size = lgetea(accpath, name, value, size);
- else
+#endif
+ } else {
+#if ARCHIVE_XATTR_LINUX
+ size = getxattr(accpath, name, value, size);
+#elif ARCHIVE_XATTR_DARWIN
+ size = getxattr(accpath, name, value, size, 0, 0);
+#elif ARCHIVE_XATTR_AIX
size = getea(accpath, name, value, size);
#endif
+ }
if (size == -1) {
archive_set_error(&a->archive, errno,
@@ -1499,38 +532,36 @@ setup_xattrs(struct archive_read_disk *a,
path = NULL;
if (*fd < 0) {
- path = archive_entry_sourcepath(entry);
- if (path == NULL || (a->tree != NULL &&
- a->tree_enter_working_dir(a->tree) != 0))
- path = archive_entry_pathname(entry);
- if (path == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't determine file path to read "
- "extended attributes");
+ path = archive_read_disk_entry_setup_path(a, entry, fd);
+ if (path == NULL)
return (ARCHIVE_WARN);
- }
- if (a->tree != NULL && (a->follow_symlinks ||
- archive_entry_filetype(entry) != AE_IFLNK)) {
- *fd = a->open_on_current_dir(a->tree,
- path, O_RDONLY | O_NONBLOCK);
- }
}
-#if HAVE_FLISTXATTR
- if (*fd >= 0)
+ if (*fd >= 0) {
+#if ARCHIVE_XATTR_LINUX
list_size = flistxattr(*fd, NULL, 0);
- else if (!a->follow_symlinks)
- list_size = llistxattr(path, NULL, 0);
- else
- list_size = listxattr(path, NULL, 0);
-#elif HAVE_FLISTEA
- if (*fd >= 0)
+#elif ARCHIVE_XATTR_DARWIN
+ list_size = flistxattr(*fd, NULL, 0, 0);
+#elif ARCHIVE_XATTR_AIX
list_size = flistea(*fd, NULL, 0);
- else if (!a->follow_symlinks)
+#endif
+ } else if (!a->follow_symlinks) {
+#if ARCHIVE_XATTR_LINUX
+ list_size = llistxattr(path, NULL, 0);
+#elif ARCHIVE_XATTR_DARWIN
+ list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
+#elif ARCHIVE_XATTR_AIX
list_size = llistea(path, NULL, 0);
- else
+#endif
+ } else {
+#if ARCHIVE_XATTR_LINUX
+ list_size = listxattr(path, NULL, 0);
+#elif ARCHIVE_XATTR_DARWIN
+ list_size = listxattr(path, NULL, 0, 0);
+#elif ARCHIVE_XATTR_AIX
list_size = listea(path, NULL, 0);
#endif
+ }
if (list_size == -1) {
if (errno == ENOTSUP || errno == ENOSYS)
@@ -1548,21 +579,31 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
-#if HAVE_FLISTXATTR
- if (*fd >= 0)
+ if (*fd >= 0) {
+#if ARCHIVE_XATTR_LINUX
list_size = flistxattr(*fd, list, list_size);
- else if (!a->follow_symlinks)
- list_size = llistxattr(path, list, list_size);
- else
- list_size = listxattr(path, list, list_size);
-#elif HAVE_FLISTEA
- if (*fd >= 0)
+#elif ARCHIVE_XATTR_DARWIN
+ list_size = flistxattr(*fd, list, list_size, 0);
+#elif ARCHIVE_XATTR_AIX
list_size = flistea(*fd, list, list_size);
- else if (!a->follow_symlinks)
+#endif
+ } else if (!a->follow_symlinks) {
+#if ARCHIVE_XATTR_LINUX
+ list_size = llistxattr(path, list, list_size);
+#elif ARCHIVE_XATTR_DARWIN
+ list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW);
+#elif ARCHIVE_XATTR_AIX
list_size = llistea(path, list, list_size);
- else
+#endif
+ } else {
+#if ARCHIVE_XATTR_LINUX
+ list_size = listxattr(path, list, list_size);
+#elif ARCHIVE_XATTR_DARWIN
+ list_size = listxattr(path, list, list_size, 0);
+#elif ARCHIVE_XATTR_AIX
list_size = listea(path, list, list_size);
#endif
+ }
if (list_size == -1) {
archive_set_error(&a->archive, errno,
@@ -1572,9 +613,21 @@ setup_xattrs(struct archive_read_disk *a,
}
for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
- if (strncmp(p, "system.", 7) == 0 ||
- strncmp(p, "xfsroot.", 8) == 0)
+#if ARCHIVE_XATTR_LINUX
+ /* Linux: skip POSIX.1e ACL extended attributes */
+ if (strncmp(p, "system.", 7) == 0 &&
+ (strcmp(p + 7, "posix_acl_access") == 0 ||
+ strcmp(p + 7, "posix_acl_default") == 0))
+ continue;
+ if (strncmp(p, "trusted.SGI_", 12) == 0 &&
+ (strcmp(p + 12, "ACL_DEFAULT") == 0 ||
+ strcmp(p + 12, "ACL_FILE") == 0))
+ continue;
+
+ /* Linux: xfsroot namespace is obsolete and unsupported */
+ if (strncmp(p, "xfsroot.", 8) == 0)
continue;
+#endif
setup_xattr(a, entry, p, *fd, path);
}
@@ -1582,8 +635,7 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_OK);
}
-#elif HAVE_EXTATTR_GET_FILE && HAVE_EXTATTR_LIST_FILE && \
- HAVE_DECL_EXTATTR_NAMESPACE_USER
+#elif ARCHIVE_XATTR_FREEBSD
/*
* FreeBSD extattr interface.
@@ -1658,21 +710,9 @@ setup_xattrs(struct archive_read_disk *a,
path = NULL;
if (*fd < 0) {
- path = archive_entry_sourcepath(entry);
- if (path == NULL || (a->tree != NULL &&
- a->tree_enter_working_dir(a->tree) != 0))
- path = archive_entry_pathname(entry);
- if (path == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't determine file path to read "
- "extended attributes");
+ path = archive_read_disk_entry_setup_path(a, entry, fd);
+ if (path == NULL)
return (ARCHIVE_WARN);
- }
- if (a->tree != NULL && (a->follow_symlinks ||
- archive_entry_filetype(entry) != AE_IFLNK)) {
- *fd = a->open_on_current_dir(a->tree,
- path, O_RDONLY | O_NONBLOCK);
- }
}
if (*fd >= 0)
@@ -1773,6 +813,7 @@ setup_sparse_fiemap(struct archive_read_disk *a,
int64_t size;
int count, do_fiemap, iters;
int exit_sts = ARCHIVE_OK;
+ const char *path;
if (archive_entry_filetype(entry) != AE_IFREG
|| archive_entry_size(entry) <= 0
@@ -1780,11 +821,10 @@ setup_sparse_fiemap(struct archive_read_disk *a,
return (ARCHIVE_OK);
if (*fd < 0) {
- const char *path;
-
- path = archive_entry_sourcepath(entry);
+ path = archive_read_disk_entry_setup_path(a, entry, NULL);
if (path == NULL)
- path = archive_entry_pathname(entry);
+ return (ARCHIVE_FAILED);
+
if (a->tree != NULL)
*fd = a->open_on_current_dir(a->tree, path,
O_RDONLY | O_NONBLOCK | O_CLOEXEC);
@@ -1880,6 +920,7 @@ setup_sparse(struct archive_read_disk *a,
off_t off_s, off_e;
int exit_sts = ARCHIVE_OK;
int check_fully_sparse = 0;
+ const char *path;
if (archive_entry_filetype(entry) != AE_IFREG
|| archive_entry_size(entry) <= 0
@@ -1887,20 +928,10 @@ setup_sparse(struct archive_read_disk *a,
return (ARCHIVE_OK);
/* Does filesystem support the reporting of hole ? */
- if (*fd < 0 && a->tree != NULL) {
- const char *path;
-
- path = archive_entry_sourcepath(entry);
- if (path == NULL)
- path = archive_entry_pathname(entry);
- *fd = a->open_on_current_dir(a->tree, path,
- O_RDONLY | O_NONBLOCK);
- if (*fd < 0) {
- archive_set_error(&a->archive, errno,
- "Can't open `%s'", path);
- return (ARCHIVE_FAILED);
- }
- }
+ if (*fd < 0)
+ path = archive_read_disk_entry_setup_path(a, entry, fd);
+ else
+ path = NULL;
if (*fd >= 0) {
#ifdef _PC_MIN_HOLE_SIZE
@@ -1911,12 +942,8 @@ setup_sparse(struct archive_read_disk *a,
if (initial_off != 0)
lseek(*fd, 0, SEEK_SET);
} else {
- const char *path;
-
- path = archive_entry_sourcepath(entry);
if (path == NULL)
- path = archive_entry_pathname(entry);
-
+ return (ARCHIVE_FAILED);
#ifdef _PC_MIN_HOLE_SIZE
if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
return (ARCHIVE_OK);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
index b5a8328..f03a0a9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
@@ -33,6 +33,8 @@
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
+#include "archive_platform_acl.h"
+
struct tree;
struct archive_entry;
@@ -86,4 +88,11 @@ struct archive_read_disk {
void *excluded_cb_data;
};
+const char *
+archive_read_disk_entry_setup_path(struct archive_read_disk *,
+ struct archive_entry *, int *);
+
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *,
+ struct archive_entry *, int *);
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_format.3 b/Utilities/cmlibarchive/libarchive/archive_read_format.3
index 53b9a7e..91c5d2c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_format.3
@@ -37,9 +37,9 @@
.Nm archive_read_support_format_empty ,
.Nm archive_read_support_format_iso9660 ,
.Nm archive_read_support_format_lha ,
-.Nm archive_read_support_format_mtree,
-.Nm archive_read_support_format_rar,
-.Nm archive_read_support_format_raw,
+.Nm archive_read_support_format_mtree ,
+.Nm archive_read_support_format_rar ,
+.Nm archive_read_support_format_raw ,
.Nm archive_read_support_format_tar ,
.Nm archive_read_support_format_xar ,
.Nm archive_read_support_format_zip
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open.3 b/Utilities/cmlibarchive/libarchive/archive_read_open.3
index 4d8272c..2278ebc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open.3
@@ -33,7 +33,7 @@
.Nm archive_read_open_fd ,
.Nm archive_read_open_FILE ,
.Nm archive_read_open_filename ,
-.Nm archive_read_open_memory ,
+.Nm archive_read_open_memory
.Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -67,7 +67,7 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "size_t block_size"
.Fc
.Ft int
-.Fn archive_read_open_memory "struct archive *" "void *buff" "size_t size"
+.Fn archive_read_open_memory "struct archive *" "const void *buff" "size_t size"
.Sh DESCRIPTION
.Bl -tag -compact -width indent
.It Fn archive_read_open
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
index 663e2d3..147f502 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -494,7 +494,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
if (read_buf == NULL)
goto truncated_error;
compressed_size = archive_le32dec(read_buf);
- if ((compressed_size & ~(1 << 31)) > state->flags.block_maximum_size)
+ if ((compressed_size & 0x7fffffff) > state->flags.block_maximum_size)
goto malformed_error;
/* A compressed size == 0 means the end of stream blocks. */
if (compressed_size == 0) {
@@ -504,8 +504,8 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
checksum_size = state->flags.block_checksum;
/* Check if the block is uncompressed. */
- if (compressed_size & (1 << 31)) {
- compressed_size &= ~(1 << 31);
+ if (compressed_size & 0x80000000U) {
+ compressed_size &= 0x7fffffff;
uncompressed_size = compressed_size;
} else
uncompressed_size = 0;/* Unknown yet. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 20eb157..51f79fa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -116,19 +116,11 @@ struct lzx_dec {
* coding tree, which is a binary tree. But a use of a large
* index table causes L1 cache read miss many times.
*/
-#define HTBL_BITS 10
int max_bits;
- int shift_bits;
int tbl_bits;
int tree_used;
- int tree_avail;
/* Direct access table. */
uint16_t *tbl;
- /* Binary tree table for extra bits over the direct access. */
- struct htree_t {
- uint16_t left;
- uint16_t right;
- } *tree;
} at, lt, mt, pt;
int loop;
@@ -187,7 +179,7 @@ struct lzx_stream {
#define CFDATA_cbData 4
#define CFDATA_cbUncomp 6
-static const char *compression_name[] = {
+static const char * const compression_name[] = {
"NONE",
"MSZIP",
"Quantum",
@@ -352,7 +344,6 @@ static int lzx_huffman_init(struct huffman *, size_t, int);
static void lzx_huffman_free(struct huffman *);
static int lzx_make_huffman_table(struct huffman *);
static inline int lzx_decode_huffman(struct huffman *, unsigned);
-static int lzx_decode_huffman_tree(struct huffman *, unsigned, int);
int
@@ -3127,7 +3118,6 @@ getdata:
static int
lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
{
- int bits;
if (hf->bitlen == NULL || hf->len_size != (int)len_size) {
free(hf->bitlen);
@@ -3138,21 +3128,11 @@ lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
} else
memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0]));
if (hf->tbl == NULL) {
- if (tbl_bits < HTBL_BITS)
- bits = tbl_bits;
- else
- bits = HTBL_BITS;
- hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
+ hf->tbl = malloc(((size_t)1 << tbl_bits) * sizeof(hf->tbl[0]));
if (hf->tbl == NULL)
return (ARCHIVE_FATAL);
hf->tbl_bits = tbl_bits;
}
- if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
- hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
- hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
- if (hf->tree == NULL)
- return (ARCHIVE_FATAL);
- }
return (ARCHIVE_OK);
}
@@ -3161,7 +3141,6 @@ lzx_huffman_free(struct huffman *hf)
{
free(hf->bitlen);
free(hf->tbl);
- free(hf->tree);
}
/*
@@ -3174,7 +3153,7 @@ lzx_make_huffman_table(struct huffman *hf)
const unsigned char *bitlen;
int bitptn[17], weight[17];
int i, maxbits = 0, ptn, tbl_size, w;
- int diffbits, len_avail;
+ int len_avail;
/*
* Initialize bit patterns.
@@ -3205,28 +3184,11 @@ lzx_make_huffman_table(struct huffman *hf)
weight[i] >>= ebits;
}
}
- if (maxbits > HTBL_BITS) {
- int htbl_max;
- uint16_t *p;
-
- diffbits = maxbits - HTBL_BITS;
- for (i = 1; i <= HTBL_BITS; i++) {
- bitptn[i] >>= diffbits;
- weight[i] >>= diffbits;
- }
- htbl_max = bitptn[HTBL_BITS] +
- weight[HTBL_BITS] * hf->freq[HTBL_BITS];
- p = &(hf->tbl[htbl_max]);
- while (p < &hf->tbl[1U<<HTBL_BITS])
- *p++ = 0;
- } else
- diffbits = 0;
- hf->shift_bits = diffbits;
/*
* Make the table.
*/
- tbl_size = 1 << HTBL_BITS;
+ tbl_size = 1 << hf->tbl_bits;
tbl = hf->tbl;
bitlen = hf->bitlen;
len_avail = hf->len_size;
@@ -3234,120 +3196,32 @@ lzx_make_huffman_table(struct huffman *hf)
for (i = 0; i < len_avail; i++) {
uint16_t *p;
int len, cnt;
- uint16_t bit;
- int extlen;
- struct htree_t *ht;
if (bitlen[i] == 0)
continue;
/* Get a bit pattern */
len = bitlen[i];
+ if (len > tbl_size)
+ return (0);
ptn = bitptn[len];
cnt = weight[len];
- if (len <= HTBL_BITS) {
- /* Calculate next bit pattern */
- if ((bitptn[len] = ptn + cnt) > tbl_size)
- return (0);/* Invalid */
- /* Update the table */
- p = &(tbl[ptn]);
- while (--cnt >= 0)
- p[cnt] = (uint16_t)i;
- continue;
- }
-
- /*
- * A bit length is too big to be housed to a direct table,
- * so we use a tree model for its extra bits.
- */
- bitptn[len] = ptn + cnt;
- bit = 1U << (diffbits -1);
- extlen = len - HTBL_BITS;
-
- p = &(tbl[ptn >> diffbits]);
- if (*p == 0) {
- *p = len_avail + hf->tree_used;
- ht = &(hf->tree[hf->tree_used++]);
- if (hf->tree_used > hf->tree_avail)
- return (0);/* Invalid */
- ht->left = 0;
- ht->right = 0;
- } else {
- if (*p < len_avail ||
- *p >= (len_avail + hf->tree_used))
- return (0);/* Invalid */
- ht = &(hf->tree[*p - len_avail]);
- }
- while (--extlen > 0) {
- if (ptn & bit) {
- if (ht->left < len_avail) {
- ht->left = len_avail + hf->tree_used;
- ht = &(hf->tree[hf->tree_used++]);
- if (hf->tree_used > hf->tree_avail)
- return (0);/* Invalid */
- ht->left = 0;
- ht->right = 0;
- } else {
- ht = &(hf->tree[ht->left - len_avail]);
- }
- } else {
- if (ht->right < len_avail) {
- ht->right = len_avail + hf->tree_used;
- ht = &(hf->tree[hf->tree_used++]);
- if (hf->tree_used > hf->tree_avail)
- return (0);/* Invalid */
- ht->left = 0;
- ht->right = 0;
- } else {
- ht = &(hf->tree[ht->right - len_avail]);
- }
- }
- bit >>= 1;
- }
- if (ptn & bit) {
- if (ht->left != 0)
- return (0);/* Invalid */
- ht->left = (uint16_t)i;
- } else {
- if (ht->right != 0)
- return (0);/* Invalid */
- ht->right = (uint16_t)i;
- }
+ /* Calculate next bit pattern */
+ if ((bitptn[len] = ptn + cnt) > tbl_size)
+ return (0);/* Invalid */
+ /* Update the table */
+ p = &(tbl[ptn]);
+ while (--cnt >= 0)
+ p[cnt] = (uint16_t)i;
}
return (1);
}
-static int
-lzx_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
-{
- struct htree_t *ht;
- int extlen;
-
- ht = hf->tree;
- extlen = hf->shift_bits;
- while (c >= hf->len_size) {
- c -= hf->len_size;
- if (extlen-- <= 0 || c >= hf->tree_used)
- return (0);
- if (rbits & (1U << extlen))
- c = ht[c].left;
- else
- c = ht[c].right;
- }
- return (c);
-}
-
static inline int
lzx_decode_huffman(struct huffman *hf, unsigned rbits)
{
int c;
- /*
- * At first search an index table for a bit pattern.
- * If it fails, search a huffman tree for.
- */
- c = hf->tbl[rbits >> hf->shift_bits];
+ c = hf->tbl[rbits];
if (c < hf->len_size)
return (c);
- /* This bit pattern needs to be found out at a huffman tree. */
- return (lzx_decode_huffman_tree(hf, rbits, c));
+ return (0);
}
-
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
index ffd4a85..ad9f782 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
@@ -165,7 +165,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 20116
struct links_entry {
struct links_entry *next;
struct links_entry *previous;
- int links;
+ unsigned int links;
dev_t dev;
int64_t ino;
char *name;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 3541330..4b436d1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -3021,8 +3021,9 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
- memcpy(new_pending_files, heap->files,
- heap->allocated * sizeof(new_pending_files[0]));
+ if (heap->allocated)
+ memcpy(new_pending_files, heap->files,
+ heap->allocated * sizeof(new_pending_files[0]));
if (heap->files != NULL)
free(heap->files);
heap->files = new_pending_files;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index ebd7f2c..1995e9c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -2480,7 +2480,7 @@ lzh_huffman_free(struct huffman *hf)
free(hf->tree);
}
-static char bitlen_tbl[0x400] = {
+static const char bitlen_tbl[0x400] = {
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index 4231ff5..44b6083 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -130,9 +130,7 @@ static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t)
static int skip(struct archive_read *a);
static int read_header(struct archive_read *,
struct archive_entry *);
-static int64_t mtree_atol10(char **);
-static int64_t mtree_atol8(char **);
-static int64_t mtree_atol(char **);
+static int64_t mtree_atol(char **, int base);
/*
* There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
@@ -399,41 +397,41 @@ bid_keycmp(const char *p, const char *key, ssize_t len)
static int
bid_keyword(const char *p, ssize_t len)
{
- static const char *keys_c[] = {
+ static const char * const keys_c[] = {
"content", "contents", "cksum", NULL
};
- static const char *keys_df[] = {
+ static const char * const keys_df[] = {
"device", "flags", NULL
};
- static const char *keys_g[] = {
+ static const char * const keys_g[] = {
"gid", "gname", NULL
};
- static const char *keys_il[] = {
+ static const char * const keys_il[] = {
"ignore", "inode", "link", NULL
};
- static const char *keys_m[] = {
+ static const char * const keys_m[] = {
"md5", "md5digest", "mode", NULL
};
- static const char *keys_no[] = {
+ static const char * const keys_no[] = {
"nlink", "nochange", "optional", NULL
};
- static const char *keys_r[] = {
+ static const char * const keys_r[] = {
"resdevice", "rmd160", "rmd160digest", NULL
};
- static const char *keys_s[] = {
+ static const char * const keys_s[] = {
"sha1", "sha1digest",
"sha256", "sha256digest",
"sha384", "sha384digest",
"sha512", "sha512digest",
"size", NULL
};
- static const char *keys_t[] = {
+ static const char * const keys_t[] = {
"tags", "time", "type", NULL
};
- static const char *keys_u[] = {
+ static const char * const keys_u[] = {
"uid", "uname", NULL
};
- const char **keys;
+ const char * const *keys;
int i;
switch (*p) {
@@ -1418,7 +1416,7 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
"Too many arguments");
return ARCHIVE_WARN;
}
- numbers[argc++] = (unsigned long)mtree_atol(&p);
+ numbers[argc++] = (unsigned long)mtree_atol(&p, 0);
}
if (argc < 2) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -1433,7 +1431,7 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
}
} else {
/* file system raw value. */
- result = (dev_t)mtree_atol(&val);
+ result = (dev_t)mtree_atol(&val, 0);
}
*pdev = result;
return ARCHIVE_OK;
@@ -1513,7 +1511,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
case 'g':
if (strcmp(key, "gid") == 0) {
*parsed_kws |= MTREE_HAS_GID;
- archive_entry_set_gid(entry, mtree_atol10(&val));
+ archive_entry_set_gid(entry, mtree_atol(&val, 10));
break;
}
if (strcmp(key, "gname") == 0) {
@@ -1523,7 +1521,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
}
case 'i':
if (strcmp(key, "inode") == 0) {
- archive_entry_set_ino(entry, mtree_atol10(&val));
+ archive_entry_set_ino(entry, mtree_atol(&val, 10));
break;
}
case 'l':
@@ -1535,14 +1533,14 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
break;
if (strcmp(key, "mode") == 0) {
- if (val[0] >= '0' && val[0] <= '9') {
+ if (val[0] >= '0' && val[0] <= '7') {
*parsed_kws |= MTREE_HAS_PERM;
archive_entry_set_perm(entry,
- (mode_t)mtree_atol8(&val));
+ (mode_t)mtree_atol(&val, 8));
} else {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Symbolic mode \"%s\" unsupported", val);
+ "Symbolic or non-octal mode \"%s\" unsupported", val);
return ARCHIVE_WARN;
}
break;
@@ -1551,7 +1549,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
if (strcmp(key, "nlink") == 0) {
*parsed_kws |= MTREE_HAS_NLINK;
archive_entry_set_nlink(entry,
- (unsigned int)mtree_atol10(&val));
+ (unsigned int)mtree_atol(&val, 10));
break;
}
case 'r':
@@ -1582,7 +1580,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
strcmp(key, "sha512digest") == 0)
break;
if (strcmp(key, "size") == 0) {
- archive_entry_set_size(entry, mtree_atol10(&val));
+ archive_entry_set_size(entry, mtree_atol(&val, 10));
break;
}
case 't':
@@ -1601,13 +1599,13 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
long ns = 0;
*parsed_kws |= MTREE_HAS_MTIME;
- m = mtree_atol10(&val);
+ m = mtree_atol(&val, 10);
/* Replicate an old mtree bug:
* 123456789.1 represents 123456789
* seconds and 1 nanosecond. */
if (*val == '.') {
++val;
- ns = (long)mtree_atol10(&val);
+ ns = (long)mtree_atol(&val, 10);
if (ns < 0)
ns = 0;
else if (ns > 999999999)
@@ -1670,7 +1668,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
case 'u':
if (strcmp(key, "uid") == 0) {
*parsed_kws |= MTREE_HAS_UID;
- archive_entry_set_uid(entry, mtree_atol10(&val));
+ archive_entry_set_uid(entry, mtree_atol(&val, 10));
break;
}
if (strcmp(key, "uname") == 0) {
@@ -1825,72 +1823,9 @@ parse_escapes(char *src, struct mtree_entry *mentry)
*dest = '\0';
}
-/*
- * Note that this implementation does not (and should not!) obey
- * locale settings; you cannot simply substitute strtol here, since
- * it does obey locale.
- */
-static int64_t
-mtree_atol8(char **p)
-{
- int64_t l, limit, last_digit_limit;
- int digit, base;
-
- base = 8;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
-
- l = 0;
- digit = **p - '0';
- while (digit >= 0 && digit < base) {
- if (l>limit || (l == limit && digit > last_digit_limit)) {
- l = INT64_MAX; /* Truncate on overflow. */
- break;
- }
- l = (l * base) + digit;
- digit = *++(*p) - '0';
- }
- return (l);
-}
-
-/*
- * Note that this implementation does not (and should not!) obey
- * locale settings; you cannot simply substitute strtol here, since
- * it does obey locale.
- */
-static int64_t
-mtree_atol10(char **p)
-{
- int64_t l, limit, last_digit_limit;
- int base, digit, sign;
-
- base = 10;
-
- if (**p == '-') {
- sign = -1;
- limit = ((uint64_t)(INT64_MAX) + 1) / base;
- last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
- ++(*p);
- } else {
- sign = 1;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
- }
-
- l = 0;
- digit = **p - '0';
- while (digit >= 0 && digit < base) {
- if (l > limit || (l == limit && digit > last_digit_limit))
- return (sign < 0) ? INT64_MIN : INT64_MAX;
- l = (l * base) + digit;
- digit = *++(*p) - '0';
- }
- return (sign < 0) ? -l : l;
-}
-
/* Parse a hex digit. */
static int
-parsehex(char c)
+parsedigit(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
@@ -1908,45 +1843,50 @@ parsehex(char c)
* it does obey locale.
*/
static int64_t
-mtree_atol16(char **p)
+mtree_atol(char **p, int base)
{
- int64_t l, limit, last_digit_limit;
- int base, digit, sign;
-
- base = 16;
+ int64_t l, limit;
+ int digit, last_digit_limit;
+
+ if (base == 0) {
+ if (**p != '0')
+ base = 10;
+ else if ((*p)[1] == 'x' || (*p)[1] == 'X') {
+ *p += 2;
+ base = 16;
+ } else {
+ base = 8;
+ }
+ }
if (**p == '-') {
- sign = -1;
- limit = ((uint64_t)(INT64_MAX) + 1) / base;
- last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
+ limit = INT64_MIN / base;
+ last_digit_limit = INT64_MIN % base;
++(*p);
+
+ l = 0;
+ digit = parsedigit(**p);
+ while (digit >= 0 && digit < base) {
+ if (l < limit || (l == limit && digit > last_digit_limit))
+ return INT64_MIN;
+ l = (l * base) - digit;
+ digit = parsedigit(*++(*p));
+ }
+ return l;
} else {
- sign = 1;
limit = INT64_MAX / base;
last_digit_limit = INT64_MAX % base;
- }
- l = 0;
- digit = parsehex(**p);
- while (digit >= 0 && digit < base) {
- if (l > limit || (l == limit && digit > last_digit_limit))
- return (sign < 0) ? INT64_MIN : INT64_MAX;
- l = (l * base) + digit;
- digit = parsehex(*++(*p));
- }
- return (sign < 0) ? -l : l;
-}
-
-static int64_t
-mtree_atol(char **p)
-{
- if (**p != '0')
- return mtree_atol10(p);
- if ((*p)[1] == 'x' || (*p)[1] == 'X') {
- *p += 2;
- return mtree_atol16(p);
+ l = 0;
+ digit = parsedigit(**p);
+ while (digit >= 0 && digit < base) {
+ if (l > limit || (l == limit && digit > last_digit_limit))
+ return INT64_MAX;
+ l = (l * base) + digit;
+ digit = parsedigit(*++(*p));
+ }
+ return l;
}
- return mtree_atol8(p);
}
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index 658d49d..a0e641e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -1750,7 +1750,7 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
return (-1);
for (j = 0; j < count; j++)
{
- rem = ((*p) << 16) | (rem >> 8);
+ rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
p++;
}
tm = localtime(&t);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index bd7f13d..30d5bc8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -155,6 +155,7 @@ struct tar {
int compat_2x;
int process_mac_extensions;
int read_concatenated_archives;
+ int realsize_override;
};
static int archive_block_is_null(const char *p);
@@ -527,6 +528,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
tar->entry_offset = 0;
gnu_clear_sparse_list(tar);
tar->realsize = -1; /* Mark this as "unset" */
+ tar->realsize_override = 0;
/* Setup default string conversion. */
tar->sconv = tar->opt_sconv;
@@ -1894,6 +1896,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
if (strcmp(key, "GNU.sparse.size") == 0) {
tar->realsize = tar_atol10(value, strlen(value));
archive_entry_set_size(entry, tar->realsize);
+ tar->realsize_override = 1;
}
/* GNU "0.1" sparse pax format. */
@@ -1925,6 +1928,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
if (strcmp(key, "GNU.sparse.realsize") == 0) {
tar->realsize = tar_atol10(value, strlen(value));
archive_entry_set_size(entry, tar->realsize);
+ tar->realsize_override = 1;
}
break;
case 'L':
@@ -1977,6 +1981,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.realsize") == 0) {
tar->realsize = tar_atol10(value, strlen(value));
+ tar->realsize_override = 1;
archive_entry_set_size(entry, tar->realsize);
} else if (strncmp(key, "SCHILY.xattr.", 13) == 0) {
pax_attribute_schily_xattr(entry, key, value,
@@ -2055,14 +2060,12 @@ pax_attribute(struct archive_read *a, struct tar *tar,
tar->entry_bytes_remaining
= tar_atol10(value, strlen(value));
/*
- * But, "size" is not necessarily the size of
- * the file on disk; if this is a sparse file,
- * the disk size may have already been set from
- * GNU.sparse.realsize or GNU.sparse.size or
- * an old GNU header field or SCHILY.realsize
- * or ....
+ * The "size" pax header keyword always overrides the
+ * "size" field in the tar header.
+ * GNU.sparse.realsize, GNU.sparse.size and
+ * SCHILY.realsize override this value.
*/
- if (tar->realsize < 0) {
+ if (!tar->realsize_override) {
archive_entry_set_size(entry,
tar->entry_bytes_remaining);
tar->realsize
@@ -2206,6 +2209,7 @@ header_gnutar(struct archive_read *a, struct tar *tar,
tar->realsize
= tar_atol(header->realsize, sizeof(header->realsize));
archive_entry_set_size(entry, tar->realsize);
+ tar->realsize_override = 1;
}
if (header->sparse[0].offset[0] != 0) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
index b162465..e875385 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -600,9 +600,10 @@ _warc_rdver(const char *buf, size_t bsz)
/* looks good so far, read the version number for a laugh */
buf += sizeof(magic) - 1U;
- if (isdigit(buf[0U]) && (buf[1U] == '.') && isdigit(buf[2U])) {
+ if (isdigit((unsigned char)buf[0U]) && (buf[1U] == '.') &&
+ isdigit((unsigned char)buf[2U])) {
/* we support a maximum of 2 digits in the minor version */
- if (isdigit(buf[3U]))
+ if (isdigit((unsigned char)buf[3U]))
end = 1U;
/* set up major version */
ver = (buf[0U] - '0') * 10000U;
@@ -686,7 +687,7 @@ _warc_rduri(const char *buf, size_t bsz)
/* spaces inside uri are not allowed, CRLF should follow */
for (p = val; p < eol; p++) {
- if (isspace(*p))
+ if (isspace((unsigned char)*p))
return res;
}
@@ -736,7 +737,7 @@ _warc_rdlen(const char *buf, size_t bsz)
while (val < eol && (*val == ' ' || *val == '\t'))
val++;
/* there must be at least one digit */
- if (!isdigit(*val))
+ if (!isdigit((unsigned char)*val))
return -1;
len = strtol(val, &on, 10);
if (on != eol) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index e56bd63..ddd4458 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -347,7 +347,7 @@ fake_crc32(unsigned long crc, const void *buff, size_t len)
return 0;
}
-static struct {
+static const struct {
int id;
const char * name;
} compression_methods[] = {
@@ -2407,7 +2407,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
* Examine Zip64 EOCD locator: If it's valid, store the information
* from it.
*/
-static void
+static int
read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
{
int64_t eocd64_offset;
@@ -2417,35 +2417,37 @@ read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
/* Central dir must be on first volume. */
if (archive_le32dec(p + 4) != 0)
- return;
+ return 0;
/* Must be only a single volume. */
if (archive_le32dec(p + 16) != 1)
- return;
+ return 0;
/* Find the Zip64 EOCD record. */
eocd64_offset = archive_le64dec(p + 8);
if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0)
- return;
+ return 0;
if ((p = __archive_read_ahead(a, 56, NULL)) == NULL)
- return;
+ return 0;
/* Make sure we can read all of it. */
eocd64_size = archive_le64dec(p + 4) + 12;
if (eocd64_size < 56 || eocd64_size > 16384)
- return;
+ return 0;
if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
- return;
+ return 0;
/* Sanity-check the EOCD64 */
if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */
- return;
+ return 0;
if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */
- return;
+ return 0;
/* CD can't be split. */
if (archive_le64dec(p + 24) != archive_le64dec(p + 32))
- return;
+ return 0;
/* Save the central directory offset for later use. */
zip->central_directory_offset = archive_le64dec(p + 48);
+
+ return 32;
}
static int
@@ -2483,15 +2485,14 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
if (memcmp(p + i, "PK\005\006", 4) == 0) {
int ret = read_eocd(zip, p + i,
current_offset + i);
- if (ret > 0) {
- /* Zip64 EOCD locator precedes
- * regular EOCD if present. */
- if (i >= 20
- && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
- read_zip64_eocd(a, zip, p + i - 20);
- }
- return (ret);
+ /* Zip64 EOCD locator precedes
+ * regular EOCD if present. */
+ if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
+ int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20);
+ if (ret_zip64 > ret)
+ ret = ret_zip64;
}
+ return (ret);
}
i -= 4;
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index 592ead2..5ae09b6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -202,7 +202,8 @@ archive_string_append(struct archive_string *as, const char *p, size_t s)
{
if (archive_string_ensure(as, as->length + s + 1) == NULL)
return (NULL);
- memmove(as->s + as->length, p, s);
+ if (s)
+ memmove(as->s + as->length, p, s);
as->length += s;
as->s[as->length] = 0;
return (as);
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
index 964ea2b..969a560 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-
static void
append_uint(struct archive_string *as, uintmax_t d, unsigned base)
{
- static const char *digits = "0123456789abcdef";
+ static const char digits[] = "0123456789abcdef";
if (d >= base)
append_uint(as, d/base, base);
archive_strappend_char(as, digits[d % base]);
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index f56ca33..1e36ad7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -89,88 +89,6 @@ archive_version_string(void)
return (ARCHIVE_VERSION_STRING);
}
-const char *
-archive_version_details(void)
-{
- static struct archive_string str;
- static int init = 0;
- const char *zlib = archive_zlib_version();
- const char *liblzma = archive_liblzma_version();
- const char *bzlib = archive_bzlib_version();
- const char *liblz4 = archive_liblz4_version();
-
- if (!init) {
- archive_string_init(&str);
-
- archive_strcat(&str, ARCHIVE_VERSION_STRING);
- if (zlib != NULL) {
- archive_strcat(&str, " zlib/");
- archive_strcat(&str, zlib);
- }
- if (liblzma) {
- archive_strcat(&str, " liblzma/");
- archive_strcat(&str, liblzma);
- }
- if (bzlib) {
- const char *p = bzlib;
- const char *sep = strchr(p, ',');
- if (sep == NULL)
- sep = p + strlen(p);
- archive_strcat(&str, " bz2lib/");
- archive_strncat(&str, p, sep - p);
- }
- if (liblz4) {
- archive_strcat(&str, " liblz4/");
- archive_strcat(&str, liblz4);
- }
- }
- return str.s;
-}
-
-const char *
-archive_zlib_version(void)
-{
-#ifdef HAVE_ZLIB_H
- return ZLIB_VERSION;
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_liblzma_version(void)
-{
-#ifdef HAVE_LZMA_H
- return LZMA_VERSION_STRING;
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_bzlib_version(void)
-{
-#ifdef HAVE_BZLIB_H
- return BZ2_bzlibVersion();
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_liblz4_version(void)
-{
-#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
-#define str(s) #s
-#define NUMBER(x) str(x)
- return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
-#undef NUMBER
-#undef str
-#else
- return NULL;
-#endif
-}
-
int
archive_errno(struct archive *a)
{
@@ -275,7 +193,7 @@ archive_copy_error(struct archive *dest, struct archive *src)
void
__archive_errx(int retvalue, const char *msg)
{
- static const char *msg1 = "Fatal Internal Error in libarchive: ";
+ static const char msg1[] = "Fatal Internal Error in libarchive: ";
size_t s;
s = write(2, msg1, strlen(msg1));
@@ -303,8 +221,8 @@ __archive_errx(int retvalue, const char *msg)
int
__archive_mktemp(const char *tmpdir)
{
- static const wchar_t *prefix = L"libarchive_";
- static const wchar_t *suffix = L"XXXXXXXXXX";
+ static const wchar_t prefix[] = L"libarchive_";
+ static const wchar_t suffix[] = L"XXXXXXXXXX";
static const wchar_t num[] = {
L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
diff --git a/Utilities/cmlibarchive/libarchive/archive_version_details.c b/Utilities/cmlibarchive/libarchive/archive_version_details.c
new file mode 100644
index 0000000..9289bf1
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_version_details.c
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <cm_lzma.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+#ifdef HAVE_LZ4_H
+#include <lz4.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_string.h"
+
+const char *
+archive_version_details(void)
+{
+ static struct archive_string str;
+ static int init = 0;
+ const char *zlib = archive_zlib_version();
+ const char *liblzma = archive_liblzma_version();
+ const char *bzlib = archive_bzlib_version();
+ const char *liblz4 = archive_liblz4_version();
+
+ if (!init) {
+ archive_string_init(&str);
+
+ archive_strcat(&str, ARCHIVE_VERSION_STRING);
+ if (zlib != NULL) {
+ archive_strcat(&str, " zlib/");
+ archive_strcat(&str, zlib);
+ }
+ if (liblzma) {
+ archive_strcat(&str, " liblzma/");
+ archive_strcat(&str, liblzma);
+ }
+ if (bzlib) {
+ const char *p = bzlib;
+ const char *sep = strchr(p, ',');
+ if (sep == NULL)
+ sep = p + strlen(p);
+ archive_strcat(&str, " bz2lib/");
+ archive_strncat(&str, p, sep - p);
+ }
+ if (liblz4) {
+ archive_strcat(&str, " liblz4/");
+ archive_strcat(&str, liblz4);
+ }
+ }
+ return str.s;
+}
+
+const char *
+archive_zlib_version(void)
+{
+#ifdef HAVE_ZLIB_H
+ return ZLIB_VERSION;
+#else
+ return NULL;
+#endif
+}
+
+const char *
+archive_liblzma_version(void)
+{
+#ifdef HAVE_LZMA_H
+ return LZMA_VERSION_STRING;
+#else
+ return NULL;
+#endif
+}
+
+const char *
+archive_bzlib_version(void)
+{
+#ifdef HAVE_BZLIB_H
+ return BZ2_bzlibVersion();
+#else
+ return NULL;
+#endif
+}
+
+const char *
+archive_liblz4_version(void)
+{
+#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
+#define str(s) #s
+#define NUMBER(x) str(x)
+ return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
+#undef NUMBER
+#undef str
+#else
+ return NULL;
+#endif
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
index ad5dc83..08f518a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
@@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$");
#include "archive_private.h"
/* A table that maps filter codes to functions. */
-static
+static const
struct { int code; int (*setter)(struct archive *); } codes[] =
{
{ ARCHIVE_FILTER_NONE, archive_write_add_filter_none },
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
index eac4011..85a8d47 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
#include "archive_private.h"
/* A table that maps names to functions. */
-static
+static const
struct { const char *name; int (*setter)(struct archive *); } names[] =
{
{ "b64encode", archive_write_add_filter_b64encode },
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
index e655185..15fd494 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
@@ -225,7 +225,7 @@ archive_filter_lz4_open(struct archive_write_filter *f)
struct private_data *data = (struct private_data *)f->data;
int ret;
size_t required_size;
- static size_t bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024,
+ static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024,
4 * 1024 * 1024 };
size_t pre_block_size;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
index 55b5e8e..660f693 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
@@ -92,7 +92,7 @@ archive_write_add_filter_program(struct archive *_a, const char *cmd)
{
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;
- static const char *prefix = "Program: ";
+ static const char prefix[] = "Program: ";
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_add_filter_program");
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_data.3 b/Utilities/cmlibarchive/libarchive/archive_write_data.3
index 0cdd25f..9c16cd9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_data.3
@@ -24,11 +24,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd February 28, 2017
.Dt ARCHIVE_WRITE_DATA 3
.Os
.Sh NAME
-.Nm archive_write_data
+.Nm archive_write_data ,
+.Nm archive_write_data_block
.Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -36,8 +37,27 @@ Streaming Archive Library (libarchive, -larchive)
.In archive.h
.Ft la_ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
+.Ft la_ssize_t
+.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_data
+Write data corresponding to the header just written.
+.It Fn archive_write_data_block
Write data corresponding to the header just written.
+This is like
+.Fn archive_write_data
+except that it performs a seek on the file being
+written to the specified offset before writing the data.
+This is useful when restoring sparse files from archive
+formats that support sparse files.
+Returns number of bytes written or -1 on error.
+(Note: This is currently not supported for
+.Tn archive_write
+handles, only for
+.Tn archive_write_disk
+handles.
+.El
.\" .Sh EXAMPLE
.\"
.Sh RETURN VALUES
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk.3 b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
index ba6c970..949c9ef 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd April 3, 2017
.Dt ARCHIVE_WRITE_DISK 3
.Os
.Sh NAME
@@ -33,14 +33,7 @@
.Nm archive_write_disk_set_skip_file ,
.Nm archive_write_disk_set_group_lookup ,
.Nm archive_write_disk_set_standard_lookup ,
-.Nm archive_write_disk_set_user_lookup ,
-.Nm archive_write_header ,
-.Nm archive_write_data ,
-.Nm archive_write_data_block ,
-.Nm archive_write_finish_entry ,
-.Nm archive_write_close ,
-.Nm archive_write_finish
-.Nm archive_write_free
+.Nm archive_write_disk_set_user_lookup
.Nd functions for creating objects on disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -68,20 +61,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "uid_t (*)(void *, const char *uname, uid_t uid)"
.Fa "void (*cleanup)(void *)"
.Fc
-.Ft int
-.Fn archive_write_header "struct archive *" "struct archive_entry *"
-.Ft la_ssize_t
-.Fn archive_write_data "struct archive *" "const void *" "size_t"
-.Ft la_ssize_t
-.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
-.Ft int
-.Fn archive_write_finish_entry "struct archive *"
-.Ft int
-.Fn archive_write_close "struct archive *"
-.Ft int
-.Fn archive_write_finish "struct archive *"
-.Ft int
-.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating objects on
disk from
@@ -117,6 +96,33 @@ performance optimization in practice.
The options field consists of a bitwise OR of one or more of the
following values:
.Bl -tag -compact -width "indent"
+.It Cm ARCHIVE_EXTRACT_ACL
+Attempt to restore Access Control Lists.
+By default, extended ACLs are ignored.
+.It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS
+Before removing a file system object prior to replacing it, clear
+platform-specific file flags which might prevent its removal.
+.It Cm ARCHIVE_EXTRACT_FFLAGS
+Attempt to restore file attributes (file flags).
+By default, file attributes are ignored.
+See
+.Xr chattr 1
+.Pq Linux
+or
+.Xr chflags 1
+.Pq FreeBSD, Mac OS X
+for more information on file attributes.
+.It Cm ARCHIVE_EXTRACT_MAC_METADATA
+Mac OS X specific. Restore metadata using
+.Xr copyfile 3 .
+By default,
+.Xr copyfile 3
+metadata is ignored.
+.It Cm ARCHIVE_EXTRACT_NO_OVERWRITE
+Existing files on disk will not be overwritten.
+By default, existing regular files are truncated and overwritten;
+existing directories will have their permissions updated;
+other pre-existing objects are unlinked and recreated from scratch.
.It Cm ARCHIVE_EXTRACT_OWNER
The user and group IDs should be set on the restored file.
By default, the user and group IDs are not restored.
@@ -132,15 +138,37 @@ is not specified, then SUID and SGID bits will only be restored
if the default user and group IDs of newly-created objects on disk
happen to match those specified in the archive entry.
By default, only basic permissions are restored, and umask is obeyed.
+.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
+Refuse to extract an absolute path.
+The default is to not refuse such paths.
+.It Cm ARCHIVE_EXTRACT_SECURE_NODOTDOT
+Refuse to extract a path that contains a
+.Pa ..
+element anywhere within it.
+The default is to not refuse such paths.
+Note that paths ending in
+.Pa ..
+always cause an error, regardless of this flag.
+.It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS
+Refuse to extract any object whose final location would be altered
+by a symlink on disk.
+This is intended to help guard against a variety of mischief
+caused by archives that (deliberately or otherwise) extract
+files outside of the current directory.
+The default is not to perform this check.
+If
+.It Cm ARCHIVE_EXTRACT_SPARSE
+Scan data for blocks of NUL bytes and try to recreate them with holes.
+This results in sparse files, independent of whether the archive format
+supports or uses them.
+.Cm ARCHIVE_EXTRACT_UNLINK
+is specified together with this option, the library will
+remove any intermediate symlinks it finds and return an
+error only if such symlink could not be removed.
.It Cm ARCHIVE_EXTRACT_TIME
The timestamps (mtime, ctime, and atime) should be restored.
By default, they are ignored.
Note that restoring of atime is not currently supported.
-.It Cm ARCHIVE_EXTRACT_NO_OVERWRITE
-Existing files on disk will not be overwritten.
-By default, existing regular files are truncated and overwritten;
-existing directories will have their permissions updated;
-other pre-existing objects are unlinked and recreated from scratch.
.It Cm ARCHIVE_EXTRACT_UNLINK
Existing files on disk will be unlinked before any attempt to
create them.
@@ -148,45 +176,18 @@ In some cases, this can prove to be a significant performance improvement.
By default, existing files are truncated and rewritten, but
the file is not recreated.
In particular, the default behavior does not break existing hard links.
-.It Cm ARCHIVE_EXTRACT_ACL
-Attempt to restore ACLs.
-By default, extended ACLs are ignored.
-.It Cm ARCHIVE_EXTRACT_FFLAGS
-Attempt to restore extended file flags.
-By default, file flags are ignored.
.It Cm ARCHIVE_EXTRACT_XATTR
-Attempt to restore POSIX.1e extended attributes.
+Attempt to restore extended file attributes.
By default, they are ignored.
-.It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS
-Refuse to extract any object whose final location would be altered
-by a symlink on disk.
-This is intended to help guard against a variety of mischief
-caused by archives that (deliberately or otherwise) extract
-files outside of the current directory.
-The default is not to perform this check.
-If
-.Cm ARCHIVE_EXTRACT_UNLINK
-is specified together with this option, the library will
-remove any intermediate symlinks it finds and return an
-error only if such symlink could not be removed.
-.It Cm ARCHIVE_EXTRACT_SECURE_NODOTDOT
-Refuse to extract a path that contains a
-.Pa ..
-element anywhere within it.
-The default is to not refuse such paths.
-Note that paths ending in
-.Pa ..
-always cause an error, regardless of this flag.
-.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
-Refuse to extract an absolute path.
-The default is to not refuse such paths.
-.It Cm ARCHIVE_EXTRACT_SPARSE
-Scan data for blocks of NUL bytes and try to recreate them with holes.
-This results in sparse files, independent of whether the archive format
-supports or uses them.
-.It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS
-Before removing a file system object prior to replacing it, clear
-platform-specific file flags which might prevent its removal.
+See
+.Xr xattr 7
+.Pq Linux ,
+.Xr xattr 2
+.Pq Mac OS X ,
+or
+.Xr getextattr 8
+.Pq FreeBSD
+for more information on extended file attributes.
.El
.It Xo
.Fn archive_write_disk_set_group_lookup ,
@@ -223,60 +224,6 @@ the number of calls to
.Xr getpwnam 3
and
.Xr getgrnam 3 .
-.It Fn archive_write_header
-Build and write a header using the data in the provided
-.Tn struct archive_entry
-structure.
-See
-.Xr archive_entry 3
-for information on creating and populating
-.Tn struct archive_entry
-objects.
-.It Fn archive_write_data
-Write data corresponding to the header just written.
-Returns number of bytes written or -1 on error.
-.It Fn archive_write_data_block
-Write data corresponding to the header just written.
-This is like
-.Fn archive_write_data
-except that it performs a seek on the file being
-written to the specified offset before writing the data.
-This is useful when restoring sparse files from archive
-formats that support sparse files.
-Returns number of bytes written or -1 on error.
-(Note: This is currently not supported for
-.Tn archive_write
-handles, only for
-.Tn archive_write_disk
-handles.)
-.It Fn archive_write_finish_entry
-Close out the entry just written.
-Ordinarily, clients never need to call this, as it
-is called automatically by
-.Fn archive_write_next_header
-and
-.Fn archive_write_close
-as needed.
-However, some file attributes are written to disk only
-after the file is closed, so this can be necessary
-if you need to work with the file on disk right away.
-.It Fn archive_write_close
-Set any attributes that could not be set during the initial restore.
-For example, directory timestamps are not restored initially because
-restoring a subsequent file would alter that timestamp.
-Similarly, non-writable directories are initially created with
-write permissions (so that their contents can be restored).
-The
-.Nm
-library maintains a list of all such deferred attributes and
-sets them when this function is invoked.
-.It Fn archive_write_finish
-This is a deprecated synonym for
-.Fn archive_write_free .
-.It Fn archive_write_free
-Invokes
-.Fn archive_write_close
-if it was not invoked manually, then releases all resources.
.El
More information about the
.Va struct archive
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c
deleted file mode 100644
index 144ab7e..0000000
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c
+++ /dev/null
@@ -1,654 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 05:35:40Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_ACL_H
-#define _ACL_PRIVATE /* For debugging */
-#include <sys/acl.h>
-#endif
-#if HAVE_DARWIN_ACL
-#include <membership.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_acl_private.h"
-#include "archive_write_disk_private.h"
-
-#if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL
-/* Default empty function body to satisfy mainline code. */
-int
-archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl)
-{
- (void)a; /* UNUSED */
- (void)fd; /* UNUSED */
- (void)name; /* UNUSED */
- (void)abstract_acl; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
-
-#if HAVE_SUN_ACL
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
-#elif HAVE_DARWIN_ACL
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
-#elif HAVE_ACL_TYPE_NFS4
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
-#endif
-
-static int set_acl(struct archive *, int fd, const char *,
- struct archive_acl *,
- acl_type_t, int archive_entry_acl_type, const char *tn);
-
-int
-archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl)
-{
- int ret = ARCHIVE_OK;
-
-#if !HAVE_DARWIN_ACL
- if ((archive_acl_types(abstract_acl)
- & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
-#if HAVE_SUN_ACL
- /* Solaris writes POSIX.1e access and default ACLs together */
- ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
- ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
-#else /* HAVE_POSIX_ACL */
- if ((archive_acl_types(abstract_acl)
- & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- ret = set_acl(a, fd, name, abstract_acl,
- ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- "access");
- if (ret != ARCHIVE_OK)
- return (ret);
- }
- if ((archive_acl_types(abstract_acl)
- & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
- ret = set_acl(a, fd, name, abstract_acl,
- ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
- "default");
-#endif /* !HAVE_SUN_ACL */
- /* Simultaneous POSIX.1e and NFSv4 is not supported */
- return (ret);
- }
-#endif /* !HAVE_DARWIN_ACL */
-#if HAVE_NFS4_ACL
- if ((archive_acl_types(abstract_acl) &
- ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- ret = set_acl(a, fd, name, abstract_acl,
- ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
- ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
- }
-#endif /* HAVE_NFS4_ACL */
- return (ret);
-}
-
-/*
- * Translate system ACL permissions into libarchive internal structure
- */
-static const struct {
- const int archive_perm;
- const int platform_perm;
-} acl_perm_map[] = {
-#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
- {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
- {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
- {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
- {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
- {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
- {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
- {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
- {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
- {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
-#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
- {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
- {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
- {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
- {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
- {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
- {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
- {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
- {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
- {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
- {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
- {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
-#else /* POSIX.1e ACL permissions */
- {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
- {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
- {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
- {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
- {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
- {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
- {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
- {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
- {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
- {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
- {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
- {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
- {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
- {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
- {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
-#endif
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
-};
-
-#if HAVE_NFS4_ACL
-/*
- * Translate system NFSv4 inheritance flags into libarchive internal structure
- */
-static const struct {
- const int archive_inherit;
- const int platform_inherit;
-} acl_inherit_map[] = {
-#if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
- {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
- {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
- {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
-#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
- {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
-#else /* FreeBSD NFSv4 ACL inheritance flags */
- {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
- {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
- {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
- {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
-};
-#endif /* HAVE_NFS4_ACL */
-
-static int
-set_acl(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl,
- acl_type_t acl_type, int ae_requested_type, const char *tname)
-{
-#if HAVE_SUN_ACL
- aclent_t *aclent;
- ace_t *ace;
- int e, r;
- acl_t *acl;
-#else
- acl_t acl;
- acl_entry_t acl_entry;
- acl_permset_t acl_permset;
-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
- acl_flagset_t acl_flagset;
-#endif
-#endif /* HAVE_SUN_ACL */
-#if HAVE_ACL_TYPE_NFS4
- int r;
-#endif
- int ret;
- int ae_type, ae_permset, ae_tag, ae_id;
-#if HAVE_DARWIN_ACL
- uuid_t ae_uuid;
-#endif
- uid_t ae_uid;
- gid_t ae_gid;
- const char *ae_name;
- int entries;
- int i;
-
- ret = ARCHIVE_OK;
- entries = archive_acl_reset(abstract_acl, ae_requested_type);
- if (entries == 0)
- return (ARCHIVE_OK);
-
-#if HAVE_SUN_ACL
- acl = NULL;
- acl = malloc(sizeof(acl_t));
- if (acl == NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Invalid ACL type");
- return (ARCHIVE_FAILED);
- }
- if (acl_type == ACE_T)
- acl->acl_entry_size = sizeof(ace_t);
- else if (acl_type == ACLENT_T)
- acl->acl_entry_size = sizeof(aclent_t);
- else {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Invalid ACL type");
- acl_free(acl);
- return (ARCHIVE_FAILED);
- }
- acl->acl_type = acl_type;
- acl->acl_cnt = entries;
-
- acl->acl_aclp = malloc(entries * acl->acl_entry_size);
- if (acl->acl_aclp == NULL) {
- archive_set_error(a, errno,
- "Can't allocate memory for acl buffer");
- acl_free(acl);
- return (ARCHIVE_FAILED);
- }
-#else /* !HAVE_SUN_ACL */
- acl = acl_init(entries);
- if (acl == (acl_t)NULL) {
- archive_set_error(a, errno,
- "Failed to initialize ACL working storage");
- return (ARCHIVE_FAILED);
- }
-#endif /* !HAVE_SUN_ACL */
-#if HAVE_SUN_ACL
- e = 0;
-#endif
- while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
- &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
-#if HAVE_SUN_ACL
- ace = NULL;
- aclent = NULL;
- if (acl->acl_type == ACE_T) {
- ace = &((ace_t *)acl->acl_aclp)[e];
- ace->a_who = -1;
- ace->a_access_mask = 0;
- ace->a_flags = 0;
- } else {
- aclent = &((aclent_t *)acl->acl_aclp)[e];
- aclent->a_id = -1;
- aclent->a_type = 0;
- aclent->a_perm = 0;
- }
-#else /* !HAVE_SUN_ACL */
-#if HAVE_DARWIN_ACL
- /*
- * Mac OS doesn't support NFSv4 ACLs for
- * owner@, group@ and everyone@.
- * We skip any of these ACLs found.
- */
- if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
- ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
- ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
- continue;
-#endif
- if (acl_create_entry(&acl, &acl_entry) != 0) {
- archive_set_error(a, errno,
- "Failed to create a new ACL entry");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-#endif /* !HAVE_SUN_ACL */
-#if HAVE_DARWIN_ACL
- switch (ae_type) {
- case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
- acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DENY:
- acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
- break;
- default:
- /* We don't support any other types on MacOS */
- continue;
- }
-#endif
- switch (ae_tag) {
-#if HAVE_SUN_ACL
- case ARCHIVE_ENTRY_ACL_USER:
- ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
- if (acl->acl_type == ACE_T)
- ace->a_who = ae_uid;
- else {
- aclent->a_id = ae_uid;
- aclent->a_type |= USER;
- }
- break;
- case ARCHIVE_ENTRY_ACL_GROUP:
- ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
- if (acl->acl_type == ACE_T) {
- ace->a_who = ae_gid;
- ace->a_flags |= ACE_IDENTIFIER_GROUP;
- } else {
- aclent->a_id = ae_gid;
- aclent->a_type |= GROUP;
- }
- break;
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- if (acl->acl_type == ACE_T)
- ace->a_flags |= ACE_OWNER;
- else
- aclent->a_type |= USER_OBJ;
- break;
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- if (acl->acl_type == ACE_T) {
- ace->a_flags |= ACE_GROUP;
- ace->a_flags |= ACE_IDENTIFIER_GROUP;
- } else
- aclent->a_type |= GROUP_OBJ;
- break;
- case ARCHIVE_ENTRY_ACL_MASK:
- aclent->a_type |= CLASS_OBJ;
- break;
- case ARCHIVE_ENTRY_ACL_OTHER:
- aclent->a_type |= OTHER_OBJ;
- break;
- case ARCHIVE_ENTRY_ACL_EVERYONE:
- ace->a_flags |= ACE_EVERYONE;
- break;
-#else /* !HAVE_SUN_ACL */
- case ARCHIVE_ENTRY_ACL_USER:
- ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
-#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
- acl_set_tag_type(acl_entry, ACL_USER);
- acl_set_qualifier(acl_entry, &ae_uid);
-#else /* MacOS */
- if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
- sizeof(uid_t), ae_uuid) != 0)
- continue;
- if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
- continue;
-#endif /* HAVE_DARWIN_ACL */
- break;
- case ARCHIVE_ENTRY_ACL_GROUP:
- ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
-#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
- acl_set_tag_type(acl_entry, ACL_GROUP);
- acl_set_qualifier(acl_entry, &ae_gid);
-#else /* MacOS */
- if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
- sizeof(gid_t), ae_uuid) != 0)
- continue;
- if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
- continue;
-#endif /* HAVE_DARWIN_ACL */
- break;
-#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- acl_set_tag_type(acl_entry, ACL_USER_OBJ);
- break;
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
- break;
- case ARCHIVE_ENTRY_ACL_MASK:
- acl_set_tag_type(acl_entry, ACL_MASK);
- break;
- case ARCHIVE_ENTRY_ACL_OTHER:
- acl_set_tag_type(acl_entry, ACL_OTHER);
- break;
-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
- case ARCHIVE_ENTRY_ACL_EVERYONE:
- acl_set_tag_type(acl_entry, ACL_EVERYONE);
- break;
-#endif
-#endif /* !HAVE_DARWIN_ACL */
-#endif /* !HAVE_SUN_ACL */
- default:
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Unknown ACL tag");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-
-#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
- r = 0;
- switch (ae_type) {
-#if HAVE_SUN_ACL
- case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
- if (ace != NULL)
- ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
- else
- r = -1;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DENY:
- if (ace != NULL)
- ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
- else
- r = -1;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
- if (ace != NULL)
- ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
- else
- r = -1;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
- if (ace != NULL)
- ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
- else
- r = -1;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
- if (aclent == NULL)
- r = -1;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
- if (aclent != NULL)
- aclent->a_type |= ACL_DEFAULT;
- else
- r = -1;
- break;
-#else /* !HAVE_SUN_ACL */
- case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
- r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DENY:
- r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
- r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
- r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
- case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
- // These don't translate directly into the system ACL.
- break;
-#endif /* !HAVE_SUN_ACL */
- default:
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Unknown ACL entry type");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-
- if (r != 0) {
-#if HAVE_SUN_ACL
- errno = EINVAL;
-#endif
- archive_set_error(a, errno,
- "Failed to set ACL entry type");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
-
-#if HAVE_SUN_ACL
- if (acl->acl_type == ACLENT_T) {
- if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
- aclent->a_perm |= 1;
- if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
- aclent->a_perm |= 2;
- if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
- aclent->a_perm |= 4;
- } else
-#else
- if (acl_get_permset(acl_entry, &acl_permset) != 0) {
- archive_set_error(a, errno,
- "Failed to get ACL permission set");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
- if (acl_clear_perms(acl_permset) != 0) {
- archive_set_error(a, errno,
- "Failed to clear ACL permissions");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-#endif /* !HAVE_SUN_ACL */
- for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
- if (ae_permset & acl_perm_map[i].archive_perm) {
-#if HAVE_SUN_ACL
- ace->a_access_mask |=
- acl_perm_map[i].platform_perm;
-#else
- if (acl_add_perm(acl_permset,
- acl_perm_map[i].platform_perm) != 0) {
- archive_set_error(a, errno,
- "Failed to add ACL permission");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-#endif
- }
- }
-
-#if HAVE_NFS4_ACL
-#if HAVE_SUN_ACL
- if (acl_type == ACE_T)
-#elif HAVE_DARWIN_ACL
- if (acl_type == ACL_TYPE_EXTENDED)
-#else /* FreeBSD */
- if (acl_type == ACL_TYPE_NFS4)
-#endif
- {
-#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
- /*
- * acl_get_flagset_np() fails with non-NFSv4 ACLs
- */
- if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
- archive_set_error(a, errno,
- "Failed to get flagset from an NFSv4 ACL entry");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
- if (acl_clear_flags_np(acl_flagset) != 0) {
- archive_set_error(a, errno,
- "Failed to clear flags from an NFSv4 ACL flagset");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
- for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
- if (ae_permset & acl_inherit_map[i].archive_inherit) {
-#if HAVE_SUN_ACL
- ace->a_flags |=
- acl_inherit_map[i].platform_inherit;
-#else /* !HAVE_SUN_ACL */
- if (acl_add_flag_np(acl_flagset,
- acl_inherit_map[i].platform_inherit) != 0) {
- archive_set_error(a, errno,
- "Failed to add flag to NFSv4 ACL flagset");
- ret = ARCHIVE_FAILED;
- goto exit_free;
- }
-#endif /* HAVE_SUN_ACL */
- }
- }
- }
-#endif /* HAVE_NFS4_ACL */
-#if HAVE_SUN_ACL
- e++;
-#endif
- }
-
-#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
- /* Try restoring the ACL through 'fd' if we can. */
-#if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
- if (fd >= 0)
-#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
- if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
-#endif
- {
-#if HAVE_SUN_ACL
- if (facl_set(fd, acl) == 0)
-#elif HAVE_ACL_SET_FD_NP
- if (acl_set_fd_np(fd, acl, acl_type) == 0)
-#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
- if (acl_set_fd(fd, acl) == 0)
-#endif
- ret = ARCHIVE_OK;
- else {
- if (errno == EOPNOTSUPP) {
- /* Filesystem doesn't support ACLs */
- ret = ARCHIVE_OK;
- } else {
- archive_set_error(a, errno,
- "Failed to set %s acl on fd", tname);
- }
- }
- } else
-#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
-#if HAVE_SUN_ACL
- if (acl_set(name, acl) != 0)
-#elif HAVE_ACL_SET_LINK_NP
- if (acl_set_link_np(name, acl_type, acl) != 0)
-#else
- /* TODO: Skip this if 'name' is a symlink. */
- if (acl_set_file(name, acl_type, acl) != 0)
-#endif
- {
- if (errno == EOPNOTSUPP) {
- /* Filesystem doesn't support ACLs */
- ret = ARCHIVE_OK;
- } else {
- archive_set_error(a, errno, "Failed to set %s acl",
- tname);
- ret = ARCHIVE_WARN;
- }
- }
-exit_free:
- acl_free(acl);
- return (ret);
-}
-#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index a5f3067..4a42a3b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -39,9 +39,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
-#if defined(HAVE_SYS_XATTR_H)
+#if HAVE_SYS_XATTR_H
#include <sys/xattr.h>
-#elif defined(HAVE_ATTR_XATTR_H)
+#elif HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
#ifdef HAVE_SYS_EA_H
@@ -575,10 +575,55 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
if (a->flags & ARCHIVE_EXTRACT_TIME)
a->todo |= TODO_TIMES;
if (a->flags & ARCHIVE_EXTRACT_ACL) {
+#if ARCHIVE_ACL_DARWIN
+ /*
+ * On MacOS, platform ACLs get stored in mac_metadata, too.
+ * If we intend to extract mac_metadata and it is present
+ * we skip extracting libarchive NFSv4 ACLs.
+ */
+ size_t metadata_size;
+
+ if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 ||
+ archive_entry_mac_metadata(a->entry,
+ &metadata_size) == NULL || metadata_size == 0)
+#endif
+#if ARCHIVE_ACL_LIBRICHACL
+ /*
+ * RichACLs are stored in an extended attribute.
+ * If we intend to extract extended attributes and have this
+ * attribute we skip extracting libarchive NFSv4 ACLs.
+ */
+ short extract_acls = 1;
+ if (a->flags & ARCHIVE_EXTRACT_XATTR && (
+ archive_entry_acl_types(a->entry) &
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4)) {
+ const char *attr_name;
+ const void *attr_value;
+ size_t attr_size;
+ int i = archive_entry_xattr_reset(a->entry);
+ while (i--) {
+ archive_entry_xattr_next(a->entry, &attr_name,
+ &attr_value, &attr_size);
+ if (attr_name != NULL && attr_value != NULL &&
+ attr_size > 0 && strcmp(attr_name,
+ "trusted.richacl") == 0) {
+ extract_acls = 0;
+ break;
+ }
+ }
+ }
+ if (extract_acls)
+#endif
+#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
+ {
+#endif
if (archive_entry_filetype(a->entry) == AE_IFDIR)
a->deferred |= TODO_ACLS;
else
a->todo |= TODO_ACLS;
+#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
+ }
+#endif
}
if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
if (archive_entry_filetype(a->entry) == AE_IFDIR)
@@ -619,8 +664,21 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
}
#endif
- if (a->flags & ARCHIVE_EXTRACT_XATTR)
+ if (a->flags & ARCHIVE_EXTRACT_XATTR) {
+#if ARCHIVE_XATTR_DARWIN
+ /*
+ * On MacOS, extended attributes get stored in mac_metadata,
+ * too. If we intend to extract mac_metadata and it is present
+ * we skip extracting extended attributes.
+ */
+ size_t metadata_size;
+
+ if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 ||
+ archive_entry_mac_metadata(a->entry,
+ &metadata_size) == NULL || metadata_size == 0)
+#endif
a->todo |= TODO_XATTR;
+ }
if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
a->todo |= TODO_FFLAGS;
if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
@@ -1703,25 +1761,11 @@ _archive_write_disk_finish_entry(struct archive *_a)
*/
if (a->todo & TODO_ACLS) {
int r2;
-#ifdef HAVE_DARWIN_ACL
- /*
- * On Mac OS, platform ACLs are stored also in mac_metadata by
- * the operating system. If mac_metadata is present it takes
- * precedence and we skip extracting libarchive NFSv4 ACLs
- */
- const void *metadata;
- size_t metadata_size;
- metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
- if ((a->todo & TODO_MAC_METADATA) == 0 ||
- metadata == NULL || metadata_size == 0) {
-#endif
r2 = archive_write_disk_set_acls(&a->archive, a->fd,
archive_entry_pathname(a->entry),
- archive_entry_acl(a->entry));
+ archive_entry_acl(a->entry),
+ archive_entry_mode(a->entry));
if (r2 < ret) ret = r2;
-#ifdef HAVE_DARWIN_ACL
- }
-#endif
}
finish_metadata:
@@ -2293,13 +2337,8 @@ _archive_write_disk_close(struct archive *_a)
if (p->fixup & TODO_MODE_BASE)
chmod(p->name, p->mode);
if (p->fixup & TODO_ACLS)
-#ifdef HAVE_DARWIN_ACL
- if ((p->fixup & TODO_MAC_METADATA) == 0 ||
- p->mac_metadata == NULL ||
- p->mac_metadata_size == 0)
-#endif
- archive_write_disk_set_acls(&a->archive,
- -1, p->name, &p->acl);
+ archive_write_disk_set_acls(&a->archive, -1, p->name,
+ &p->acl, p->mode);
if (p->fixup & TODO_FFLAGS)
set_fflags_platform(a, -1, p->name,
p->mode, p->fflags_set, 0);
@@ -2467,7 +2506,7 @@ fsobj_error(int *a_eno, struct archive_string *a_estr,
if (a_eno)
*a_eno = err;
if (a_estr)
- archive_string_sprintf(a_estr, errstr, path);
+ archive_string_sprintf(a_estr, "%s%s", errstr, path);
}
/*
@@ -2573,7 +2612,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
* with the deep-directory editing.
*/
fsobj_error(a_eno, a_estr, errno,
- "Could not stat %s", path);
+ "Could not stat ", path);
res = ARCHIVE_FAILED;
break;
}
@@ -2582,7 +2621,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
if (chdir(head) != 0) {
tail[0] = c;
fsobj_error(a_eno, a_estr, errno,
- "Could not chdir %s", path);
+ "Could not chdir ", path);
res = (ARCHIVE_FATAL);
break;
}
@@ -2599,7 +2638,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
if (unlink(head)) {
tail[0] = c;
fsobj_error(a_eno, a_estr, errno,
- "Could not remove symlink %s",
+ "Could not remove symlink ",
path);
res = ARCHIVE_FAILED;
break;
@@ -2618,7 +2657,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
/*
if (!S_ISLNK(path)) {
fsobj_error(a_eno, a_estr, 0,
- "Removing symlink %s", path);
+ "Removing symlink ", path);
}
*/
/* Symlink gone. No more problem! */
@@ -2630,7 +2669,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
tail[0] = c;
fsobj_error(a_eno, a_estr, 0,
"Cannot remove intervening "
- "symlink %s", path);
+ "symlink ", path);
res = ARCHIVE_FAILED;
break;
}
@@ -2652,7 +2691,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
} else {
fsobj_error(a_eno, a_estr,
errno,
- "Could not stat %s", path);
+ "Could not stat ", path);
res = (ARCHIVE_FAILED);
break;
}
@@ -2661,7 +2700,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
tail[0] = c;
fsobj_error(a_eno, a_estr,
errno,
- "Could not chdir %s", path);
+ "Could not chdir ", path);
res = (ARCHIVE_FATAL);
break;
}
@@ -2674,14 +2713,14 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
tail[0] = c;
fsobj_error(a_eno, a_estr, 0,
"Cannot extract through "
- "symlink %s", path);
+ "symlink ", path);
res = ARCHIVE_FAILED;
break;
}
} else {
tail[0] = c;
fsobj_error(a_eno, a_estr, 0,
- "Cannot extract through symlink %s", path);
+ "Cannot extract through symlink ", path);
res = ARCHIVE_FAILED;
break;
}
@@ -4044,71 +4083,98 @@ skip_appledouble:
}
#endif
-#if HAVE_LSETXATTR || HAVE_LSETEA
+#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX
/*
- * Restore extended attributes - Linux and AIX implementations:
+ * Restore extended attributes - Linux, Darwin and AIX implementations:
* AIX' ea interface is syntaxwise identical to the Linux xattr interface.
*/
static int
set_xattrs(struct archive_write_disk *a)
{
struct archive_entry *entry = a->entry;
- static int warning_done = 0;
+ struct archive_string errlist;
int ret = ARCHIVE_OK;
int i = archive_entry_xattr_reset(entry);
+ short fail = 0;
+
+ archive_string_init(&errlist);
while (i--) {
const char *name;
const void *value;
size_t size;
+ int e;
+
archive_entry_xattr_next(entry, &name, &value, &size);
- if (name != NULL &&
- strncmp(name, "xfsroot.", 8) != 0 &&
- strncmp(name, "system.", 7) != 0) {
- int e;
-#if HAVE_FSETXATTR
- if (a->fd >= 0)
- e = fsetxattr(a->fd, name, value, size, 0);
- else
-#elif HAVE_FSETEA
- if (a->fd >= 0)
- e = fsetea(a->fd, name, value, size, 0);
- else
+
+ if (name == NULL)
+ continue;
+#if ARCHIVE_XATTR_LINUX
+ /* Linux: quietly skip POSIX.1e ACL extended attributes */
+ if (strncmp(name, "system.", 7) == 0 &&
+ (strcmp(name + 7, "posix_acl_access") == 0 ||
+ strcmp(name + 7, "posix_acl_default") == 0))
+ continue;
+ if (strncmp(name, "trusted.SGI_", 12) == 0 &&
+ (strcmp(name + 12, "ACL_DEFAULT") == 0 ||
+ strcmp(name + 12, "ACL_FILE") == 0))
+ continue;
+
+ /* Linux: xfsroot namespace is obsolete and unsupported */
+ if (strncmp(name, "xfsroot.", 8) == 0) {
+ fail = 1;
+ archive_strcat(&errlist, name);
+ archive_strappend_char(&errlist, ' ');
+ continue;
+ }
#endif
- {
-#if HAVE_LSETXATTR
- e = lsetxattr(archive_entry_pathname(entry),
- name, value, size, 0);
-#elif HAVE_LSETEA
- e = lsetea(archive_entry_pathname(entry),
- name, value, size, 0);
+
+ if (a->fd >= 0) {
+#if ARCHIVE_XATTR_LINUX
+ e = fsetxattr(a->fd, name, value, size, 0);
+#elif ARCHIVE_XATTR_DARWIN
+ e = fsetxattr(a->fd, name, value, size, 0, 0);
+#elif ARCHIVE_XATTR_AIX
+ e = fsetea(a->fd, name, value, size, 0);
#endif
- }
- if (e == -1) {
- if (errno == ENOTSUP || errno == ENOSYS) {
- if (!warning_done) {
- warning_done = 1;
- archive_set_error(&a->archive,
- errno,
- "Cannot restore extended "
- "attributes on this file "
- "system");
- }
- } else
- archive_set_error(&a->archive, errno,
- "Failed to set extended attribute");
- ret = ARCHIVE_WARN;
- }
} else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid extended attribute encountered");
+#if ARCHIVE_XATTR_LINUX
+ e = lsetxattr(archive_entry_pathname(entry),
+ name, value, size, 0);
+#elif ARCHIVE_XATTR_DARWIN
+ e = setxattr(archive_entry_pathname(entry),
+ name, value, size, 0, XATTR_NOFOLLOW);
+#elif ARCHIVE_XATTR_AIX
+ e = lsetea(archive_entry_pathname(entry),
+ name, value, size, 0);
+#endif
+ }
+ if (e == -1) {
ret = ARCHIVE_WARN;
+ archive_strcat(&errlist, name);
+ archive_strappend_char(&errlist, ' ');
+ if (errno != ENOTSUP && errno != ENOSYS)
+ fail = 1;
}
}
+
+ if (ret == ARCHIVE_WARN) {
+ if (fail && errlist.length > 0) {
+ errlist.length--;
+ errlist.s[errlist.length] = '\0';
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Cannot restore extended attributes: %s",
+ errlist.s);
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Cannot restore extended "
+ "attributes on this file system.");
+ }
+
+ archive_string_free(&errlist);
return (ret);
}
-#elif HAVE_EXTATTR_SET_FILE && HAVE_DECL_EXTATTR_NAMESPACE_USER
+#elif ARCHIVE_XATTR_FREEBSD
/*
* Restore extended attributes - FreeBSD implementation
*/
@@ -4116,9 +4182,12 @@ static int
set_xattrs(struct archive_write_disk *a)
{
struct archive_entry *entry = a->entry;
- static int warning_done = 0;
+ struct archive_string errlist;
int ret = ARCHIVE_OK;
int i = archive_entry_xattr_reset(entry);
+ short fail = 0;
+
+ archive_string_init(&errlist);
while (i--) {
const char *name;
@@ -4134,46 +4203,47 @@ set_xattrs(struct archive_write_disk *a)
name += 5;
namespace = EXTATTR_NAMESPACE_USER;
} else {
- /* Warn about other extended attributes. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't restore extended attribute ``%s''",
- name);
+ /* Other namespaces are unsupported */
+ archive_strcat(&errlist, name);
+ archive_strappend_char(&errlist, ' ');
+ fail = 1;
ret = ARCHIVE_WARN;
continue;
}
- errno = 0;
-#if HAVE_EXTATTR_SET_FD
- if (a->fd >= 0)
+
+ if (a->fd >= 0) {
e = extattr_set_fd(a->fd, namespace, name,
value, size);
- else
-#endif
- /* TODO: should we use extattr_set_link() instead? */
- {
- e = extattr_set_file(
+ } else {
+ e = extattr_set_link(
archive_entry_pathname(entry), namespace,
name, value, size);
}
if (e != (int)size) {
- if (errno == ENOTSUP || errno == ENOSYS) {
- if (!warning_done) {
- warning_done = 1;
- archive_set_error(&a->archive,
- errno,
- "Cannot restore extended "
- "attributes on this file "
- "system");
- }
- } else {
- archive_set_error(&a->archive, errno,
- "Failed to set extended attribute");
- }
-
+ archive_strcat(&errlist, name);
+ archive_strappend_char(&errlist, ' ');
ret = ARCHIVE_WARN;
+ if (errno != ENOTSUP && errno != ENOSYS)
+ fail = 1;
}
}
}
+
+ if (ret == ARCHIVE_WARN) {
+ if (fail && errlist.length > 0) {
+ errlist.length--;
+ errlist.s[errlist.length] = '\0';
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Cannot restore extended attributes: %s",
+ errlist.s);
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Cannot restore extended "
+ "attributes on this file system.");
+ }
+
+ archive_string_free(&errlist);
return (ret);
}
#else
@@ -4239,5 +4309,19 @@ older(struct stat *st, struct archive_entry *entry)
return (0);
}
+#ifndef ARCHIVE_ACL_SUPPORT
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode)
+{
+ (void)a; /* UNUSED */
+ (void)fd; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)abstract_acl; /* UNUSED */
+ (void)mode; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#endif
+
#endif /* !_WIN32 || __CYGWIN__ */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
index d84e7e1..b655dea 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
@@ -33,11 +33,13 @@
#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
+#include "archive_platform_acl.h"
#include "archive_acl_private.h"
+#include "archive_entry.h"
struct archive_write_disk;
-int
-archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /* pathname */, struct archive_acl *);
+int archive_write_disk_set_acls(struct archive *, int, const char *,
+ struct archive_acl *, __LA_MODE_T);
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3 b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
index c5ef69e..dc1b94b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd February 28, 2017
.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
.Os
.Sh NAME
@@ -45,6 +45,9 @@ is called automatically by
and
.Fn archive_write_close
as needed.
+For
+.Tn archive_write_disk
+handles, this flushes pending file attribute changes like modification time.
.\" .Sh EXAMPLE
.Sh RETURN VALUES
This function returns
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_format.3 b/Utilities/cmlibarchive/libarchive/archive_write_format.3
index d4ba6ab..aaafb0a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_format.3
@@ -108,7 +108,6 @@ Streaming Archive Library (libarchive, -larchive)
These functions set the format that will be used for the archive.
.Pp
The library can write a variety of common archive formats.
-
.Bl -tag -width indent
.It Fn archive_write_set_format
Sets the format based on the format code (see
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
index 744302d..0f70623 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
@@ -38,7 +38,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-1
#include "archive_private.h"
/* A table that maps format codes to functions. */
-static
+static const
struct { int code; int (*setter)(struct archive *); } codes[] =
{
{ ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip },
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
index a2ce7c6..86e8621 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 20116
#include "archive_private.h"
/* A table that maps names to functions. */
-static
+static const
struct { const char *name; int (*setter)(struct archive *); } names[] =
{
{ "7zip", archive_write_set_format_7zip },
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
index adec9b2..9fe21e4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 20116
#include "archive_private.h"
/* A table that maps names to functions. */
-static
+static const
struct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] =
{
{ ".7z", archive_write_set_format_7zip, archive_write_add_filter_none},
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
index 6a301ac..0eaf733 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -1196,8 +1196,12 @@ archive_write_pax_header(struct archive_write *a,
"GNU.sparse.major", 1);
add_pax_attr_int(&(pax->pax_header),
"GNU.sparse.minor", 0);
+ /*
+ * Make sure to store the original path, since
+ * truncation to ustar limit happened already.
+ */
add_pax_attr(&(pax->pax_header),
- "GNU.sparse.name", entry_name.s);
+ "GNU.sparse.name", path);
add_pax_attr_int(&(pax->pax_header),
"GNU.sparse.realsize",
archive_entry_size(entry_main));
@@ -1650,13 +1654,14 @@ build_pax_attribute_name(char *dest, const char *src)
* GNU PAX Format 1.0 requires the special name, which pattern is:
* <dir>/GNUSparseFile.<pid>/<original file name>
*
+ * Since reproducable archives are more important, use 0 as pid.
+ *
* This function is used for only Sparse file, a file type of which
* is regular file.
*/
static char *
build_gnu_sparse_name(char *dest, const char *src)
{
- char buff[64];
const char *p;
/* Handle the null filename case. */
@@ -1682,15 +1687,9 @@ build_gnu_sparse_name(char *dest, const char *src)
break;
}
-#if HAVE_GETPID && 0 /* Disable this as pax attribute name. */
- sprintf(buff, "GNUSparseFile.%d", getpid());
-#else
- /* If the platform can't fetch the pid, don't include it. */
- strcpy(buff, "GNUSparseFile");
-#endif
/* General case: build a ustar-compatible name adding
* "/GNUSparseFile/". */
- build_ustar_entry_name(dest, src, p - src, buff);
+ build_ustar_entry_name(dest, src, p - src, "GNUSparseFile.0");
return (dest);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
index 8b6daf9..edad072 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
@@ -354,7 +354,7 @@ static ssize_t
_popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr)
{
static const char _ver[] = "WARC/1.0\r\n";
- static const char *_typ[LAST_WT] = {
+ static const char * const _typ[LAST_WT] = {
NULL, "warcinfo", "metadata", "resource", NULL
};
char std_uuid[48U];
diff --git a/Utilities/cmlibarchive/libarchive/config_freebsd.h b/Utilities/cmlibarchive/libarchive/config_freebsd.h
index 215e886..be25258 100644
--- a/Utilities/cmlibarchive/libarchive/config_freebsd.h
+++ b/Utilities/cmlibarchive/libarchive/config_freebsd.h
@@ -22,141 +22,238 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: head/lib/libarchive/config_freebsd.h 201079 2009-12-28 02:01:42Z kientzle $
+ * $FreeBSD$
*/
-/* FreeBSD 5.0 and later have ACL and extattr support. */
+#include <osreldate.h>
+
+/* FreeBSD 5.0 and later has ACL and extattr support. */
#if __FreeBSD__ > 4
-#define HAVE_ACL_CREATE_ENTRY 1
-#define HAVE_ACL_GET_FD_NP 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_STRUCT_XVFSCONF 1
-#define HAVE_SYS_ACL_H 1
-#define HAVE_SYS_EXTATTR_H 1
-#endif
+#define ARCHIVE_ACL_FREEBSD 1
+#define HAVE_ACL_GET_PERM_NP 1
+#define HAVE_ARC4RANDOM_BUF 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_STRUCT_XVFSCONF 1
+#define HAVE_SYS_ACL_H 1
+#define HAVE_SYS_EXTATTR_H 1
+#if __FreeBSD__ > 7
+/* FreeBSD 8.0 and later has NFSv4 ACL support */
+#define ARCHIVE_ACL_FREEBSD_NFS4 1
+#define HAVE_ACL_GET_LINK_NP 1
+#define HAVE_ACL_IS_TRIVIAL_NP 1
+#define HAVE_ACL_SET_LINK_NP 1
+#endif /* __FreeBSD__ > 7 */
+#endif /* __FreeBSD__ > 4 */
#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
+#define HAVE_LIBCRYPTO 1
+#define HAVE_OPENSSL_EVP_H 1
+#define HAVE_OPENSSL_MD5_H 1
+#define HAVE_OPENSSL_RIPEMD_H 1
+#define HAVE_OPENSSL_SHA_H 1
+#define HAVE_OPENSSL_SHA256_INIT 1
+#define HAVE_OPENSSL_SHA384_INIT 1
+#define HAVE_OPENSSL_SHA512_INIT 1
+#define HAVE_PKCS5_PBKDF2_HMAC_SHA1 1
+#define HAVE_SHA256 1
+#define HAVE_SHA384 1
+#define HAVE_SHA512 1
+#else
+#define HAVE_LIBMD 1
+#define HAVE_MD5_H 1
+#define HAVE_MD5INIT 1
+#define HAVE_RIPEMD_H 1
+#define HAVE_SHA_H 1
+#define HAVE_SHA1 1
+#define HAVE_SHA1_INIT 1
+#define HAVE_SHA256 1
+#define HAVE_SHA256_H 1
+#define HAVE_SHA256_INIT 1
+#define HAVE_SHA512 1
+#define HAVE_SHA512_H 1
+#define HAVE_SHA512_INIT 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
+#define HAVE_BSDXML_H 1
+#define HAVE_BZLIB_H 1
+#define HAVE_CHFLAGS 1
+#define HAVE_CHOWN 1
+#define HAVE_CHROOT 1
+#define HAVE_CTIME_R 1
+#define HAVE_CTYPE_H 1
+#define HAVE_DECL_EXTATTR_NAMESPACE_USER 1
+#define HAVE_DECL_INT32_MAX 1
+#define HAVE_DECL_INT32_MIN 1
+#define HAVE_DECL_INT64_MAX 1
+#define HAVE_DECL_INT64_MIN 1
+#define HAVE_DECL_INTMAX_MAX 1
+#define HAVE_DECL_INTMAX_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_DECL_UINTMAX_MAX 1
+#define HAVE_DIRENT_H 1
+#define HAVE_DLFCN_H 1
+#define HAVE_D_MD_ORDER 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_FDOPENDIR 1
+#define HAVE_FORK 1
+#define HAVE_FSEEKO 1
+#define HAVE_FSTAT 1
+#define HAVE_FSTATAT 1
+#define HAVE_FSTATFS 1
+#define HAVE_FSTATVFS 1
+#define HAVE_FTRUNCATE 1
+#define HAVE_FUTIMES 1
+#define HAVE_FUTIMESAT 1
+#define HAVE_GETEUID 1
+#define HAVE_GETGRGID_R 1
+#define HAVE_GETGRNAM_R 1
+#define HAVE_GETPID 1
+#define HAVE_GETPWNAM_R 1
+#define HAVE_GETPWUID_R 1
+#define HAVE_GETVFSBYNAME 1
+#define HAVE_GMTIME_R 1
+#define HAVE_GRP_H 1
+#define HAVE_INTMAX_T 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_LANGINFO_H 1
+#define HAVE_LCHFLAGS 1
+#define HAVE_LCHMOD 1
+#define HAVE_LCHOWN 1
+#define HAVE_LIBZ 1
+#define HAVE_LIMITS_H 1
+#define HAVE_LINK 1
+#define HAVE_LOCALE_H 1
+#define HAVE_LOCALTIME_R 1
+#define HAVE_LONG_LONG_INT 1
+#define HAVE_LSTAT 1
+#define HAVE_LUTIMES 1
+#define HAVE_MBRTOWC 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MEMORY_H 1
+#define HAVE_MEMSET 1
+#define HAVE_MKDIR 1
+#define HAVE_MKFIFO 1
+#define HAVE_MKNOD 1
+#define HAVE_MKSTEMP 1
+#define HAVE_NL_LANGINFO 1
+#define HAVE_OPENAT 1
+#define HAVE_PATHS_H 1
+#define HAVE_PIPE 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
+#define HAVE_POSIX_SPAWNP 1
+#define HAVE_PTHREAD_H 1
+#define HAVE_PWD_H 1
+#define HAVE_READDIR_R 1
+#define HAVE_READLINK 1
+#define HAVE_READLINKAT 1
+#define HAVE_READPASSPHRASE 1
+#define HAVE_READPASSPHRASE_H 1
+#define HAVE_REGEX_H 1
+#define HAVE_SELECT 1
+#define HAVE_SETENV 1
+#define HAVE_SETLOCALE 1
+#define HAVE_SIGACTION 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_SPAWN_H 1
+#define HAVE_STATFS 1
+#define HAVE_STATVFS 1
+#define HAVE_STDARG_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_STRFTIME 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRRCHR 1
+#define HAVE_STRUCT_STATFS_F_NAMEMAX 1
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+#define HAVE_STRUCT_STAT_ST_FLAGS 1
+#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+#define HAVE_STRUCT_STAT_ST_MTIM_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_POLL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_STATVFS_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UTSNAME_H 1
+#define HAVE_SYS_WAIT_H 1
+#define HAVE_TIMEGM 1
+#define HAVE_TIME_H 1
+#define HAVE_TZSET 1
+#define HAVE_UINTMAX_T 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UNSETENV 1
+#define HAVE_UNSIGNED_LONG_LONG 1
+#define HAVE_UNSIGNED_LONG_LONG_INT 1
+#define HAVE_UTIME 1
+#define HAVE_UTIMES 1
+#define HAVE_UTIME_H 1
+#define HAVE_VFORK 1
+#define HAVE_VPRINTF 1
+#define HAVE_WCHAR_H 1
+#define HAVE_WCHAR_T 1
+#define HAVE_WCRTOMB 1
+#define HAVE_WCSCMP 1
+#define HAVE_WCSCPY 1
+#define HAVE_WCSLEN 1
+#define HAVE_WCTOMB 1
+#define HAVE_WCTYPE_H 1
+#define HAVE_WMEMCMP 1
+#define HAVE_WMEMCPY 1
+#define HAVE_WMEMMOVE 1
+#define HAVE_ZLIB_H 1
+#define TIME_WITH_SYS_TIME 1
+
+#if __FreeBSD_version >= 1100056
+#define HAVE_FUTIMENS 1
+#define HAVE_UTIMENSAT 1
+#endif
/* FreeBSD 4 and earlier lack intmax_t/uintmax_t */
#if __FreeBSD__ < 5
-#define intmax_t int64_t
-#define uintmax_t uint64_t
+#define intmax_t int64_t
+#define uintmax_t uint64_t
+#endif
+
+/* FreeBSD defines for archive_hash.h */
+#ifdef WITH_OPENSSL
+#define ARCHIVE_CRYPTO_MD5_OPENSSL 1
+#define ARCHIVE_CRYPTO_RMD160_OPENSSL 1
+#define ARCHIVE_CRYPTO_SHA1_OPENSSL
+#define ARCHIVE_CRYPTO_SHA256_OPENSSL 1
+#define ARCHIVE_CRYPTO_SHA384_OPENSSL 1
+#define ARCHIVE_CRYPTO_SHA512_OPENSSL 1
+#else
+#define ARCHIVE_CRYPTO_MD5_LIBMD 1
+#define ARCHIVE_CRYPTO_SHA1_LIBMD 1
+#define ARCHIVE_CRYPTO_SHA256_LIBMD 1
+#define ARCHIVE_CRYPTO_SHA512_LIBMD 1
#endif
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_changes.3 b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
index 881a67c..adc87fe 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_changes.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
@@ -28,6 +28,7 @@
.Dt LIBARCHIVE_CHANGES 3
.Os
.Sh NAME
+.Nm libarchive_changes
.Nd changes in libarchive interface
.\"
.Sh CHANGES IN LIBARCHIVE 3
diff --git a/Utilities/cmlibarchive/libarchive/mtree.5 b/Utilities/cmlibarchive/libarchive/mtree.5
index 16c8abe..e607e4a 100644
--- a/Utilities/cmlibarchive/libarchive/mtree.5
+++ b/Utilities/cmlibarchive/libarchive/mtree.5
@@ -48,7 +48,7 @@ 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
+encoded as 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
diff --git a/Utilities/cmlibarchive/libarchive/xxhash.c b/Utilities/cmlibarchive/libarchive/xxhash.c
index 6f5ba52..70750ba 100644
--- a/Utilities/cmlibarchive/libarchive/xxhash.c
+++ b/Utilities/cmlibarchive/libarchive/xxhash.c
@@ -141,13 +141,19 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
# pragma pack(pop)
#endif
-#define A32(x) (((const U32_S *)(x))->v)
-
/****************************************
** Compiler-specific Functions and Macros
*****************************************/
-#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#define GCC_VERSION ((__GNUC__-0) * 100 + (__GNUC_MINOR__ - 0))
+
+#if GCC_VERSION >= 409
+__attribute__((__no_sanitize_undefined__))
+#endif
+static inline U32 A32(const void * x)
+{
+ return (((const U32_S *)(x))->v);
+}
/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
#if defined(_MSC_VER)
diff --git a/bootstrap b/bootstrap
index 83e67c5..9d73233 100755
--- a/bootstrap
+++ b/bootstrap
@@ -129,6 +129,11 @@ fi
# Determine whether this is HP-UX
if echo "${cmake_system}" | grep -q HP-UX; then
+ die 'CMake no longer compiles on HP-UX. See
+
+ https://gitlab.kitware.com/cmake/cmake/issues/17137
+
+Use CMake 3.9 or lower instead.'
cmake_system_hpux=true
else
cmake_system_hpux=false
@@ -1140,60 +1145,6 @@ else
fi
rm -f "${TMPFILE}.cxx"
-if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then
- # Check for non-GNU compiler flags
-
- # If we are on HP-UX, check for -Ae for the C compiler.
- if [ "x${cmake_system}" = "xHP-UX" ]; then
- cmake_test_flags="-Ae"
- TMPFILE=`cmake_tmp_file`
- echo '
- int main(int argc, char** argv) { (void)argc; (void)argv; return 0; }
-' > ${TMPFILE}.c
- cmake_need_Ae=0
- if cmake_try_run "${cmake_c_compiler}" "${cmake_c_flags}" "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1; then
- :
- else
- if cmake_try_run "${cmake_c_compiler}" \
- "${cmake_c_flags} ${cmake_test_flags}" "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1; then
- cmake_need_Ae=1
- fi
- fi
- if [ "x${cmake_need_Ae}" = "x1" ]; then
- cmake_c_flags="${cmake_c_flags} ${cmake_test_flags}"
- echo "${cmake_c_compiler} needs ${cmake_test_flags}"
- else
- echo "${cmake_c_compiler} does not need ${cmake_test_flags}"
- fi
- rm -f "${TMPFILE}.c"
- echo '
- #include <iostream>
- int main(int argc, char** argv) {
- for(int i=0; i < 1; ++i);
- for(int i=0; i < 1; ++i);
- (void)argc; (void)argv; return 0; }
-' > ${TMPFILE}.cxx
- cmake_need_AAstd98=0
- cmake_test_flags="-AA +hpxstd98"
- if cmake_try_run "${cmake_cxx_compiler}" "${cmake_cxx_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
- :
- else
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} ${cmake_test_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
- cmake_need_AAstd98=1
- fi
- fi
- if [ "x${cmake_need_AAstd98}" = "x1" ]; then
- cmake_cxx_flags="${cmake_cxx_flags} ${cmake_test_flags}"
- echo "${cmake_cxx_compiler} needs ${cmake_test_flags}"
- else
- echo "${cmake_cxx_compiler} does not need ${cmake_test_flags}"
- fi
- fi
- cmake_test_flags=
-fi
-
-
# Test for kwsys features
KWSYS_NAME_IS_KWSYS=0
KWSYS_BUILD_SHARED=0