<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>