install-sh revision 414cce6a
1ded1caa4Smrg#!/bin/sh 2ded1caa4Smrg# install - install a program, script, or datafile 350539131Smrg 4414cce6aSmrgscriptversion=2020-11-14.01; # UTC 550539131Smrg 6ded1caa4Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7ded1caa4Smrg# later released in X11R6 (xc/config/util/install.sh) with the 8ded1caa4Smrg# following copyright and license. 9ded1caa4Smrg# 10ded1caa4Smrg# Copyright (C) 1994 X Consortium 11ded1caa4Smrg# 12ded1caa4Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13ded1caa4Smrg# of this software and associated documentation files (the "Software"), to 14ded1caa4Smrg# deal in the Software without restriction, including without limitation the 15ded1caa4Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16ded1caa4Smrg# sell copies of the Software, and to permit persons to whom the Software is 17ded1caa4Smrg# furnished to do so, subject to the following conditions: 18ded1caa4Smrg# 19ded1caa4Smrg# The above copyright notice and this permission notice shall be included in 20ded1caa4Smrg# all copies or substantial portions of the Software. 21ded1caa4Smrg# 22ded1caa4Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23ded1caa4Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24ded1caa4Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25ded1caa4Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26ded1caa4Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27ded1caa4Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28ded1caa4Smrg# 29ded1caa4Smrg# Except as contained in this notice, the name of the X Consortium shall not 30ded1caa4Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 31ded1caa4Smrg# ings in this Software without prior written authorization from the X Consor- 32ded1caa4Smrg# tium. 33ded1caa4Smrg# 34ded1caa4Smrg# 35ded1caa4Smrg# FSF changes to this file are in the public domain. 36ded1caa4Smrg# 37ded1caa4Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38414cce6aSmrg# 'make' implicit rules from creating a file called install from it 39ded1caa4Smrg# when there is no Makefile. 40ded1caa4Smrg# 41ded1caa4Smrg# This script is compatible with the BSD install script, but was written 4250539131Smrg# from scratch. 43ded1caa4Smrg 44414cce6aSmrgtab=' ' 4550539131Smrgnl=' 4650539131Smrg' 47414cce6aSmrgIFS=" $tab$nl" 48ded1caa4Smrg 49414cce6aSmrg# Set DOITPROG to "echo" to test this script. 50ded1caa4Smrg 5150539131Smrgdoit=${DOITPROG-} 52414cce6aSmrgdoit_exec=${doit:-exec} 53ded1caa4Smrg 5450539131Smrg# Put in absolute file names if you don't have them in your path; 5550539131Smrg# or use environment vars. 5650539131Smrg 5750539131Smrgchgrpprog=${CHGRPPROG-chgrp} 5850539131Smrgchmodprog=${CHMODPROG-chmod} 5950539131Smrgchownprog=${CHOWNPROG-chown} 6050539131Smrgcmpprog=${CMPPROG-cmp} 6150539131Smrgcpprog=${CPPROG-cp} 6250539131Smrgmkdirprog=${MKDIRPROG-mkdir} 6350539131Smrgmvprog=${MVPROG-mv} 6450539131Smrgrmprog=${RMPROG-rm} 6550539131Smrgstripprog=${STRIPPROG-strip} 6650539131Smrg 6750539131Smrgposix_mkdir= 6850539131Smrg 6950539131Smrg# Desired mode of installed file. 7050539131Smrgmode=0755 7150539131Smrg 72414cce6aSmrg# Create dirs (including intermediate dirs) using mode 755. 73414cce6aSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74414cce6aSmrgmkdir_umask=22 75414cce6aSmrg 76414cce6aSmrgbackupsuffix= 7750539131Smrgchgrpcmd= 7850539131Smrgchmodcmd=$chmodprog 7950539131Smrgchowncmd= 8050539131Smrgmvcmd=$mvprog 8150539131Smrgrmcmd="$rmprog -f" 8250539131Smrgstripcmd= 83ded1caa4Smrg 8450539131Smrgsrc= 8550539131Smrgdst= 8650539131Smrgdir_arg= 8750539131Smrgdst_arg= 88ded1caa4Smrg 8950539131Smrgcopy_on_change=false 90414cce6aSmrgis_target_a_directory=possibly 91ded1caa4Smrg 9250539131Smrgusage="\ 9350539131SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 9450539131Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 9550539131Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9650539131Smrg or: $0 [OPTION]... -d DIRECTORIES... 97ded1caa4Smrg 9850539131SmrgIn the 1st form, copy SRCFILE to DSTFILE. 9950539131SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 10050539131SmrgIn the 4th, create DIRECTORIES. 101ded1caa4Smrg 10250539131SmrgOptions: 10350539131Smrg --help display this help and exit. 10450539131Smrg --version display version info and exit. 105ded1caa4Smrg 10650539131Smrg -c (ignored) 107414cce6aSmrg -C install only if different (preserve data modification time) 10850539131Smrg -d create directories instead of installing files. 10950539131Smrg -g GROUP $chgrpprog installed files to GROUP. 11050539131Smrg -m MODE $chmodprog installed files to MODE. 11150539131Smrg -o USER $chownprog installed files to USER. 112414cce6aSmrg -p pass -p to $cpprog. 11350539131Smrg -s $stripprog installed files. 114414cce6aSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 11550539131Smrg -t DIRECTORY install into DIRECTORY. 11650539131Smrg -T report an error if DSTFILE is a directory. 117ded1caa4Smrg 11850539131SmrgEnvironment variables override the default commands: 11950539131Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 12050539131Smrg RMPROG STRIPPROG 121414cce6aSmrg 122414cce6aSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123414cce6aSmrgit's up to you to specify -f if you want it. 124414cce6aSmrg 125414cce6aSmrgIf -S is not specified, no backups are attempted. 126414cce6aSmrg 127414cce6aSmrgEmail bug reports to bug-automake@gnu.org. 128414cce6aSmrgAutomake home page: https://www.gnu.org/software/automake/ 12950539131Smrg" 130ded1caa4Smrg 13150539131Smrgwhile test $# -ne 0; do 13250539131Smrg case $1 in 13350539131Smrg -c) ;; 134ded1caa4Smrg 13550539131Smrg -C) copy_on_change=true;; 136ded1caa4Smrg 13750539131Smrg -d) dir_arg=true;; 138ded1caa4Smrg 13950539131Smrg -g) chgrpcmd="$chgrpprog $2" 140414cce6aSmrg shift;; 141ded1caa4Smrg 14250539131Smrg --help) echo "$usage"; exit $?;; 143ded1caa4Smrg 14450539131Smrg -m) mode=$2 145414cce6aSmrg case $mode in 146414cce6aSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147414cce6aSmrg echo "$0: invalid mode: $mode" >&2 148414cce6aSmrg exit 1;; 149414cce6aSmrg esac 150414cce6aSmrg shift;; 151ded1caa4Smrg 15250539131Smrg -o) chowncmd="$chownprog $2" 153414cce6aSmrg shift;; 154414cce6aSmrg 155414cce6aSmrg -p) cpprog="$cpprog -p";; 156ded1caa4Smrg 15750539131Smrg -s) stripcmd=$stripprog;; 158ded1caa4Smrg 159414cce6aSmrg -S) backupsuffix="$2" 160414cce6aSmrg shift;; 161414cce6aSmrg 162414cce6aSmrg -t) 163414cce6aSmrg is_target_a_directory=always 164414cce6aSmrg dst_arg=$2 165414cce6aSmrg # Protect names problematic for 'test' and other utilities. 166414cce6aSmrg case $dst_arg in 167414cce6aSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168414cce6aSmrg esac 169414cce6aSmrg shift;; 170ded1caa4Smrg 171414cce6aSmrg -T) is_target_a_directory=never;; 172ded1caa4Smrg 17350539131Smrg --version) echo "$0 $scriptversion"; exit $?;; 174ded1caa4Smrg 175414cce6aSmrg --) shift 176414cce6aSmrg break;; 177ded1caa4Smrg 178414cce6aSmrg -*) echo "$0: invalid option: $1" >&2 179414cce6aSmrg exit 1;; 180ded1caa4Smrg 18150539131Smrg *) break;; 18250539131Smrg esac 18350539131Smrg shift 18450539131Smrgdone 185ded1caa4Smrg 186414cce6aSmrg# We allow the use of options -d and -T together, by making -d 187414cce6aSmrg# take the precedence; this is for compatibility with GNU install. 188414cce6aSmrg 189414cce6aSmrgif test -n "$dir_arg"; then 190414cce6aSmrg if test -n "$dst_arg"; then 191414cce6aSmrg echo "$0: target directory not allowed when installing a directory." >&2 192414cce6aSmrg exit 1 193414cce6aSmrg fi 194414cce6aSmrgfi 195414cce6aSmrg 19650539131Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 19750539131Smrg # When -d is used, all remaining arguments are directories to create. 19850539131Smrg # When -t is used, the destination is already specified. 19950539131Smrg # Otherwise, the last argument is the destination. Remove it from $@. 20050539131Smrg for arg 20150539131Smrg do 20250539131Smrg if test -n "$dst_arg"; then 20350539131Smrg # $@ is not empty: it contains at least $arg. 20450539131Smrg set fnord "$@" "$dst_arg" 20550539131Smrg shift # fnord 20650539131Smrg fi 20750539131Smrg shift # arg 20850539131Smrg dst_arg=$arg 209414cce6aSmrg # Protect names problematic for 'test' and other utilities. 210414cce6aSmrg case $dst_arg in 211414cce6aSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212414cce6aSmrg esac 21350539131Smrg done 21450539131Smrgfi 215ded1caa4Smrg 21650539131Smrgif test $# -eq 0; then 21750539131Smrg if test -z "$dir_arg"; then 21850539131Smrg echo "$0: no input file specified." >&2 21950539131Smrg exit 1 22050539131Smrg fi 221414cce6aSmrg # It's OK to call 'install-sh -d' without argument. 22250539131Smrg # This can happen when creating conditional directories. 22350539131Smrg exit 0 22450539131Smrgfi 225ded1caa4Smrg 22650539131Smrgif test -z "$dir_arg"; then 227414cce6aSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228414cce6aSmrg if test ! -d "$dst_arg"; then 229414cce6aSmrg echo "$0: $dst_arg: Is not a directory." >&2 230414cce6aSmrg exit 1 231414cce6aSmrg fi 232414cce6aSmrg fi 233414cce6aSmrgfi 234414cce6aSmrg 235414cce6aSmrgif test -z "$dir_arg"; then 236414cce6aSmrg do_exit='(exit $ret); exit $ret' 237414cce6aSmrg trap "ret=129; $do_exit" 1 238414cce6aSmrg trap "ret=130; $do_exit" 2 239414cce6aSmrg trap "ret=141; $do_exit" 13 240414cce6aSmrg trap "ret=143; $do_exit" 15 24150539131Smrg 24250539131Smrg # Set umask so as not to create temps with too-generous modes. 24350539131Smrg # However, 'strip' requires both read and write access to temps. 24450539131Smrg case $mode in 24550539131Smrg # Optimize common cases. 24650539131Smrg *644) cp_umask=133;; 24750539131Smrg *755) cp_umask=22;; 24850539131Smrg 24950539131Smrg *[0-7]) 25050539131Smrg if test -z "$stripcmd"; then 251414cce6aSmrg u_plus_rw= 25250539131Smrg else 253414cce6aSmrg u_plus_rw='% 200' 25450539131Smrg fi 25550539131Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 25650539131Smrg *) 25750539131Smrg if test -z "$stripcmd"; then 258414cce6aSmrg u_plus_rw= 25950539131Smrg else 260414cce6aSmrg u_plus_rw=,u+rw 26150539131Smrg fi 26250539131Smrg cp_umask=$mode$u_plus_rw;; 26350539131Smrg esac 26450539131Smrgfi 265ded1caa4Smrg 26650539131Smrgfor src 26750539131Smrgdo 268414cce6aSmrg # Protect names problematic for 'test' and other utilities. 26950539131Smrg case $src in 270414cce6aSmrg -* | [=\(\)!]) src=./$src;; 27150539131Smrg esac 27250539131Smrg 27350539131Smrg if test -n "$dir_arg"; then 27450539131Smrg dst=$src 27550539131Smrg dstdir=$dst 27650539131Smrg test -d "$dstdir" 27750539131Smrg dstdir_status=$? 278414cce6aSmrg # Don't chown directories that already exist. 279414cce6aSmrg if test $dstdir_status = 0; then 280414cce6aSmrg chowncmd="" 281414cce6aSmrg fi 28250539131Smrg else 28350539131Smrg 28450539131Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 28550539131Smrg # might cause directories to be created, which would be especially bad 28650539131Smrg # if $src (and thus $dsttmp) contains '*'. 28750539131Smrg if test ! -f "$src" && test ! -d "$src"; then 28850539131Smrg echo "$0: $src does not exist." >&2 28950539131Smrg exit 1 29050539131Smrg fi 29150539131Smrg 29250539131Smrg if test -z "$dst_arg"; then 29350539131Smrg echo "$0: no destination specified." >&2 29450539131Smrg exit 1 29550539131Smrg fi 29650539131Smrg dst=$dst_arg 297ded1caa4Smrg 298414cce6aSmrg # If destination is a directory, append the input filename. 29950539131Smrg if test -d "$dst"; then 300414cce6aSmrg if test "$is_target_a_directory" = never; then 301414cce6aSmrg echo "$0: $dst_arg: Is a directory" >&2 302414cce6aSmrg exit 1 30350539131Smrg fi 30450539131Smrg dstdir=$dst 305414cce6aSmrg dstbase=`basename "$src"` 306414cce6aSmrg case $dst in 307414cce6aSmrg */) dst=$dst$dstbase;; 308414cce6aSmrg *) dst=$dst/$dstbase;; 309414cce6aSmrg esac 31050539131Smrg dstdir_status=0 31150539131Smrg else 312414cce6aSmrg dstdir=`dirname "$dst"` 31350539131Smrg test -d "$dstdir" 31450539131Smrg dstdir_status=$? 31550539131Smrg fi 31650539131Smrg fi 31750539131Smrg 318414cce6aSmrg case $dstdir in 319414cce6aSmrg */) dstdirslash=$dstdir;; 320414cce6aSmrg *) dstdirslash=$dstdir/;; 321414cce6aSmrg esac 322414cce6aSmrg 32350539131Smrg obsolete_mkdir_used=false 32450539131Smrg 32550539131Smrg if test $dstdir_status != 0; then 32650539131Smrg case $posix_mkdir in 32750539131Smrg '') 328414cce6aSmrg # With -d, create the new directory with the user-specified mode. 329414cce6aSmrg # Otherwise, rely on $mkdir_umask. 330414cce6aSmrg if test -n "$dir_arg"; then 331414cce6aSmrg mkdir_mode=-m$mode 332414cce6aSmrg else 333414cce6aSmrg mkdir_mode= 334414cce6aSmrg fi 335414cce6aSmrg 336414cce6aSmrg posix_mkdir=false 337414cce6aSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 338414cce6aSmrg # here however when possible just to lower collision chance. 339414cce6aSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340414cce6aSmrg 341414cce6aSmrg trap ' 342414cce6aSmrg ret=$? 343414cce6aSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344414cce6aSmrg exit $ret 345414cce6aSmrg ' 0 346414cce6aSmrg 347414cce6aSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348414cce6aSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349414cce6aSmrg # directory is successfully created first before we actually test 350414cce6aSmrg # 'mkdir -p'. 351414cce6aSmrg if (umask $mkdir_umask && 352414cce6aSmrg $mkdirprog $mkdir_mode "$tmpdir" && 353414cce6aSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354414cce6aSmrg then 355414cce6aSmrg if test -z "$dir_arg" || { 356414cce6aSmrg # Check for POSIX incompatibilities with -m. 357414cce6aSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358414cce6aSmrg # other-writable bit of parent directory when it shouldn't. 359414cce6aSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360414cce6aSmrg test_tmpdir="$tmpdir/a" 361414cce6aSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362414cce6aSmrg case $ls_ld_tmpdir in 363414cce6aSmrg d????-?r-*) different_mode=700;; 364414cce6aSmrg d????-?--*) different_mode=755;; 365414cce6aSmrg *) false;; 366414cce6aSmrg esac && 367414cce6aSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368414cce6aSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369414cce6aSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370414cce6aSmrg } 371414cce6aSmrg } 372414cce6aSmrg then posix_mkdir=: 373414cce6aSmrg fi 374414cce6aSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375ded1caa4Smrg else 376414cce6aSmrg # Remove any dirs left behind by ancient mkdir implementations. 377414cce6aSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378ded1caa4Smrg fi 379414cce6aSmrg trap '' 0;; 38050539131Smrg esac 381ded1caa4Smrg 38250539131Smrg if 38350539131Smrg $posix_mkdir && ( 384414cce6aSmrg umask $mkdir_umask && 385414cce6aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 38650539131Smrg ) 38750539131Smrg then : 38850539131Smrg else 38950539131Smrg 390414cce6aSmrg # mkdir does not conform to POSIX, 39150539131Smrg # or it failed possibly due to a race condition. Create the 39250539131Smrg # directory the slow way, step by step, checking for races as we go. 39350539131Smrg 39450539131Smrg case $dstdir in 395414cce6aSmrg /*) prefix='/';; 396414cce6aSmrg [-=\(\)!]*) prefix='./';; 397414cce6aSmrg *) prefix='';; 39850539131Smrg esac 39950539131Smrg 40050539131Smrg oIFS=$IFS 40150539131Smrg IFS=/ 402414cce6aSmrg set -f 40350539131Smrg set fnord $dstdir 40450539131Smrg shift 405414cce6aSmrg set +f 40650539131Smrg IFS=$oIFS 40750539131Smrg 40850539131Smrg prefixes= 40950539131Smrg 41050539131Smrg for d 41150539131Smrg do 412414cce6aSmrg test X"$d" = X && continue 413414cce6aSmrg 414414cce6aSmrg prefix=$prefix$d 415414cce6aSmrg if test -d "$prefix"; then 416414cce6aSmrg prefixes= 417414cce6aSmrg else 418414cce6aSmrg if $posix_mkdir; then 419414cce6aSmrg (umask $mkdir_umask && 420414cce6aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421414cce6aSmrg # Don't fail if two instances are running concurrently. 422414cce6aSmrg test -d "$prefix" || exit 1 423414cce6aSmrg else 424414cce6aSmrg case $prefix in 425414cce6aSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426414cce6aSmrg *) qprefix=$prefix;; 427414cce6aSmrg esac 428414cce6aSmrg prefixes="$prefixes '$qprefix'" 429414cce6aSmrg fi 430414cce6aSmrg fi 431414cce6aSmrg prefix=$prefix/ 43250539131Smrg done 43350539131Smrg 43450539131Smrg if test -n "$prefixes"; then 435414cce6aSmrg # Don't fail if two instances are running concurrently. 436414cce6aSmrg (umask $mkdir_umask && 437414cce6aSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 438414cce6aSmrg test -d "$dstdir" || exit 1 439414cce6aSmrg obsolete_mkdir_used=true 44050539131Smrg fi 44150539131Smrg fi 44250539131Smrg fi 44350539131Smrg 44450539131Smrg if test -n "$dir_arg"; then 44550539131Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 44650539131Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 44750539131Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 44850539131Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 44950539131Smrg else 45050539131Smrg 45150539131Smrg # Make a couple of temp file names in the proper directory. 452414cce6aSmrg dsttmp=${dstdirslash}_inst.$$_ 453414cce6aSmrg rmtmp=${dstdirslash}_rm.$$_ 45450539131Smrg 45550539131Smrg # Trap to clean up those temp files at exit. 45650539131Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 45750539131Smrg 45850539131Smrg # Copy the file name to the temp name. 459414cce6aSmrg (umask $cp_umask && 460414cce6aSmrg { test -z "$stripcmd" || { 461414cce6aSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462414cce6aSmrg # which would cause strip to fail. 463414cce6aSmrg if test -z "$doit"; then 464414cce6aSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 465414cce6aSmrg else 466414cce6aSmrg $doit touch "$dsttmp" 467414cce6aSmrg fi 468414cce6aSmrg } 469414cce6aSmrg } && 470414cce6aSmrg $doit_exec $cpprog "$src" "$dsttmp") && 47150539131Smrg 47250539131Smrg # and set any options; do chmod last to preserve setuid bits. 47350539131Smrg # 47450539131Smrg # If any of these fail, we abort the whole thing. If we want to 47550539131Smrg # ignore errors from any of these, just make sure not to ignore 47650539131Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 47750539131Smrg # 47850539131Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 47950539131Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 48050539131Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 48150539131Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 48250539131Smrg 48350539131Smrg # If -C, don't bother to copy if it wouldn't change the file. 48450539131Smrg if $copy_on_change && 485414cce6aSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486414cce6aSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487414cce6aSmrg set -f && 48850539131Smrg set X $old && old=:$2:$4:$5:$6 && 48950539131Smrg set X $new && new=:$2:$4:$5:$6 && 490414cce6aSmrg set +f && 49150539131Smrg test "$old" = "$new" && 49250539131Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 49350539131Smrg then 49450539131Smrg rm -f "$dsttmp" 49550539131Smrg else 496414cce6aSmrg # If $backupsuffix is set, and the file being installed 497414cce6aSmrg # already exists, attempt a backup. Don't worry if it fails, 498414cce6aSmrg # e.g., if mv doesn't support -f. 499414cce6aSmrg if test -n "$backupsuffix" && test -f "$dst"; then 500414cce6aSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501414cce6aSmrg fi 502414cce6aSmrg 50350539131Smrg # Rename the file to the real destination. 50450539131Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 50550539131Smrg 50650539131Smrg # The rename failed, perhaps because mv can't rename something else 50750539131Smrg # to itself, or perhaps because mv is so ancient that it does not 50850539131Smrg # support -f. 50950539131Smrg { 510414cce6aSmrg # Now remove or move aside any old file at destination location. 511414cce6aSmrg # We try this two ways since rm can't unlink itself on some 512414cce6aSmrg # systems and the destination file might be busy for other 513414cce6aSmrg # reasons. In this case, the final cleanup might fail but the new 514414cce6aSmrg # file should still install successfully. 515414cce6aSmrg { 516414cce6aSmrg test ! -f "$dst" || 517414cce6aSmrg $doit $rmcmd "$dst" 2>/dev/null || 518414cce6aSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519414cce6aSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520414cce6aSmrg } || 521414cce6aSmrg { echo "$0: cannot unlink or rename $dst" >&2 522414cce6aSmrg (exit 1); exit 1 523414cce6aSmrg } 524414cce6aSmrg } && 525414cce6aSmrg 526414cce6aSmrg # Now rename the file to the real destination. 527414cce6aSmrg $doit $mvcmd "$dsttmp" "$dst" 52850539131Smrg } 52950539131Smrg fi || exit 1 53050539131Smrg 53150539131Smrg trap '' 0 53250539131Smrg fi 53350539131Smrgdone 534ded1caa4Smrg 53550539131Smrg# Local variables: 536414cce6aSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 53750539131Smrg# time-stamp-start: "scriptversion=" 53850539131Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539414cce6aSmrg# time-stamp-time-zone: "UTC0" 54050539131Smrg# time-stamp-end: "; # UTC" 54150539131Smrg# End: 542