<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/3da9cd2a0deb1f5b0412ecf4ea2899183024c56b">https://github.com/macports/macports-base/commit/3da9cd2a0deb1f5b0412ecf4ea2899183024c56b</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 3da9cd2a0 Use clonefile(2) in more places
</span>3da9cd2a0 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 3da9cd2a0deb1f5b0412ecf4ea2899183024c56b
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Wed Aug 28 00:24:25 2024 +1000

<span style='display:block; white-space:pre;color:#404040;'>    Use clonefile(2) in more places
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    A lot of file copies that we create are not subsequently modified,
</span><span style='display:block; white-space:pre;color:#404040;'>    especially in the destroot phase. This makes cloning a more efficient
</span><span style='display:block; white-space:pre;color:#404040;'>    alternative.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    * Modified xinstall and 'file copy' Tcl commands to try cloning.
</span><span style='display:block; white-space:pre;color:#404040;'>    * Created a vendored copy of install(1) that tries cloning.
</span><span style='display:block; white-space:pre;color:#404040;'>    * Created a thin wrapper around cp(1) that adds the -c flag.
</span><span style='display:block; white-space:pre;color:#404040;'>    * If the build directory is on a filesystem that supports cloning, the
</span><span style='display:block; white-space:pre;color:#404040;'>      configure.install option defaults to our install(1), and the
</span><span style='display:block; white-space:pre;color:#404040;'>      directory containing our install and cp commands is added to the
</span><span style='display:block; white-space:pre;color:#404040;'>      front of PATH, currently only during the destroot phase.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    The code for all of the above is not built on systems that lack
</span><span style='display:block; white-space:pre;color:#404040;'>    clonefile(2). If cloning fails, everything will fall back to creating
</span><span style='display:block; white-space:pre;color:#404040;'>    a copy as previously done.
</span>---
 .gitignore                                |   3 +-
 Mk/macports.autoconf.mk.in                |   1 +
 configure                                 |  24 +-
 configure.ac                              |  16 +-
 src/macports1.0/macports.tcl              |  25 +-
 src/macports1.0/macports_autoconf.tcl.in  |   1 +
 src/pextlib1.0/xinstall.c                 |  83 ++-
 src/port1.0/portconfigure.tcl             |   2 +-
 src/port1.0/portdestroot.tcl              |  14 +-
 src/programs/{daemondo => cp}/Makefile.in |  24 +-
 src/programs/cp/cp.c                      |  26 +
 src/programs/daemondo/Makefile.in         |   2 +
 vendor/Makefile.in                        |  37 +-
 vendor/install/Makefile.in                |  38 ++
 vendor/install/tests/Kyuafile             |   3 +
 vendor/install/tests/install_test.sh      | 448 +++++++++++++++
 vendor/install/xinstall.c                 | 878 ++++++++++++++++++++++++++++++
 vendor/patches/install/xinstall.c.patch   | 129 +++++
 vendor/patches/tcl/clonefile.patch        | 112 ++++
 vendor/tcl8.6.14/unix/configure           |   4 +-
 vendor/tcl8.6.14/unix/tclUnixFCmd.c       |  59 +-
 21 files changed, 1883 insertions(+), 46 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/.gitignore b/.gitignore
</span><span style='display:block; white-space:pre;color:#808080;'>index bcc07c440..3c783ba87 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/.gitignore
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/.gitignore
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -32,7 +32,7 @@ src/darwintracelib1.0/sip_copy_proc.[ch]
</span> src/machista1.0/tests/libmachista-test
 src/port/*
 !src/port/*.tcl
<span style='display:block; white-space:pre;background:#ffe0e0;'>-src/programs/daemondo/build/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+src/programs/*/build/
</span> src/**/*.o
 src/**/*.a
 src/**/*.dylib
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -44,6 +44,7 @@ tests/test/trace/test.tcl
</span> 
 vendor/vendor-destroot/
 vendor/tclsh
<span style='display:block; white-space:pre;background:#e0ffe0;'>+vendor/install/build/
</span> vendor/**/*.o
 vendor/**/*.a
 vendor/**/*.dylib
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/Mk/macports.autoconf.mk.in b/Mk/macports.autoconf.mk.in
</span><span style='display:block; white-space:pre;color:#808080;'>index bbf3ef972..29cbeaa2b 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/Mk/macports.autoconf.mk.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/Mk/macports.autoconf.mk.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -37,6 +37,7 @@ XCODEBUILD                = @XCODEBUILD@
</span> INTREE_TCLSH              = @INTREE_TCLSH@
 TCLSH                  = @TCLSH@
 TCL_PACKAGE_PATH       = @TCL_PACKAGE_PATH@
<span style='display:block; white-space:pre;background:#e0ffe0;'>+TCL_PREFIX              = @TCL_PREFIX@
</span> 
 DSCL                   = @DSCL@
 DSEDITGROUP            = @DSEDITGROUP@
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/configure b/configure
</span><span style='display:block; white-space:pre;color:#808080;'>index 39ab3f4e3..550ac0e11 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/configure
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/configure
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -672,6 +672,7 @@ VENDOR_TCLX_SUBDIR
</span> VENDOR_DESTROOT
 VENDOR_TCL_INSTALL
 VENDOR_TCL_SUBDIR
<span style='display:block; white-space:pre;background:#e0ffe0;'>+CLONEBIN_PATH
</span> localstatedir_expanded
 MPCONFIGDIR_EXPANDED
 DARWINTRACE_SIP_WORKAROUND_PATH
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -689,6 +690,8 @@ HAVE_STRLCPY
</span> HAVE_STRLCAT
 HAVE_GETLINE
 HAVE_GETDELIM
<span style='display:block; white-space:pre;background:#e0ffe0;'>+EXTRA_PROGS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+HAVE_CLONEFILE
</span> HAVE_TIMINGSAFE_BCMP
 HAVE_GETENTROPY
 HAVE_ARC4RANDOM_BUF
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -704,7 +707,6 @@ RUNUSR
</span> DSTGRP
 DSTUSR
 MPCONFIGDIR
<span style='display:block; white-space:pre;background:#ffe0e0;'>-EXTRA_PROGS
</span> HAVE_FUNCTION_CFNOTIFICATIONCENTERGETDARWINNOTIFYCENTER
 HAVE_FRAMEWORK_IOKIT
 HAVE_FRAMEWORK_SYSTEMCONFIGURATION
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -7012,8 +7014,6 @@ printf %s "checking for whether we will build daemondo... " >&6; }
</span> printf "%s\n" "${result}" >&6; }
 
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> # Check for paths
 
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -7729,6 +7729,17 @@ HAVE_GETENTROPY=$ac_cv_func_getentropy
</span> HAVE_TIMINGSAFE_BCMP=$ac_cv_func_timingsafe_bcmp
 
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# For vendor/install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+HAVE_CLONEFILE=$ac_cv_func_clonefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# For programs/cp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if test x$ac_cv_func_clonefile = xyes; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+EXTRA_PROGS="$EXTRA_PROGS cp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ac_config_files="$ac_config_files src/programs/cp/Makefile vendor/install/Makefile"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> # Check for library functions, replacements are in pextlib1.0/compat/
 ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline"
 if test "x$ac_cv_func_getline" = xyes
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -8660,6 +8671,11 @@ eval "macports_libexec_dir=$macports_libexec_dir"
</span> prefix=$oldprefix
 exec_prefix=$oldexec_prefix
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+if test x$ac_cv_func_clonefile = xyes; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    CLONEBIN_PATH="${macports_libexec_dir}/clonebin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> ## Tcl package
        mp_fn_var_prepend() {
                eval "$1=\"$2\$$1\""
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -10448,6 +10464,8 @@ do
</span>   case $ac_config_target in
     "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
     "src/programs/daemondo/Makefile") CONFIG_FILES="$CONFIG_FILES src/programs/daemondo/Makefile" ;;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    "src/programs/cp/Makefile") CONFIG_FILES="$CONFIG_FILES src/programs/cp/Makefile" ;;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    "vendor/install/Makefile") CONFIG_FILES="$CONFIG_FILES vendor/install/Makefile" ;;
</span>     "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "Mk/macports.autoconf.mk") CONFIG_FILES="$CONFIG_FILES Mk/macports.autoconf.mk" ;;
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/configure.ac b/configure.ac
</span><span style='display:block; white-space:pre;color:#808080;'>index 6c64060bd..1d9691565 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/configure.ac
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/configure.ac
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -201,8 +201,6 @@ MP_COMPILER_ATTRIBUTE_UNUSED
</span> 
 MP_PROG_DAEMONDO
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-AC_SUBST(EXTRA_PROGS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> # Check for paths
 AC_PREFIX_DEFAULT(/opt/local)
 AC_ARG_WITH(
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -269,6 +267,15 @@ AC_SUBST(HAVE_ARC4RANDOM_BUF, $ac_cv_func_arc4random_buf)
</span> AC_SUBST(HAVE_GETENTROPY, $ac_cv_func_getentropy)
 AC_SUBST(HAVE_TIMINGSAFE_BCMP, $ac_cv_func_timingsafe_bcmp)
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# For vendor/install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+AC_SUBST(HAVE_CLONEFILE, $ac_cv_func_clonefile)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# For programs/cp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if test x$ac_cv_func_clonefile = xyes; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+EXTRA_PROGS="$EXTRA_PROGS cp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+AC_CONFIG_FILES([src/programs/cp/Makefile vendor/install/Makefile])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+AC_SUBST(EXTRA_PROGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> # Check for library functions, replacements are in pextlib1.0/compat/
 AC_CHECK_FUNCS([getline getdelim strlcat strlcpy])
 AC_SUBST(HAVE_GETDELIM, $ac_cv_func_getdelim)
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -347,6 +354,11 @@ eval "macports_libexec_dir=$macports_libexec_dir"
</span> prefix=$oldprefix
 exec_prefix=$oldexec_prefix
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+if test x$ac_cv_func_clonefile = xyes; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    CLONEBIN_PATH="${macports_libexec_dir}/clonebin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+AC_SUBST(CLONEBIN_PATH)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> ## Tcl package
 MP_CONFIG_SUBDIR([vendor/tcl/unix], [--prefix=${macports_libexec_dir} --enable-threads])
 VENDOR_TCL_SUBDIR=tcl/unix
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index e324c2ee0..5b9dd9d3f 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -49,7 +49,7 @@ package require mpcommon 1.0
</span> namespace eval macports {
     variable bootstrap_options [dict create]
     # Config file options with no special handling
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    foreach opt [list binpath auto_path extra_env portdbformat \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach opt [list binpath auto_path clonebin_path extra_env portdbformat \
</span>         portarchivetype portimage_mode hfscompression portautoclean \
         porttrace portverbose keeplogs destroot_umask release_urls release_version_urls \
         rsync_server rsync_options rsync_dir \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -87,6 +87,9 @@ namespace eval macports {
</span>         macosx_deployment_target packagemaker_path default_compilers sandbox_enable sandbox_network \
         delete_la_files cxx_stdlib pkg_post_unarchive_deletions {*}$user_options]
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Options set in the portfile interpreter but only in system_options
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    variable portinterp_private_options [list clonebin_path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     # deferred options are only computed when needed.
     # they are not exported to the trace thread.
     # they are not exported to the interpreter in system_options array.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -985,6 +988,7 @@ proc mportinit {{up_ui_options {}} {up_options {}} {up_variations {}}} {
</span>         macports::portarchive_hfscompression \
         macports::host_cache \
         macports::porturl_prefix_map \
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::clonebin_path \
</span>         macports::ui_options \
         macports::global_options \
         macports::global_variations
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1486,6 +1490,15 @@ match macports.conf.default."
</span>         set env(PATH) $binpath
     }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![info exists clonebin_path]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![catch {fs_clone_capable [file join $portdbpath build]} result] && $result
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            && [file executable ${macports::autoconf::clonebin_path}/install]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set clonebin_path ${macports::autoconf::clonebin_path}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set clonebin_path {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     # Set startupitem default type (can be overridden by portfile)
     if {![info exists startupitem_type]} {
         set startupitem_type default
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1896,6 +1909,7 @@ proc macports::copy_xcode_plist {target_homedir} {
</span> 
 proc macports::worker_init {workername portpath porturl portbuildpath options variations} {
     variable portinterp_options; variable portinterp_deferred_options
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    variable portinterp_private_options
</span>     variable ui_priorities; variable ui_options
 
     # Hide any Tcl commands that should be inaccessible to port1.0 and Portfiles
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2044,6 +2058,15 @@ proc macports::worker_init {workername portpath porturl portbuildpath options va
</span>         $workername eval [list set $opt ?]
     }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach opt $portinterp_private_options {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![info exists $opt]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            variable $opt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[info exists $opt]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            $workername eval [list set system_options($opt) [set $opt]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     foreach {opt val} $options {
         $workername eval [list set user_options($opt) $val]
         $workername eval [list set $opt $val]
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/macports_autoconf.tcl.in b/src/macports1.0/macports_autoconf.tcl.in
</span><span style='display:block; white-space:pre;color:#808080;'>index c2444bfdb..5cd3813c6 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/macports_autoconf.tcl.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/macports_autoconf.tcl.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -35,6 +35,7 @@ namespace eval macports::autoconf {
</span>     variable aa_path "@AA@"
     variable bzip2_path "@BZIP2_BIN@"
     variable chown_path "@CHOWN@"
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    variable clonebin_path "@CLONEBIN_PATH@"
</span>     variable gzip_path "@GZIP_BIN@"
     variable macports_conf_path "@MPCONFIGDIR_EXPANDED@"
     variable macports_keys_base "@prefix_expanded@/share/macports/keys/base"
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/xinstall.c b/src/pextlib1.0/xinstall.c
</span><span style='display:block; white-space:pre;color:#808080;'>index bc990178a..3cb59fe03 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/xinstall.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/xinstall.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -47,6 +47,14 @@
</span> #include <sys/cdefs.h>
 #endif
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* For clonefile */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_SYS_ATTR_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/attr.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_SYS_CLONEFILE_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/clonefile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #include <sys/param.h>
 #include <sys/mman.h>
 #include <sys/mount.h>
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -131,6 +139,9 @@ static char *funcname;
</span> static int safecopy, docompare, dostrip, dobackup, dopreserve, nommap;
 static mode_t mode;
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int clone(const char *, const char *, int, char *, size_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span> static int        copy(Tcl_Interp *interp, int, const char *, int, const char *, off_t);
 static int     compare(int, const char *, size_t, int, const char *, size_t);
 static int     create_newfile(Tcl_Interp *interp, const char *, int, struct stat *);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -139,6 +150,7 @@ static int   install(Tcl_Interp *interp, const char *, const char *, u_long, u_int
</span> static int        install_dir(Tcl_Interp *interp, char *);
 static u_long  numeric_id(Tcl_Interp *interp, const char *, const char *, int *rval);
 static void    strip(const char *);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+static void tempfile_template(const char *, char *, size_t);
</span> static int        trymmap(int);
 static void    usage(Tcl_Interp *interp);
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -432,9 +444,14 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
</span> {
        struct stat from_sb, temp_sb, to_sb;
        struct timeval tvb[2];
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        int devnull, files_match, from_fd = 0, serrno, target;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   int tempcopy, temp_fd, to_fd = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int devnull, files_match, from_fd = -1, serrno, target;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int tempcopy, temp_fd = -1, to_fd = -1;
</span>   char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   const int tryclone = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   const int tryclone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span> 
        files_match = 0;
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -484,7 +501,7 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
</span>   /* Only copy safe if the target exists. */
        tempcopy = safecopy && target;
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ((!tryclone || dostrip || docompare) && !devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) {
</span>           char errmsg[255];
 
                snprintf(errmsg, sizeof errmsg, "%s: Unable to open: %s, %s",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -517,6 +534,26 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
</span>   }
 
        if (!files_match) {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            int done_clone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       if (tryclone && !devnull && !dostrip) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       if (done_clone &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (((to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           || (!tempcopy && fstat(to_fd, &to_sb) == -1))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                (void)unlink(tempcopy ? tempfile : to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                done_clone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!done_clone && from_fd < 0 && (from_fd = open(from_name, O_RDONLY, 0)) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char errmsg[255];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            snprintf(errmsg, sizeof errmsg, "%s: Unable to open: %s, %s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 funcname, from_name, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            Tcl_SetResult(interp, errmsg, TCL_VOLATILE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (!done_clone) {
</span>           if (tempcopy) {
                        to_fd = create_tempfile(to_name, tempfile,
                            sizeof(tempfile));
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -539,8 +576,9 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
</span>                   }
                        ui_info(interp, "%s: %s -> %s", funcname, from_name, to_name);
                }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+                } /* !done_clone */
</span>           if (!devnull) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                        if (copy(interp, from_fd, from_name, to_fd,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (!done_clone && copy(interp, from_fd, from_name, to_fd,
</span>                        tempcopy ? tempfile : to_name, from_sb.st_size) != TCL_OK)
                                return TCL_ERROR;
 #if HAVE_COPYFILE
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -838,12 +876,11 @@ compare(int from_fd, const char *from_name UNUSED, size_t from_len,
</span>   return rv;
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * create_tempfile --
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * create a temporary file based on path and open it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* tempfile_template --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * prepare a template filename for use with mktemp/mkstemp.
</span>  */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-create_tempfile(const char *path, char *temp, size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+tempfile_template(const char *path, char *temp, size_t tsize)
</span> {
        char *p;
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -855,6 +892,16 @@ create_tempfile(const char *path, char *temp, size_t tsize)
</span>           p = temp;
        (void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
        temp[tsize - 1] = '\0';
<span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create_tempfile --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create a temporary file based on path and open it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+create_tempfile(const char *path, char *temp, size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   tempfile_template(path, temp, tsize);
</span>   return (mkstemp(temp));
 }
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -993,6 +1040,24 @@ copy(Tcl_Interp *interp, int from_fd, const char *from_name, int to_fd, const ch
</span>   return TCL_OK;
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * clone --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create a clone of a file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clone(const char *from_name, const char *to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      int use_temp, char *temp_name, size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (use_temp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        tempfile_template(to_name, temp_name, tsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        mktemp(temp_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        to_name = temp_name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /*
  * strip --
  *     use strip(1) to strip the target file
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port1.0/portconfigure.tcl b/src/port1.0/portconfigure.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index ecca5f81d..6a89c7b62 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port1.0/portconfigure.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port1.0/portconfigure.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -291,7 +291,7 @@ options configure.perl configure.python configure.ruby \
</span> default configure.perl              {}
 default configure.python            {}
 default configure.ruby              {}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-default configure.install           {${portutil::autoconf::install_command}}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default configure.install           {[expr {$system_options(clonebin_path) ne "" ? [file join $system_options(clonebin_path) install] : ${portutil::autoconf::install_command}}]}
</span> default configure.awk               {}
 default configure.bison             {}
 default configure.pkg_config        {}
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port1.0/portdestroot.tcl b/src/port1.0/portdestroot.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 0ebf48732..1b4e9bf81 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port1.0/portdestroot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port1.0/portdestroot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -126,7 +126,19 @@ proc portdestroot::destroot_start {args} {
</span> }
 
 proc portdestroot::destroot_main {args} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    command_exec -callback portprogress::target_progress_callback destroot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global system_options
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$system_options(clonebin_path) ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        global env
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set saved_path $env(PATH)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set env(PATH) $system_options(clonebin_path):$env(PATH)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        command_exec -callback portprogress::target_progress_callback destroot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } finally {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[info exists saved_path]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set env(PATH) $saved_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span>     return 0
 }
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/programs/daemondo/Makefile.in b/src/programs/cp/Makefile.in
</span>similarity index 52%
copy from src/programs/daemondo/Makefile.in
copy to src/programs/cp/Makefile.in
<span style='display:block; white-space:pre;color:#808080;'>index e22036871..ea1dc8665 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/programs/daemondo/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/programs/cp/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4,22 +4,15 @@ VPATH      = @srcdir@
</span> 
 include ../../../Mk/macports.autoconf.mk
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-datarootdir=    @datarootdir@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-mandir=            @mandir@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-mandircat8=        ${mandir}/cat8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+SRCS               = cp.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+OBJS               = cp.o
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PROGRAM            = build/cp
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-CFLAGS_PEDANTIC =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-CPPFLAGS   += -I../..
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-SRCS               = main.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-OBJS               = main.o
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-LIBS               = -framework CoreFoundation \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     -framework SystemConfiguration \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     -framework IOKit
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-PROGRAM            = build/daemondo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: cp mkdirs
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-all: daemondo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+all: cp
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-daemondo: mkdirs ${PROGRAM}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+cp: mkdirs ${PROGRAM}
</span> 
 ${PROGRAM}: ${OBJS}
        ${CC} ${CFLAGS} -o ${PROGRAM} ${LIBS} ${OBJS}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -33,8 +26,9 @@ clean:
</span> distclean: clean
        rm -f Makefile
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-install: daemondo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   ${INSTALL} -o "${DSTUSR}" -g "${DSTGRP}" -m 555 "${PROGRAM}" "${DESTDIR}${bindir}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+install: cp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ${INSTALL} -d -m 755 "${DESTDIR}${TCL_PREFIX}/clonebin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ${INSTALL} -o "${DSTUSR}" -g "${DSTGRP}" -m 555 "${PROGRAM}" "${DESTDIR}${TCL_PREFIX}/clonebin"
</span> 
 test:
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/programs/cp/cp.c b/src/programs/cp/cp.c
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..24c9703ef
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/programs/cp/cp.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,26 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* cp wrapper to add -c (clone) option */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+extern char **environ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int main(int argc, char *argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char *cp_path = "/bin/cp";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char *clone_arg = "-c";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char **new_argv = malloc(sizeof(char *) * (argc+1));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (new_argv) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        new_argv[0] = cp_path;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        new_argv[1] = clone_arg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        for (int i = 1; i < argc; i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            new_argv[i+1] = argv[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        execve(cp_path, new_argv, environ);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* something failed */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("cp");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/programs/daemondo/Makefile.in b/src/programs/daemondo/Makefile.in
</span><span style='display:block; white-space:pre;color:#808080;'>index e22036871..d5733c2a5 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/programs/daemondo/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/programs/daemondo/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -17,6 +17,8 @@ LIBS              = -framework CoreFoundation \
</span>                     -framework IOKit
 PROGRAM                = build/daemondo
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: daemondo mkdirs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> all: daemondo
 
 daemondo: mkdirs ${PROGRAM}
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/Makefile.in b/vendor/Makefile.in
</span><span style='display:block; white-space:pre;color:#808080;'>index 44371ddd9..14aed0cf2 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/vendor/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2,14 +2,15 @@ TCL_SUBDIR=                       @VENDOR_TCL_SUBDIR@
</span> TCLX_SUBDIR=              @VENDOR_TCLX_SUBDIR@
 TCLLIB_SUBDIR=         @VENDOR_TCLLIB_SUBDIR@
 SIGNIFY_SUBDIR=                signify-osx
<span style='display:block; white-space:pre;background:#e0ffe0;'>+INSTALL_SUBDIR=         install
</span> 
 PREFIX=                        @prefix@
 DESTROOT=              @abs_top_builddir@/vendor/vendor-destroot
 
 .PHONY: all clean distclean install destroot test
<span style='display:block; white-space:pre;background:#ffe0e0;'>-.PHONY: destroot-tcl destroot-tclx destroot-tcllib destroot-signify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-.PHONY: install-tcl install-tclx install-tcllib install-signify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-.PHONY: %-tcl %-tclx %-tcllib %-signify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: destroot-tcl destroot-tclx destroot-tcllib destroot-signify destroot-install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: install-tcl install-tclx install-tcllib install-signify install-install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: %-tcl %-tclx %-tcllib %-signify %-install
</span> 
 # for make all, run destroot (where destroot will depend on all of each
 # subpackage)
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -37,33 +38,47 @@ all-tcllib: all-tcl
</span>   @echo ===\> making $(@:%-signify=%) in ${DIRPRFX}${SIGNIFY_SUBDIR}
        @umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} $(@:%-signify=%)
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+%-install:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @echo ===\> making $(@:%-install=%) in ${DIRPRFX}${INSTALL_SUBDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C ${INSTALL_SUBDIR} $(@:%-install=%)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> DESTROOT_TARGETS=   destroot-tcl destroot-tclx destroot-tcllib
 ifneq (@OS_PLATFORM@,linux)
 DESTROOT_TARGETS+=   destroot-signify
 endif
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ifeq (@HAVE_CLONEFILE@,yes)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+DESTROOT_TARGETS+=   destroot-install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+endif
</span> 
 destroot: $(DESTROOT_TARGETS)
 destroot-tcl: all-tcl
        @echo ===\> staging to destroot in ${DIRPRFX}@VENDOR_TCL_SUBDIR@
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        @umask 0022; $(MAKE) -C @VENDOR_TCL_SUBDIR@ DESTDIR=${DESTROOT} @VENDOR_TCL_INSTALL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C @VENDOR_TCL_SUBDIR@ "DESTDIR=${DESTROOT}" @VENDOR_TCL_INSTALL@
</span> 
 destroot-tclx: all-tclx
        @echo ===\> staging to destroot in ${DIRPRFX}@VENDOR_TCLX_SUBDIR@
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        @umask 0022; $(MAKE) -C @VENDOR_TCLX_SUBDIR@ DESTDIR=${DESTROOT} @VENDOR_TCLX_INSTALL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C @VENDOR_TCLX_SUBDIR@ "DESTDIR=${DESTROOT}" @VENDOR_TCLX_INSTALL@
</span> 
 destroot-tcllib: all-tcllib
        @echo ===\> staging to destroot in ${DIRPRFX}@VENDOR_TCLLIB_SUBDIR@
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        @umask 0022; $(MAKE) -C @VENDOR_TCLLIB_SUBDIR@ DESTDIR=${DESTROOT} TCLSH_PROG=@INTREE_TCLSH@ @VENDOR_TCLLIB_INSTALL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C @VENDOR_TCLLIB_SUBDIR@ "DESTDIR=${DESTROOT}" TCLSH_PROG=@INTREE_TCLSH@ @VENDOR_TCLLIB_INSTALL@
</span>   @chmod -R ugo+rX ${DESTROOT}${PREFIX}/libexec/macports/lib/tcllib*
 
 destroot-signify:
        @echo ===\> staging to destroot in ${DIRPRFX}${SIGNIFY_SUBDIR}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        @umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} install PREFIX=${DESTROOT}${PREFIX}/libexec/macports
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} install "PREFIX=${DESTROOT}${PREFIX}/libexec/macports"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+destroot-install:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @echo ===\> staging to destroot in ${DIRPRFX}${INSTALL_SUBDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C ${INSTALL_SUBDIR} install "DESTDIR=${DESTROOT}"
</span> 
 INSTALL_TARGETS=    install-tcl install-tclx install-tcllib
 ifneq (@OS_PLATFORM@,linux)
 INSTALL_TARGETS+=   install-signify
 endif
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ifeq (@HAVE_CLONEFILE@,yes)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+INSTALL_TARGETS+=   install-install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+endif
</span> 
 install: $(INSTALL_TARGETS)
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -106,12 +121,16 @@ install-signify:
</span>   @echo ===\> making $(@:%-signify=%) in ${DIRPRFX}${SIGNIFY_SUBDIR}
        @umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} install PREFIX=$(DESTDIR)${PREFIX}/libexec/macports
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+install-install:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @echo ===\> making $(@:%-install=%) in ${DIRPRFX}${INSTALL_SUBDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   @umask 0022; $(MAKE) -C ${INSTALL_SUBDIR} install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> test:
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-clean: clean-tcl clean-tcllib clean-tclx clean-signify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clean: clean-tcl clean-tcllib clean-tclx clean-signify clean-install
</span>   rm -rf ${DESTROOT}
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-distclean: distclean-tcl distclean-tcllib distclean-tclx distclean-signify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+distclean: distclean-tcl distclean-tcllib distclean-tclx distclean-signify distclean-install
</span>   rm -f Makefile
        rm -rf vendor-destroot
        rm -f tclsh
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/install/Makefile.in b/vendor/install/Makefile.in
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..6b0e32046
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/install/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,38 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+srcdir     = @srcdir@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+VPATH      = @srcdir@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+include ../../Mk/macports.autoconf.mk
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+SRCS               = xinstall.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+OBJS               = xinstall.o
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PROGRAM            = build/install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: xinstall mkdirs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+all: xinstall
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+xinstall: mkdirs ${PROGRAM}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+${PROGRAM}: ${OBJS}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ${CC} ${CFLAGS} -o ${PROGRAM} ${LIBS} ${OBJS}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mkdirs:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   mkdir -p build
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clean:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   rm -Rf build ${PROGRAM} ${OBJS}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+distclean: clean
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   rm -f Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+install: xinstall
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ${INSTALL} -d -m 755 "${DESTDIR}${TCL_PREFIX}/clonebin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ${INSTALL} -m 555 "${PROGRAM}" "${DESTDIR}${TCL_PREFIX}/clonebin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test: xinstall
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if which -s kyua > /dev/null ; then \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           cd tests && env "PATH=../build:$$PATH" kyua test ; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+codesign:: ${PROGRAM}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ../../codesign.sh $?
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/install/tests/Kyuafile b/vendor/install/tests/Kyuafile
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..040b0e8a6
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/install/tests/Kyuafile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,3 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+syntax(2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test_suite('install')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_program{name='install_test.sh'}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/install/tests/install_test.sh b/vendor/install/tests/install_test.sh
</span>new file mode 100755
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..a98e34911
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/install/tests/install_test.sh
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,448 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#! /usr/bin/env atf-sh
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Copyright (c) 2016 Jilles Tjoelker
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# are met:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# $FreeBSD$
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install "$@" testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp testf copyf || atf_fail "bad copy"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt copyf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! -e copyf.bak ] || atf_fail "no backup expected"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_safe_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts -S
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_safe_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts -S -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent_backup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_backup_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts -b -B.bak
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent_backup_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_backup_safe_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts -b -B.bak -S
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_to_nonexistent_preserving
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_to_nonexistent_preserving_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_to_nonexistent_with_opts -p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -ot copyf ] || atf_fail "bad timestamp 2"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_self_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check -s not-exit:0 -o empty -e match:. install "$@" testf testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp testf testf2 || atf_fail "file changed after self-copy attempt"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_self
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_self_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_self_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_self_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_self_safe_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_self_with_opts -S
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_self_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_self_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_self_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case copy_self_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy_self_safe_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   copy_self_with_opts -S -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0w' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install "$@" testf otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp testf otherf || atf_fail "bad overwrite"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt otherf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_safe_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_with_opts -S
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_safe_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_with_opts -S -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_eq_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install "$@" testf otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp testf otherf || atf_fail "bad overwrite"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt otherf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_eq
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_eq_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_eq_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_eq_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_eq_safe_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_eq_with_opts -S
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_eq_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_eq_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_eq_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_eq_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_eq_safe_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_eq_with_opts -S -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_backup_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0w' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0w' >otherf2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -b -B.bak "$@" testf otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp testf otherf || atf_fail "bad overwrite"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt otherf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp otherf.bak otherf2 || atf_fail "bad backup"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_backup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_backup_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_backup_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_backup_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_backup_safe_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_backup_with_opts -S
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_backup_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_backup_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_backup_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case overwrite_backup_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+overwrite_backup_safe_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   overwrite_backup_with_opts -S -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+setup_stripbin() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cat <<\STRIPBIN >stripbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#!/bin/sh
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+[ "$1" = "-o" ] && dst="$2" && shift 2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+[ "$1" = "--" ] && shift
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+[ -z "$dst" ] && dst="$1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+STRIPBIN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ "$1" = "true" ] && cmd="cat" || cmd="tr z @"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   echo $cmd '<"$1" >"$1.new" && mv -- "$1.new" "$dst"' >>stripbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   chmod 755 stripbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   export STRIPBIN="$PWD/stripbin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+strip_changing_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   setup_stripbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -s "$@" testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt copyf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0@' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp otherf copyf || atf_fail "bad stripped copy"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_changing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_changing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  strip_changing_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_changing_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_changing_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  strip_changing_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+strip_changing_overwrite_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   setup_stripbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0w' >copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -s "$@" testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt copyf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0@' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp otherf copyf || atf_fail "bad stripped copy"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_changing_overwrite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_changing_overwrite_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  strip_changing_overwrite_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_changing_overwrite_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_changing_overwrite_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  strip_changing_overwrite_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+strip_changing_overwrite_eq_with_opts() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   setup_stripbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0@' >copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -s "$@" testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ ! testf -nt copyf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   printf 'test\n123\r456\r\n789\0@' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmp otherf copyf || atf_fail "bad stripped copy"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_changing_overwrite_eq
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_changing_overwrite_eq_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  strip_changing_overwrite_eq_with_opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_changing_overwrite_eq_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_changing_overwrite_eq_comparing_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  strip_changing_overwrite_eq_with_opts -C
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case strip_noop
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# strip_noop_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  setup_stripbin true
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -s testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ ! testf -nt copyf ] || atf_fail "bad timestamp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  printf 'test\n123\r456\r\n789\0z' >otherf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  cmp otherf copyf || atf_fail "bad stripped copy"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#atf_test_case hard_link
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#hard_link_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l h testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ testf -ef copyf ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ ! -L copyf ] || atf_fail "copy is symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#atf_test_case symbolic_link
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#symbolic_link_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l s testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ testf -ef copyf ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ -L copyf ] || atf_fail "copy is not symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#atf_test_case symbolic_link_absolute
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#symbolic_link_absolute_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l sa testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ testf -ef copyf ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ -L copyf ] || atf_fail "copy is not symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  copyf_path=$(readlink copyf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  testf_path="$(pwd -P)/testf"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  if [ "$copyf_path" != "$testf_path" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          atf_fail "unexpected symlink contents ('$copyf_path' != '$testf_path')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#atf_test_case symbolic_link_relative
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#symbolic_link_relative_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  printf 'test\n123\r456\r\n789\0z' >testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l sr testf copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ testf -ef copyf ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ -L copyf ] || atf_fail "copy is not symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  copyf_path=$(readlink copyf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  testf_path="testf"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  if [ "$copyf_path" != "$testf_path" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          atf_fail "unexpected symlink contents ('$copyf_path' != '$testf_path')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case symbolic_link_relative_absolute_source_and_dest1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_source_and_dest1_head() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_set "descr" "Verify -l rs with absolute paths (.../copyf -> .../a/b/c/testf)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_source_and_dest1_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path=a/b/c/testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_prefixed=$PWD/$src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path=$PWD/copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check mkdir -p a/b/c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check touch $src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l sr $src_path_prefixed $dest_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ -L $dest_path ] || atf_fail "copy is not symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path_relative=$(readlink $dest_path)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_relative="$src_path"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  if [ "$src_path_relative" != "$dest_path_relative" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case symbolic_link_relative_absolute_source_and_dest1_double_slash
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_source_and_dest1_double_slash_head() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_set "descr" "Verify -l rs with absolute paths (.../copyf -> .../a/b/c/testf), using double-slashes"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_source_and_dest1_double_slash_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path=a//b//c//testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_prefixed=$PWD/$src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path=$PWD/copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check mkdir -p a/b/c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check touch $src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l sr $src_path_prefixed $dest_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ -L $dest_path ] || atf_fail "copy is not symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path_relative=$(readlink $dest_path)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_relative="$(echo $src_path | sed -e 's,//,/,g')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  if [ "$src_path_relative" != "$dest_path_relative" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case symbolic_link_relative_absolute_source_and_dest2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_source_and_dest2_head() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_set "descr" "Verify -l rs with absolute paths (.../a/b/c/copyf -> .../testf)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_source_and_dest2_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path=testf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_prefixed=$PWD/$src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path=$PWD/a/b/c/copyf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check mkdir -p a/b/c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check touch $src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l sr $src_path_prefixed $dest_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  [ -L $dest_path ] || atf_fail "copy is not symlink"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path_relative=$(readlink $dest_path)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_relative="../../../$src_path"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  if [ "$src_path_relative" != "$dest_path_relative" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_test_case mkdir_simple
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mkdir_simple_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -d dir1/dir2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ -d dir1 ] || atf_fail "dir1 missing"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ -d dir1/dir2 ] || atf_fail "dir2 missing"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -d dir1/dir2/dir3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   [ -d dir1/dir2/dir3 ] || atf_fail "dir3 missing"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -d dir1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_check install -d dir1/dir2/dir3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# atf_test_case symbolic_link_relative_absolute_common
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_common_head() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_set "descr" "Verify -l rs with absolute paths having common components"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# symbolic_link_relative_absolute_common_body() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  filename=foo.so
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path=lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_prefixed=$PWD/$src_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path=$PWD/libexec/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_file=$src_path_prefixed/$filename
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_file=$dest_path/$filename
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check mkdir $src_path_prefixed $dest_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check touch $src_file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  atf_check install -l sr $src_file $dest_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  dest_path_relative=$(readlink $dest_file)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  src_path_relative="../lib/$filename"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  if [ "$src_path_relative" != "$dest_path_relative" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+atf_init_test_cases() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent_backup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent_backup_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_to_nonexistent_preserving
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_self
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_self_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_self_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case copy_self_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_eq
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_eq_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_eq_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_eq_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_backup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_backup_safe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_backup_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case overwrite_backup_safe_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_changing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_changing_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_changing_overwrite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_changing_overwrite_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_changing_overwrite_eq
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_changing_overwrite_eq_comparing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case strip_noop
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case hard_link
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link_absolute
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link_relative
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link_relative_absolute_source_and_dest1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link_relative_absolute_source_and_dest1_double_slash
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link_relative_absolute_source_and_dest2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   #atf_add_test_case symbolic_link_relative_absolute_common
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   atf_add_test_case mkdir_simple
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/install/xinstall.c b/vendor/install/xinstall.c
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..6f543f17f
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/install/xinstall.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,878 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 1987, 1993
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The Regents of the University of California.  All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * are met:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 3. All advertising materials mentioning features or use of this software
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    must display the following acknowledgement:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This product includes software developed by the University of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * California, Berkeley and its contributors.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 4. Neither the name of the University nor the names of its contributors
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    may be used to endorse or promote products derived from this software
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    without specific prior written permission.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/cdefs.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef lint
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+__used static const char copyright[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+"@(#) Copyright (c) 1987, 1993\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   The Regents of the University of California.  All rights reserved.\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* not lint */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef lint
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static char sccsid[] = "From: @(#)xinstall.c  8.1 (Berkeley) 7/21/93";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+__used static const char rcsid[] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  "$FreeBSD: src/usr.bin/xinstall/xinstall.c,v 1.43 2001/05/30 07:08:49 ru Exp $";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* not lint */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/param.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/wait.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/mman.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/stat.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/mount.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <ctype.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <err.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <fcntl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <grp.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <paths.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <pwd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sysexits.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <utime.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <spawn.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <TargetConditionals.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <copyfile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/attr.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/clonefile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif     /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Bootstrap aid - this doesn't exist in most older releases */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef MAP_FAILED
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MAP_FAILED ((void *)-1)    /* from <sys/mman.h> */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define    DIRECTORY       0x01            /* Tell install it's a directory. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define    SETFLAGS        0x02            /* Tell install to set flags. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define    NOCHANGEBITS    (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define    BACKUP_SUFFIX   ".old"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+struct passwd *pp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+struct group *gp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+gid_t gid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+uid_t uid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy, verbose;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+char *suffix = BACKUP_SUFFIX;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int clone __P((const char *, const char *, int, char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void       copy __P((int, char *, int, char *, off_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int        compare __P((int, const char *, size_t, int, const char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int        create_newfile __P((char *, int, struct stat *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int        create_tempfile __P((char *, char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void       install __P((char *, char *, u_long, u_int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void       install_dir __P((char *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+u_long     numeric_id __P((char *, char *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void       strip __P((char *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void tempfile_template __P((const char *, char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int        trymmap __P((int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void       usage __P((void));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+main(int argc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char *argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct stat from_sb, to_sb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   mode_t *set;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   u_long fset = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int ch, no_target;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   u_int iflags;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char *flags, *group, *owner, *to_name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   iflags = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   group = owner = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:o:pSsv")) != -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           switch((char)ch) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'B':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   suffix = optarg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   /* FALLTHROUGH */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'b':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   dobackup = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'C':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   docompare = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'c':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   /* For backwards compatibility. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'd':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   dodir = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'f':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   flags = optarg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (strtofflags(&flags, &fset, NULL))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errx(EX_USAGE, "%s: invalid flag", flags);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   iflags |= SETFLAGS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'g':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   group = optarg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'M':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   nommap = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'm':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (!(set = setmode(optarg)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errx(EX_USAGE, "invalid file mode: %s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                optarg);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   mode = getmode(set, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   free(set);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'o':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   owner = optarg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'p':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   docompare = dopreserve = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'S':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   safecopy = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 's':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   dostrip = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 'v':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   verbose = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case '?':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   usage();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   argc -= optind;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   argv += optind;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* some options make no sense when creating directories */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ((safecopy || dostrip) && dodir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           usage();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Older versions allowed -d -C combo.  Issue a warning
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * for now, but turn this into an error before 4.5-RELEASE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (docompare && dodir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           warnx("the -d and -C options may not be specified together");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* must have at least two arguments, except when creating directories */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (argc < 2 && !dodir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           usage();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* need to make a temp copy so we can compare stripped version */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (docompare && dostrip)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           safecopy = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* get group and owner id's */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (group != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((gp = getgrnam(group)) != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   gid = gp->gr_gid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   gid = (uid_t)numeric_id(group, "group");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           gid = (gid_t)-1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (owner != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((pp = getpwnam(owner)) != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   uid = pp->pw_uid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   uid = (uid_t)numeric_id(owner, "user");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           uid = (uid_t)-1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (dodir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           for (; *argv != NULL; ++argv)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   install_dir(*argv);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           exit(EX_OK);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* NOTREACHED */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   no_target = stat(to_name = argv[argc - 1], &to_sb);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!no_target && S_ISDIR(to_sb.st_mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           for (; *argv != to_name; ++argv)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   install(*argv, to_name, fset, iflags | DIRECTORY);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           exit(EX_OK);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* NOTREACHED */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* can't do file1 file2 directory/file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (argc != 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           usage();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!no_target) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (stat(*argv, &from_sb))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", *argv);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!S_ISREG(to_sb.st_mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = EFTYPE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (to_sb.st_dev == from_sb.st_dev &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               to_sb.st_ino == from_sb.st_ino)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errx(EX_USAGE, 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       "%s and %s are the same file", *argv, to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   install(*argv, to_name, fset, iflags);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   exit(EX_OK);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* NOTREACHED */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+u_long
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+numeric_id(char *name, char *type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   u_long val;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char *ep;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * XXX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * We know that uid_t's and gid_t's are unsigned longs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   errno = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   val = strtoul(name, &ep, 10);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (errno)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           err(EX_NOUSER, "%s", name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (*ep != '\0')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           errx(EX_NOUSER, "unknown %s %s", type, name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return (val);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * install --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * build a path name and install the file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+install(char *from_name, char *to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   u_long fset,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   u_int flags)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct stat from_sb, temp_sb, to_sb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct utimbuf utb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int devnull, files_match, from_fd=-1, serrno, target;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int tempcopy, temp_fd=-1, to_fd=-1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   const int tryclone = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   files_match = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* If try to install NULL file to a directory, fails. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (stat(from_name, &from_sb))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!S_ISREG(from_sb.st_mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = EFTYPE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* Build the target path. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (flags & DIRECTORY) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       (p = strrchr(from_name, '/')) ? ++p : from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   to_name = pathbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           devnull = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           devnull = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   target = stat(to_name, &to_sb) == 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* Only install to regular files. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (target && !S_ISREG(to_sb.st_mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           errno = EFTYPE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           warn("%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* Only copy safe if the target exists. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   tempcopy = safecopy && target;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           err(EX_OSERR, "%s", from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* If we don't strip, we can compare first. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (docompare && !dostrip && target) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (devnull)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   files_match = to_sb.st_size == 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   files_match = !(compare(from_fd, from_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       (size_t)from_sb.st_size, to_fd,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       to_name, (size_t)to_sb.st_size));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* Close "to" file unless we match. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!files_match)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)close(to_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!files_match) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           int done_clone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       if (tryclone && !devnull && !dostrip) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       if (done_clone &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (((to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           || (!tempcopy && fstat(to_fd, &to_sb) == -1))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                (void)unlink(tempcopy ? tempfile : to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                done_clone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!done_clone) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (tempcopy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   to_fd = create_tempfile(to_name, tempfile,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       sizeof(tempfile));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (to_fd < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(EX_OSERR, "%s", tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if ((to_fd = create_newfile(to_name, target,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       &to_sb)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)printf("install: %s -> %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                               from_name, to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!devnull)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   copy(from_fd, from_name, to_fd,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        tempcopy ? tempfile : to_name, from_sb.st_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           } /* !done_clone */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (dostrip) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           strip(tempcopy ? tempfile : to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            * Re-open our fd on the target, in case we used a strip
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            * that does not work in-place -- like GNU binutils strip.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           close(to_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (to_fd < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "stripping %s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Compare the stripped temp file with the target.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (docompare && dostrip && target) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           temp_fd = to_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* Re-open to_fd using the real target name. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (fstat(temp_fd, &temp_sb)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)unlink(tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (compare(temp_fd, tempfile, (size_t)temp_sb.st_size, to_fd,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       to_name, (size_t)to_sb.st_size) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    * If target has more than one link we need to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    * replace it in order to snap the extra links.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    * Need to preserve target file times, though.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (to_sb.st_nlink != 1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           utb.actime = to_sb.st_atime;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           utb.modtime = to_sb.st_mtime;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)utime(tempfile, &utb);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           files_match = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)unlink(tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void) close(temp_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Move the new file into place if doing a safe copy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * and the files are different (or just not compared).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (tempcopy && !files_match) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* Try to turn off the immutable bits. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (to_sb.st_flags & NOCHANGEBITS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (dobackup) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (snprintf(backup, MAXPATHLEN, "%s%s", to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       suffix) != strlen(to_name) + strlen(suffix)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           unlink(tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errx(EX_OSERR, "%s: backup filename too long",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                               to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)printf("install: %s -> %s\n", to_name, backup);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (rename(to_name, backup) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           unlink(tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(EX_OSERR, "rename: %s to %s", to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                backup);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)printf("install: %s -> %s\n", from_name, to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (rename(tempfile, to_name) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   unlink(tempfile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "rename: %s to %s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       tempfile, to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* Re-open to_fd so we aren't hosed by the rename(2). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (void) close(to_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* in case mtime is modified */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!devnull && (S_ISLNK(from_sb.st_mode) || S_ISREG(from_sb.st_mode)) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       fcopyfile(from_fd, to_fd, NULL, COPYFILE_XATTR) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           warn("%s: unable to copy extended attributes from %s", to_name, from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif     /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Preserve the timestamp of the source file if necessary.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (dopreserve && !files_match && !devnull) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           utb.actime = from_sb.st_atime;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           utb.modtime = from_sb.st_mtime;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (void)utime(to_name, &utb);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (fstat(to_fd, &to_sb) == -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Set owner, group, mode for target; do the chown first,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * chown may lose the setuid bits.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ((gid != (gid_t)-1 && gid != to_sb.st_gid) ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       (uid != (uid_t)-1 && uid != to_sb.st_uid) ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       (mode != to_sb.st_mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /* Try to turn off the immutable bits. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (to_sb.st_flags & NOCHANGEBITS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ((gid != (gid_t)-1 && gid != to_sb.st_gid) ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       (uid != (uid_t)-1 && uid != to_sb.st_uid))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (fchown(to_fd, uid, gid) == -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR,"%s: chown/chgrp", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (mode != to_sb.st_mode)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (fchmod(to_fd, mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s: chmod", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * If provided a set of flags, set them, otherwise, preserve the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * flags, except for the dump flag.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * NFS does not support flags.  Ignore ENOTSUP flags if we're just
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * trying to turn off UF_NODUMP.  If we're trying to set real flags,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * then warn if the the fs doesn't support it, otherwise fail.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!devnull && fchflags(to_fd,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (flags & SETFLAGS) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (errno == ENOTSUP)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           warn("%s: chflags", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(EX_OSERR, "%s: chflags", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* the ACL could prevent credential/permission system calls later on... */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!devnull && (S_ISLNK(from_sb.st_mode) || S_ISREG(from_sb.st_mode)) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       (fcopyfile(from_fd, to_fd, NULL, COPYFILE_ACL) < 0)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           warn("%s: unable to copy ACL from %s", to_name, from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif     /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   (void)close(to_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!devnull)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (void)close(from_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * compare --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * compare two files; non-zero means files differ
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compare(int from_fd, const char *from_name, size_t from_len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int to_fd, const char *to_name, size_t to_len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char *p, *q;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int rv;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int done_compare;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   rv = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (from_len != to_len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (from_len <= 8 * 1024 * 1024) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           done_compare = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (trymmap(from_fd) && trymmap(to_fd)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   p = mmap(NULL, from_len, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (p == (char *)MAP_FAILED)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           goto out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   q = mmap(NULL, from_len, PROT_READ, MAP_SHARED, to_fd, (off_t)0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (q == (char *)MAP_FAILED) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           munmap(p, from_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           goto out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   rv = memcmp(p, q, from_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   munmap(p, from_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   munmap(q, from_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   done_compare = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   out:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!done_compare) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   char buf1[MAXBSIZE];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   char buf2[MAXBSIZE];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   int n1, n2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   rv = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   lseek(from_fd, 0, SEEK_SET);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   lseek(to_fd, 0, SEEK_SET);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   while (rv == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           n1 = read(from_fd, buf1, sizeof(buf1));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           if (n1 == 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   break;          /* EOF */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           else if (n1 > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   n2 = read(to_fd, buf2, n1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   if (n2 == n1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                           rv = memcmp(buf1, buf2, n1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                           rv = 1; /* out of sync */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           } else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   rv = 1;         /* read failure */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   lseek(from_fd, 0, SEEK_SET);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   lseek(to_fd, 0, SEEK_SET);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           rv = 1; /* don't bother in this case */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return rv;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * tempfile_template --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * prepare a template filename for use with mktemp/mkstemp.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+tempfile_template(const char *path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           char *temp,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char *p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   (void)strncpy(temp, path, tsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   temp[tsize - 1] = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ((p = strrchr(temp, '/')) != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           p++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           p = temp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   (void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   temp[tsize - 1] = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create_tempfile --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create a temporary file based on path and open it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+create_tempfile(char *path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           char *temp,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   tempfile_template(path, temp, tsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return (mkstemp(temp));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create_newfile --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create a new file, overwriting an existing one if necessary
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+create_newfile(char *path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          int target,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          struct stat *sbp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char backup[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (target) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            * Unlink now... avoid ETXTBSY errors later.  Try to turn
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            * off the append/immutable bits -- if we fail, go ahead,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            * it might work.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (sbp->st_flags & NOCHANGEBITS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)chflags(path, sbp->st_flags & ~NOCHANGEBITS);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (dobackup) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (snprintf(backup, MAXPATHLEN, "%s%s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       path, suffix) != strlen(path) + strlen(suffix))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errx(EX_OSERR, "%s: backup filename too long",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                               path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)snprintf(backup, MAXPATHLEN, "%s%s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       path, suffix);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)printf("install: %s -> %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                               path, backup);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (rename(path, backup) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(EX_OSERR, "rename: %s to %s", path, backup);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           } else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)unlink(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return (open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Memory strategy threshold, in pages: if physmem is larger then this, use a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * large buffer */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define PHYSPAGES_THRESHOLD (32*1024)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Maximum buffer size in bytes - do not allow it to grow larger than this */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define BUFSIZE_MAX (2*1024*1024)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Small (default) buffer size in bytes. It's inefficient for this to be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * smaller than MAXPHYS */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define BUFSIZE_SMALL (MAXPHYS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * copy --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * copy from one file to another
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy(int from_fd, char *from_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int to_fd, char *to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     off_t size)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   register int nr, nw;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char *p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int done_copy;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   static char *buf = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   static size_t bufsize = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* Rewind file descriptors. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (lseek(from_fd, (off_t)0, SEEK_SET) == (off_t)-1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           err(EX_OSERR, "lseek: %s", from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (lseek(to_fd, (off_t)0, SEEK_SET) == (off_t)-1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           err(EX_OSERR, "lseek: %s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Mmap and write if less than 8M (the limit is so we don't totally
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * trash memory on big files.  This is really a minor hack, but it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * wins some CPU back.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   done_copy = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (size <= 8 * 1048576 && trymmap(from_fd) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       (p = mmap(NULL, (size_t)size, PROT_READ, MAP_SHARED,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               from_fd, (off_t)0)) != (char *)MAP_FAILED) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((nw = write(to_fd, p, size)) != size) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = nw > 0 ? EIO : serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           done_copy = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!done_copy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (buf == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    * Note that buf and bufsize are static. If
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    * malloc() fails, it will fail at the start
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    * and not copy only some files.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (sysconf(_SC_PHYS_PAGES) >
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       PHYSPAGES_THRESHOLD)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           bufsize = BUFSIZE_SMALL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   buf = malloc(bufsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (buf == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(1, "Not enough memory");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           while ((nr = read(from_fd, buf, bufsize)) > 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if ((nw = write(to_fd, buf, nr)) != nr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errno = nw > 0 ? EIO : serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           err(EX_OSERR, "%s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (nr != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   serrno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   (void)unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errno = serrno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   err(EX_OSERR, "%s", from_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * clone --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * create a clone of a file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clone(const char *from_name, const char *to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      int use_temp, char *temp_name, size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (use_temp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        tempfile_template(to_name, temp_name, tsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        mktemp(temp_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        to_name = temp_name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * strip --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * use strip(1) to strip the target file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+strip(char *to_name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   pid_t pid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   extern char** environ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char *const argv[] = { "xcrun", "strip", "-", to_name, NULL };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (0 == (error = posix_spawnp(&pid, "xcrun", NULL, NULL, argv, environ))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           int status = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           pid_t child = waitpid(pid, &status, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ((child == -1) || status) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   unlink(to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   errx(EX_SOFTWARE, "child process failed: xcrun strip - %s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           errno = error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           err(EX_OSERR, "xcrun strip - %s", to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * install_dir --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * build directory heirarchy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+install_dir(char *path)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   register char *p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct stat sb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int ch;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   for (p = path;; ++p)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!*p || (p != path && *p  == '/')) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   ch = *p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   *p = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (stat(path, &sb)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           if (errno != ENOENT || mkdir(path, 0755) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   err(EX_OSERR, "mkdir %s", path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   /* NOTREACHED */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           } else if (verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   (void)printf("install: mkdir %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                                path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   } else if (!S_ISDIR(sb.st_mode))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           errx(EX_OSERR, "%s exists but is not a directory", path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (!(*p = ch))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ((gid != (gid_t)-1 || uid != (uid_t)-1) && chown(path, uid, gid))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           warn("chown %u:%u %s", uid, gid, path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (chmod(path, mode))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           warn("chmod %o %s", mode, path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * usage --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * print a usage message and die
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+usage(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   (void)fprintf(stderr, "\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+usage: install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               [-o owner] file1 file2\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               [-o owner] file1 ... fileN directory\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       install -d [-v] [-g group] [-m mode] [-o owner] directory ...\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   exit(EX_USAGE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* NOTREACHED */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * trymmap --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * return true (1) if mmap should be tried, false (0) if not.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+trymmap(int fd)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The ifdef is for bootstrapping - f_fstypename doesn't exist in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * pre-Lite2-merge systems.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef MFSNAMELEN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct statfs stfs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (nommap || fstatfs(fd, &stfs) != 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return (0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (strcmp(stfs.f_fstypename, "ufs") == 0 ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       strcmp(stfs.f_fstypename, "cd9660") == 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return (1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return (0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/patches/install/xinstall.c.patch b/vendor/patches/install/xinstall.c.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..1e940d074
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/patches/install/xinstall.c.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,129 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Applied to original from file_cmds-430.140.2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- xinstall.c.orig        2024-08-20 16:07:42
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ xinstall.c     2024-08-27 16:58:56
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -70,9 +70,9 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <TargetConditionals.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <copyfile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sys/attr.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sys/clonefile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif    /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include "pathnames.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Bootstrap aid - this doesn't exist in most older releases */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifndef MAP_FAILED
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -92,6 +92,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *suffix = BACKUP_SUFFIX;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int        clone __P((const char *, const char *, int, char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void      copy __P((int, char *, int, char *, off_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int       compare __P((int, const char *, size_t, int, const char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int       create_newfile __P((char *, int, struct stat *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -100,6 +101,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void      install_dir __P((char *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ u_long    numeric_id __P((char *, char *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void      strip __P((char *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void tempfile_template __P((const char *, char *, size_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int       trymmap __P((int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void      usage __P((void));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -276,9 +278,10 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct stat from_sb, temp_sb, to_sb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   struct utimbuf utb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  int devnull, files_match, from_fd=0, serrno, target;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  int tempcopy, temp_fd, to_fd=0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int devnull, files_match, from_fd=-1, serrno, target;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int tempcopy, temp_fd=-1, to_fd=-1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const int tryclone = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   files_match = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -334,6 +337,17 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!files_match) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          int done_clone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (tryclone && !devnull && !dostrip) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (done_clone &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          (((to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0)) < 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          || (!tempcopy && fstat(to_fd, &to_sb) == -1))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                (void)unlink(tempcopy ? tempfile : to_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                done_clone = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (!done_clone) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (tempcopy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   to_fd = create_tempfile(to_name, tempfile,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       sizeof(tempfile));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -350,6 +364,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (!devnull)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   copy(from_fd, from_name, to_fd,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        tempcopy ? tempfile : to_name, from_sb.st_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          } /* !done_clone */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (dostrip) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -592,11 +607,11 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- * create_tempfile --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- *        create a temporary file based on path and open it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * tempfile_template --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        prepare a template filename for use with mktemp/mkstemp.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-create_tempfile(char *path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++tempfile_template(const char *path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           char *temp,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -610,6 +625,18 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           p = temp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   (void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   temp[tsize - 1] = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * create_tempfile --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        create a temporary file based on path and open it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++create_tempfile(char *path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          char *temp,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tempfile_template(path, temp, tsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return (mkstemp(temp));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -736,6 +763,22 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * clone --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        create a clone of a file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++clone(const char *from_name, const char *to_name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      int use_temp, char *temp_name, size_t tsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (use_temp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        tempfile_template(to_name, temp_name, tsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        mktemp(temp_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        to_name = temp_name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  * strip --
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *        use strip(1) to strip the target file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  */
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/patches/tcl/clonefile.patch b/vendor/patches/tcl/clonefile.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 000000000..769a0bfff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/patches/tcl/clonefile.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,112 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/vendor/tcl8.6.14/unix/configure b/vendor/tcl8.6.14/unix/configure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 87dc84d1e..a161fed43 100755
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/vendor/tcl8.6.14/unix/configure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/vendor/tcl8.6.14/unix/configure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -17439,7 +17439,7 @@ fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-for ac_header in copyfile.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++for ac_header in sys/clonefile.h copyfile.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if eval "test \"\${$as_ac_Header+set}\" = set"; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -17589,7 +17589,7 @@ fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-for ac_func in copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++for ac_func in clonefile copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ echo "$as_me:$LINENO: checking for $ac_func" >&5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/vendor/tcl8.6.14/unix/tclUnixFCmd.c b/vendor/tcl8.6.14/unix/tclUnixFCmd.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 26429df73..82da6d433 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/vendor/tcl8.6.14/unix/tclUnixFCmd.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/vendor/tcl8.6.14/unix/tclUnixFCmd.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -51,6 +51,18 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef HAVE_FTS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <fts.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_SYS_CLONEFILE_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sys/clonefile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(__APPLE__) && \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MAC_OS_X_VERSION_MIN_REQUIRED < 101200
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define MayUseCloneFile() (clonefile != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define MayUseCloneFile()   (1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif /* HAVE_CLONEFILE */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  * The following constants specify the type of callback when
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -526,14 +538,50 @@ DoCopyFile(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *----------------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * TclUnixCloneFile -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        Helper function for TclUnixCopyFile. Clones one regular file, using
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        clonefile().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Results:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        A standard Tcl result.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Side effects:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        A file is cloned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *----------------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TclUnixCloneFile(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    const char *src,              /* Pathname of file to clone (native). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    const char *dst,              /* Pathname of file to create (native). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    const Tcl_StatBuf *statBufPtr,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          /* Used to copy attributes. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int dontCopyAtts)             /* If flag set, don't copy attributes. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (clonefile(src, dst, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (dontCopyAtts || CopyFileAtts(src, dst, statBufPtr) == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    unlink(dst);                                  /* INTL: Native. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *----------------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  * TclUnixCopyFile -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *        Helper function for TclpCopyFile. Copies one regular file, using
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- *        read() and write().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *        read() and write(), or clones it with TclUnixCloneFile() if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *  supported.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  * Results:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *        A standard Tcl result.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -558,6 +606,13 @@ TclUnixCopyFile(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char *buffer;         /* Data buffer for copy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     size_t nread;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (MayUseCloneFile() &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            TclUnixCloneFile(src, dst, statBufPtr, dontCopyAtts) == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef DJGPP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define BINMODE |O_BINARY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #else
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/tcl8.6.14/unix/configure b/vendor/tcl8.6.14/unix/configure
</span><span style='display:block; white-space:pre;color:#808080;'>index 87dc84d1e..a161fed43 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/vendor/tcl8.6.14/unix/configure
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/tcl8.6.14/unix/configure
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -17439,7 +17439,7 @@ fi
</span> done
 
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-for ac_header in copyfile.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for ac_header in sys/clonefile.h copyfile.h
</span> do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -17589,7 +17589,7 @@ fi
</span> done
 
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-for ac_func in copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for ac_func in clonefile copyfile
</span> do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/vendor/tcl8.6.14/unix/tclUnixFCmd.c b/vendor/tcl8.6.14/unix/tclUnixFCmd.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 26429df73..470c56337 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/vendor/tcl8.6.14/unix/tclUnixFCmd.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/vendor/tcl8.6.14/unix/tclUnixFCmd.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -51,6 +51,18 @@
</span> #ifdef HAVE_FTS
 #include <fts.h>
 #endif
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_SYS_CLONEFILE_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/clonefile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if defined(__APPLE__) && \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   MAC_OS_X_VERSION_MIN_REQUIRED < 101200
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MayUseCloneFile()  (clonefile != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MayUseCloneFile()   (1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* HAVE_CLONEFILE */
</span> 
 /*
  * The following constants specify the type of callback when
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -526,14 +538,50 @@ DoCopyFile(
</span>     }
     return TCL_OK;
 }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *----------------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * TclUnixCloneFile -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Helper function for TclUnixCopyFile. Clones one regular file, using
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * clonefile().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Results:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * A standard Tcl result.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Side effects:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * A file is cloned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *----------------------------------------------------------------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+TclUnixCloneFile(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char *src,               /* Pathname of file to clone (native). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char *dst,               /* Pathname of file to create (native). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const Tcl_StatBuf *statBufPtr,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           /* Used to copy attributes. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int dontCopyAtts)              /* If flag set, don't copy attributes. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (clonefile(src, dst, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (dontCopyAtts || CopyFileAtts(src, dst, statBufPtr) == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    unlink(dst);                                   /* INTL: Native. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /*
  *----------------------------------------------------------------------
  *
  * TclUnixCopyFile -
  *
  *     Helper function for TclpCopyFile. Copies one regular file, using
<span style='display:block; white-space:pre;background:#ffe0e0;'>- *      read() and write().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * read() and write(), or clones it with TclUnixCloneFile() if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  supported.
</span>  *
  * Results:
  *     A standard Tcl result.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -558,6 +606,13 @@ TclUnixCopyFile(
</span>     char *buffer;         /* Data buffer for copy */
     size_t nread;
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef HAVE_CLONEFILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (MayUseCloneFile() &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            TclUnixCloneFile(src, dst, statBufPtr, dontCopyAtts) == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #ifdef DJGPP
 #define BINMODE |O_BINARY
 #else
</pre><pre style='margin:0'>

</pre>