install-sh revision 051ceee6
167f05d30Smrg#!/bin/sh 267f05d30Smrg# install - install a program, script, or datafile 3fffe5102Smrg 4051ceee6Smrgscriptversion=2020-11-14.01; # UTC 5fffe5102Smrg 667f05d30Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 767f05d30Smrg# later released in X11R6 (xc/config/util/install.sh) with the 867f05d30Smrg# following copyright and license. 967f05d30Smrg# 1067f05d30Smrg# Copyright (C) 1994 X Consortium 1167f05d30Smrg# 1267f05d30Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1367f05d30Smrg# of this software and associated documentation files (the "Software"), to 1467f05d30Smrg# deal in the Software without restriction, including without limitation the 1567f05d30Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1667f05d30Smrg# sell copies of the Software, and to permit persons to whom the Software is 1767f05d30Smrg# furnished to do so, subject to the following conditions: 1867f05d30Smrg# 1967f05d30Smrg# The above copyright notice and this permission notice shall be included in 2067f05d30Smrg# all copies or substantial portions of the Software. 2167f05d30Smrg# 2267f05d30Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2367f05d30Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2467f05d30Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2567f05d30Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2667f05d30Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2767f05d30Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2867f05d30Smrg# 2967f05d30Smrg# Except as contained in this notice, the name of the X Consortium shall not 3067f05d30Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3167f05d30Smrg# ings in this Software without prior written authorization from the X Consor- 3267f05d30Smrg# tium. 3367f05d30Smrg# 3467f05d30Smrg# 3567f05d30Smrg# FSF changes to this file are in the public domain. 3667f05d30Smrg# 3767f05d30Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38e90eff46Smrg# 'make' implicit rules from creating a file called install from it 3967f05d30Smrg# when there is no Makefile. 4067f05d30Smrg# 4167f05d30Smrg# This script is compatible with the BSD install script, but was written 42fffe5102Smrg# from scratch. 4367f05d30Smrg 44e90eff46Smrgtab=' ' 45fffe5102Smrgnl=' 46fffe5102Smrg' 47e90eff46SmrgIFS=" $tab$nl" 4867f05d30Smrg 49e90eff46Smrg# Set DOITPROG to "echo" to test this script. 5067f05d30Smrg 51fffe5102Smrgdoit=${DOITPROG-} 52e90eff46Smrgdoit_exec=${doit:-exec} 5367f05d30Smrg 54fffe5102Smrg# Put in absolute file names if you don't have them in your path; 55fffe5102Smrg# or use environment vars. 56fffe5102Smrg 57fffe5102Smrgchgrpprog=${CHGRPPROG-chgrp} 58fffe5102Smrgchmodprog=${CHMODPROG-chmod} 59fffe5102Smrgchownprog=${CHOWNPROG-chown} 60fffe5102Smrgcmpprog=${CMPPROG-cmp} 61fffe5102Smrgcpprog=${CPPROG-cp} 62fffe5102Smrgmkdirprog=${MKDIRPROG-mkdir} 63fffe5102Smrgmvprog=${MVPROG-mv} 64fffe5102Smrgrmprog=${RMPROG-rm} 65fffe5102Smrgstripprog=${STRIPPROG-strip} 66fffe5102Smrg 67fffe5102Smrgposix_mkdir= 68fffe5102Smrg 69fffe5102Smrg# Desired mode of installed file. 70fffe5102Smrgmode=0755 71fffe5102Smrg 72051ceee6Smrg# Create dirs (including intermediate dirs) using mode 755. 73051ceee6Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74051ceee6Smrgmkdir_umask=22 75051ceee6Smrg 76051ceee6Smrgbackupsuffix= 77fffe5102Smrgchgrpcmd= 78fffe5102Smrgchmodcmd=$chmodprog 79fffe5102Smrgchowncmd= 80fffe5102Smrgmvcmd=$mvprog 81fffe5102Smrgrmcmd="$rmprog -f" 82fffe5102Smrgstripcmd= 8367f05d30Smrg 84fffe5102Smrgsrc= 85fffe5102Smrgdst= 86fffe5102Smrgdir_arg= 87fffe5102Smrgdst_arg= 8867f05d30Smrg 89fffe5102Smrgcopy_on_change=false 90e90eff46Smrgis_target_a_directory=possibly 9167f05d30Smrg 92fffe5102Smrgusage="\ 93fffe5102SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94fffe5102Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95fffe5102Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96fffe5102Smrg or: $0 [OPTION]... -d DIRECTORIES... 9767f05d30Smrg 98fffe5102SmrgIn the 1st form, copy SRCFILE to DSTFILE. 99fffe5102SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100fffe5102SmrgIn the 4th, create DIRECTORIES. 10167f05d30Smrg 102fffe5102SmrgOptions: 103fffe5102Smrg --help display this help and exit. 104fffe5102Smrg --version display version info and exit. 10567f05d30Smrg 106fffe5102Smrg -c (ignored) 107051ceee6Smrg -C install only if different (preserve data modification time) 108fffe5102Smrg -d create directories instead of installing files. 109fffe5102Smrg -g GROUP $chgrpprog installed files to GROUP. 110fffe5102Smrg -m MODE $chmodprog installed files to MODE. 111fffe5102Smrg -o USER $chownprog installed files to USER. 112051ceee6Smrg -p pass -p to $cpprog. 113fffe5102Smrg -s $stripprog installed files. 114051ceee6Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115fffe5102Smrg -t DIRECTORY install into DIRECTORY. 116fffe5102Smrg -T report an error if DSTFILE is a directory. 11767f05d30Smrg 118fffe5102SmrgEnvironment variables override the default commands: 119fffe5102Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120fffe5102Smrg RMPROG STRIPPROG 121051ceee6Smrg 122051ceee6SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123051ceee6Smrgit's up to you to specify -f if you want it. 124051ceee6Smrg 125051ceee6SmrgIf -S is not specified, no backups are attempted. 126051ceee6Smrg 127051ceee6SmrgEmail bug reports to bug-automake@gnu.org. 128051ceee6SmrgAutomake home page: https://www.gnu.org/software/automake/ 129fffe5102Smrg" 13067f05d30Smrg 131fffe5102Smrgwhile test $# -ne 0; do 132fffe5102Smrg case $1 in 133fffe5102Smrg -c) ;; 13467f05d30Smrg 135fffe5102Smrg -C) copy_on_change=true;; 13667f05d30Smrg 137fffe5102Smrg -d) dir_arg=true;; 13867f05d30Smrg 139fffe5102Smrg -g) chgrpcmd="$chgrpprog $2" 140e90eff46Smrg shift;; 14167f05d30Smrg 142fffe5102Smrg --help) echo "$usage"; exit $?;; 14367f05d30Smrg 144fffe5102Smrg -m) mode=$2 145e90eff46Smrg case $mode in 146e90eff46Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147e90eff46Smrg echo "$0: invalid mode: $mode" >&2 148e90eff46Smrg exit 1;; 149e90eff46Smrg esac 150e90eff46Smrg shift;; 15167f05d30Smrg 152fffe5102Smrg -o) chowncmd="$chownprog $2" 153e90eff46Smrg shift;; 15467f05d30Smrg 155051ceee6Smrg -p) cpprog="$cpprog -p";; 156051ceee6Smrg 157fffe5102Smrg -s) stripcmd=$stripprog;; 15867f05d30Smrg 159051ceee6Smrg -S) backupsuffix="$2" 160051ceee6Smrg shift;; 161051ceee6Smrg 162e90eff46Smrg -t) 163e90eff46Smrg is_target_a_directory=always 164e90eff46Smrg dst_arg=$2 165e90eff46Smrg # Protect names problematic for 'test' and other utilities. 166e90eff46Smrg case $dst_arg in 167e90eff46Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168e90eff46Smrg esac 169e90eff46Smrg shift;; 17067f05d30Smrg 171e90eff46Smrg -T) is_target_a_directory=never;; 17267f05d30Smrg 173fffe5102Smrg --version) echo "$0 $scriptversion"; exit $?;; 17467f05d30Smrg 175e90eff46Smrg --) shift 176e90eff46Smrg break;; 17767f05d30Smrg 178e90eff46Smrg -*) echo "$0: invalid option: $1" >&2 179e90eff46Smrg exit 1;; 18067f05d30Smrg 181fffe5102Smrg *) break;; 182fffe5102Smrg esac 183fffe5102Smrg shift 184fffe5102Smrgdone 18567f05d30Smrg 186e90eff46Smrg# We allow the use of options -d and -T together, by making -d 187e90eff46Smrg# take the precedence; this is for compatibility with GNU install. 188e90eff46Smrg 189e90eff46Smrgif test -n "$dir_arg"; then 190e90eff46Smrg if test -n "$dst_arg"; then 191e90eff46Smrg echo "$0: target directory not allowed when installing a directory." >&2 192e90eff46Smrg exit 1 193e90eff46Smrg fi 194e90eff46Smrgfi 195e90eff46Smrg 196fffe5102Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197fffe5102Smrg # When -d is used, all remaining arguments are directories to create. 198fffe5102Smrg # When -t is used, the destination is already specified. 199fffe5102Smrg # Otherwise, the last argument is the destination. Remove it from $@. 200fffe5102Smrg for arg 201fffe5102Smrg do 202fffe5102Smrg if test -n "$dst_arg"; then 203fffe5102Smrg # $@ is not empty: it contains at least $arg. 204fffe5102Smrg set fnord "$@" "$dst_arg" 205fffe5102Smrg shift # fnord 206fffe5102Smrg fi 207fffe5102Smrg shift # arg 208fffe5102Smrg dst_arg=$arg 209e90eff46Smrg # Protect names problematic for 'test' and other utilities. 2106dbd43aaSmrg case $dst_arg in 2116dbd43aaSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 2126dbd43aaSmrg esac 213fffe5102Smrg done 214fffe5102Smrgfi 21567f05d30Smrg 216fffe5102Smrgif test $# -eq 0; then 217fffe5102Smrg if test -z "$dir_arg"; then 218fffe5102Smrg echo "$0: no input file specified." >&2 219fffe5102Smrg exit 1 220fffe5102Smrg fi 221e90eff46Smrg # It's OK to call 'install-sh -d' without argument. 222fffe5102Smrg # This can happen when creating conditional directories. 223fffe5102Smrg exit 0 224fffe5102Smrgfi 22567f05d30Smrg 226e90eff46Smrgif test -z "$dir_arg"; then 227e90eff46Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228e90eff46Smrg if test ! -d "$dst_arg"; then 229e90eff46Smrg echo "$0: $dst_arg: Is not a directory." >&2 230e90eff46Smrg exit 1 231e90eff46Smrg fi 232e90eff46Smrg fi 233e90eff46Smrgfi 234e90eff46Smrg 235fffe5102Smrgif test -z "$dir_arg"; then 2366dbd43aaSmrg do_exit='(exit $ret); exit $ret' 2376dbd43aaSmrg trap "ret=129; $do_exit" 1 2386dbd43aaSmrg trap "ret=130; $do_exit" 2 2396dbd43aaSmrg trap "ret=141; $do_exit" 13 2406dbd43aaSmrg trap "ret=143; $do_exit" 15 241fffe5102Smrg 242fffe5102Smrg # Set umask so as not to create temps with too-generous modes. 243fffe5102Smrg # However, 'strip' requires both read and write access to temps. 244fffe5102Smrg case $mode in 245fffe5102Smrg # Optimize common cases. 246fffe5102Smrg *644) cp_umask=133;; 247fffe5102Smrg *755) cp_umask=22;; 248fffe5102Smrg 249fffe5102Smrg *[0-7]) 250fffe5102Smrg if test -z "$stripcmd"; then 251e90eff46Smrg u_plus_rw= 252fffe5102Smrg else 253e90eff46Smrg u_plus_rw='% 200' 254fffe5102Smrg fi 255fffe5102Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256fffe5102Smrg *) 257fffe5102Smrg if test -z "$stripcmd"; then 258e90eff46Smrg u_plus_rw= 259fffe5102Smrg else 260e90eff46Smrg u_plus_rw=,u+rw 261fffe5102Smrg fi 262fffe5102Smrg cp_umask=$mode$u_plus_rw;; 263fffe5102Smrg esac 264fffe5102Smrgfi 26567f05d30Smrg 266fffe5102Smrgfor src 267fffe5102Smrgdo 268e90eff46Smrg # Protect names problematic for 'test' and other utilities. 269fffe5102Smrg case $src in 2706dbd43aaSmrg -* | [=\(\)!]) src=./$src;; 271fffe5102Smrg esac 272fffe5102Smrg 273fffe5102Smrg if test -n "$dir_arg"; then 274fffe5102Smrg dst=$src 275fffe5102Smrg dstdir=$dst 276fffe5102Smrg test -d "$dstdir" 277fffe5102Smrg dstdir_status=$? 278051ceee6Smrg # Don't chown directories that already exist. 279051ceee6Smrg if test $dstdir_status = 0; then 280051ceee6Smrg chowncmd="" 281051ceee6Smrg fi 282fffe5102Smrg else 283fffe5102Smrg 284fffe5102Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285fffe5102Smrg # might cause directories to be created, which would be especially bad 286fffe5102Smrg # if $src (and thus $dsttmp) contains '*'. 287fffe5102Smrg if test ! -f "$src" && test ! -d "$src"; then 288fffe5102Smrg echo "$0: $src does not exist." >&2 289fffe5102Smrg exit 1 290fffe5102Smrg fi 291fffe5102Smrg 292fffe5102Smrg if test -z "$dst_arg"; then 293fffe5102Smrg echo "$0: no destination specified." >&2 294fffe5102Smrg exit 1 295fffe5102Smrg fi 296fffe5102Smrg dst=$dst_arg 29767f05d30Smrg 298051ceee6Smrg # If destination is a directory, append the input filename. 299fffe5102Smrg if test -d "$dst"; then 300e90eff46Smrg if test "$is_target_a_directory" = never; then 301e90eff46Smrg echo "$0: $dst_arg: Is a directory" >&2 302e90eff46Smrg exit 1 303fffe5102Smrg fi 304fffe5102Smrg dstdir=$dst 305051ceee6Smrg dstbase=`basename "$src"` 306051ceee6Smrg case $dst in 307051ceee6Smrg */) dst=$dst$dstbase;; 308051ceee6Smrg *) dst=$dst/$dstbase;; 309051ceee6Smrg esac 310fffe5102Smrg dstdir_status=0 311fffe5102Smrg else 312e90eff46Smrg dstdir=`dirname "$dst"` 313fffe5102Smrg test -d "$dstdir" 314fffe5102Smrg dstdir_status=$? 315fffe5102Smrg fi 316fffe5102Smrg fi 317fffe5102Smrg 318051ceee6Smrg case $dstdir in 319051ceee6Smrg */) dstdirslash=$dstdir;; 320051ceee6Smrg *) dstdirslash=$dstdir/;; 321051ceee6Smrg esac 322051ceee6Smrg 323fffe5102Smrg obsolete_mkdir_used=false 324fffe5102Smrg 325fffe5102Smrg if test $dstdir_status != 0; then 326fffe5102Smrg case $posix_mkdir in 327fffe5102Smrg '') 328e90eff46Smrg # With -d, create the new directory with the user-specified mode. 329e90eff46Smrg # Otherwise, rely on $mkdir_umask. 330e90eff46Smrg if test -n "$dir_arg"; then 331e90eff46Smrg mkdir_mode=-m$mode 332e90eff46Smrg else 333e90eff46Smrg mkdir_mode= 334e90eff46Smrg fi 335e90eff46Smrg 336e90eff46Smrg posix_mkdir=false 337051ceee6Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 338051ceee6Smrg # here however when possible just to lower collision chance. 339051ceee6Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340051ceee6Smrg 341051ceee6Smrg trap ' 342051ceee6Smrg ret=$? 343051ceee6Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344051ceee6Smrg exit $ret 345051ceee6Smrg ' 0 346051ceee6Smrg 347051ceee6Smrg # Because "mkdir -p" follows existing symlinks and we likely work 348051ceee6Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349051ceee6Smrg # directory is successfully created first before we actually test 350051ceee6Smrg # 'mkdir -p'. 351051ceee6Smrg if (umask $mkdir_umask && 352051ceee6Smrg $mkdirprog $mkdir_mode "$tmpdir" && 353051ceee6Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354051ceee6Smrg then 355051ceee6Smrg if test -z "$dir_arg" || { 356051ceee6Smrg # Check for POSIX incompatibilities with -m. 357051ceee6Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358051ceee6Smrg # other-writable bit of parent directory when it shouldn't. 359051ceee6Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360051ceee6Smrg test_tmpdir="$tmpdir/a" 361051ceee6Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362051ceee6Smrg case $ls_ld_tmpdir in 363051ceee6Smrg d????-?r-*) different_mode=700;; 364051ceee6Smrg d????-?--*) different_mode=755;; 365051ceee6Smrg *) false;; 366051ceee6Smrg esac && 367051ceee6Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368051ceee6Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369051ceee6Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370051ceee6Smrg } 371051ceee6Smrg } 372051ceee6Smrg then posix_mkdir=: 373051ceee6Smrg fi 374051ceee6Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375051ceee6Smrg else 376051ceee6Smrg # Remove any dirs left behind by ancient mkdir implementations. 377051ceee6Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378051ceee6Smrg fi 379051ceee6Smrg trap '' 0;; 380fffe5102Smrg esac 38167f05d30Smrg 382fffe5102Smrg if 383fffe5102Smrg $posix_mkdir && ( 384e90eff46Smrg umask $mkdir_umask && 385e90eff46Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386fffe5102Smrg ) 387fffe5102Smrg then : 388fffe5102Smrg else 389fffe5102Smrg 390051ceee6Smrg # mkdir does not conform to POSIX, 391fffe5102Smrg # or it failed possibly due to a race condition. Create the 392fffe5102Smrg # directory the slow way, step by step, checking for races as we go. 393fffe5102Smrg 394fffe5102Smrg case $dstdir in 395e90eff46Smrg /*) prefix='/';; 396e90eff46Smrg [-=\(\)!]*) prefix='./';; 397e90eff46Smrg *) prefix='';; 398fffe5102Smrg esac 399fffe5102Smrg 400fffe5102Smrg oIFS=$IFS 401fffe5102Smrg IFS=/ 402e90eff46Smrg set -f 403fffe5102Smrg set fnord $dstdir 404fffe5102Smrg shift 405e90eff46Smrg set +f 406fffe5102Smrg IFS=$oIFS 407fffe5102Smrg 408fffe5102Smrg prefixes= 409fffe5102Smrg 410fffe5102Smrg for d 411fffe5102Smrg do 412e90eff46Smrg test X"$d" = X && continue 413e90eff46Smrg 414e90eff46Smrg prefix=$prefix$d 415e90eff46Smrg if test -d "$prefix"; then 416e90eff46Smrg prefixes= 417e90eff46Smrg else 418e90eff46Smrg if $posix_mkdir; then 419051ceee6Smrg (umask $mkdir_umask && 420e90eff46Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421e90eff46Smrg # Don't fail if two instances are running concurrently. 422e90eff46Smrg test -d "$prefix" || exit 1 423e90eff46Smrg else 424e90eff46Smrg case $prefix in 425e90eff46Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426e90eff46Smrg *) qprefix=$prefix;; 427e90eff46Smrg esac 428e90eff46Smrg prefixes="$prefixes '$qprefix'" 429e90eff46Smrg fi 430e90eff46Smrg fi 431e90eff46Smrg prefix=$prefix/ 432fffe5102Smrg done 433fffe5102Smrg 434fffe5102Smrg if test -n "$prefixes"; then 435e90eff46Smrg # Don't fail if two instances are running concurrently. 436e90eff46Smrg (umask $mkdir_umask && 437e90eff46Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 438e90eff46Smrg test -d "$dstdir" || exit 1 439e90eff46Smrg obsolete_mkdir_used=true 440fffe5102Smrg fi 441fffe5102Smrg fi 442fffe5102Smrg fi 443fffe5102Smrg 444fffe5102Smrg if test -n "$dir_arg"; then 445fffe5102Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446fffe5102Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447fffe5102Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448fffe5102Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449fffe5102Smrg else 450fffe5102Smrg 451fffe5102Smrg # Make a couple of temp file names in the proper directory. 452051ceee6Smrg dsttmp=${dstdirslash}_inst.$$_ 453051ceee6Smrg rmtmp=${dstdirslash}_rm.$$_ 454fffe5102Smrg 455fffe5102Smrg # Trap to clean up those temp files at exit. 456fffe5102Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457fffe5102Smrg 458fffe5102Smrg # Copy the file name to the temp name. 459051ceee6Smrg (umask $cp_umask && 460051ceee6Smrg { test -z "$stripcmd" || { 461051ceee6Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462051ceee6Smrg # which would cause strip to fail. 463051ceee6Smrg if test -z "$doit"; then 464051ceee6Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 465051ceee6Smrg else 466051ceee6Smrg $doit touch "$dsttmp" 467051ceee6Smrg fi 468051ceee6Smrg } 469051ceee6Smrg } && 470051ceee6Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471fffe5102Smrg 472fffe5102Smrg # and set any options; do chmod last to preserve setuid bits. 473fffe5102Smrg # 474fffe5102Smrg # If any of these fail, we abort the whole thing. If we want to 475fffe5102Smrg # ignore errors from any of these, just make sure not to ignore 476fffe5102Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477fffe5102Smrg # 478fffe5102Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479fffe5102Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480fffe5102Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481fffe5102Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482fffe5102Smrg 483fffe5102Smrg # If -C, don't bother to copy if it wouldn't change the file. 484fffe5102Smrg if $copy_on_change && 485e90eff46Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486e90eff46Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487e90eff46Smrg set -f && 488fffe5102Smrg set X $old && old=:$2:$4:$5:$6 && 489fffe5102Smrg set X $new && new=:$2:$4:$5:$6 && 490e90eff46Smrg set +f && 491fffe5102Smrg test "$old" = "$new" && 492fffe5102Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493fffe5102Smrg then 494fffe5102Smrg rm -f "$dsttmp" 495fffe5102Smrg else 496051ceee6Smrg # If $backupsuffix is set, and the file being installed 497051ceee6Smrg # already exists, attempt a backup. Don't worry if it fails, 498051ceee6Smrg # e.g., if mv doesn't support -f. 499051ceee6Smrg if test -n "$backupsuffix" && test -f "$dst"; then 500051ceee6Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501051ceee6Smrg fi 502051ceee6Smrg 503fffe5102Smrg # Rename the file to the real destination. 504fffe5102Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505fffe5102Smrg 506fffe5102Smrg # The rename failed, perhaps because mv can't rename something else 507fffe5102Smrg # to itself, or perhaps because mv is so ancient that it does not 508fffe5102Smrg # support -f. 509fffe5102Smrg { 510e90eff46Smrg # Now remove or move aside any old file at destination location. 511e90eff46Smrg # We try this two ways since rm can't unlink itself on some 512e90eff46Smrg # systems and the destination file might be busy for other 513e90eff46Smrg # reasons. In this case, the final cleanup might fail but the new 514e90eff46Smrg # file should still install successfully. 515e90eff46Smrg { 516e90eff46Smrg test ! -f "$dst" || 517051ceee6Smrg $doit $rmcmd "$dst" 2>/dev/null || 518e90eff46Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519051ceee6Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520e90eff46Smrg } || 521e90eff46Smrg { echo "$0: cannot unlink or rename $dst" >&2 522e90eff46Smrg (exit 1); exit 1 523e90eff46Smrg } 524e90eff46Smrg } && 525e90eff46Smrg 526e90eff46Smrg # Now rename the file to the real destination. 527e90eff46Smrg $doit $mvcmd "$dsttmp" "$dst" 528fffe5102Smrg } 529fffe5102Smrg fi || exit 1 530fffe5102Smrg 531fffe5102Smrg trap '' 0 532fffe5102Smrg fi 533fffe5102Smrgdone 53467f05d30Smrg 535fffe5102Smrg# Local variables: 536051ceee6Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537fffe5102Smrg# time-stamp-start: "scriptversion=" 538fffe5102Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539051ceee6Smrg# time-stamp-time-zone: "UTC0" 540fffe5102Smrg# time-stamp-end: "; # UTC" 541fffe5102Smrg# End: 542