install-sh revision 7cea3689
127702724Smrg#!/bin/sh 227702724Smrg# install - install a program, script, or datafile 327702724Smrg 47cea3689Smrgscriptversion=2013-12-25.23; # UTC 527702724Smrg 627702724Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 727702724Smrg# later released in X11R6 (xc/config/util/install.sh) with the 827702724Smrg# following copyright and license. 927702724Smrg# 1027702724Smrg# Copyright (C) 1994 X Consortium 1127702724Smrg# 1227702724Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1327702724Smrg# of this software and associated documentation files (the "Software"), to 1427702724Smrg# deal in the Software without restriction, including without limitation the 1527702724Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1627702724Smrg# sell copies of the Software, and to permit persons to whom the Software is 1727702724Smrg# furnished to do so, subject to the following conditions: 1827702724Smrg# 1927702724Smrg# The above copyright notice and this permission notice shall be included in 2027702724Smrg# all copies or substantial portions of the Software. 2127702724Smrg# 2227702724Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2327702724Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2427702724Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2527702724Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2627702724Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2727702724Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2827702724Smrg# 2927702724Smrg# Except as contained in this notice, the name of the X Consortium shall not 3027702724Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3127702724Smrg# ings in this Software without prior written authorization from the X Consor- 3227702724Smrg# tium. 3327702724Smrg# 3427702724Smrg# 3527702724Smrg# FSF changes to this file are in the public domain. 3627702724Smrg# 3727702724Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38313a12fdSmrg# 'make' implicit rules from creating a file called install from it 3927702724Smrg# when there is no Makefile. 4027702724Smrg# 4127702724Smrg# This script is compatible with the BSD install script, but was written 42e19dfac4Smrg# from scratch. 43e19dfac4Smrg 447cea3689Smrgtab=' ' 45e19dfac4Smrgnl=' 46e19dfac4Smrg' 477cea3689SmrgIFS=" $tab$nl" 4827702724Smrg 497cea3689Smrg# Set DOITPROG to "echo" to test this script. 5027702724Smrg 51e19dfac4Smrgdoit=${DOITPROG-} 527cea3689Smrgdoit_exec=${doit:-exec} 5327702724Smrg 54e19dfac4Smrg# Put in absolute file names if you don't have them in your path; 55e19dfac4Smrg# or use environment vars. 56e19dfac4Smrg 57e19dfac4Smrgchgrpprog=${CHGRPPROG-chgrp} 58e19dfac4Smrgchmodprog=${CHMODPROG-chmod} 59e19dfac4Smrgchownprog=${CHOWNPROG-chown} 60e19dfac4Smrgcmpprog=${CMPPROG-cmp} 61e19dfac4Smrgcpprog=${CPPROG-cp} 62e19dfac4Smrgmkdirprog=${MKDIRPROG-mkdir} 63e19dfac4Smrgmvprog=${MVPROG-mv} 64e19dfac4Smrgrmprog=${RMPROG-rm} 65e19dfac4Smrgstripprog=${STRIPPROG-strip} 66e19dfac4Smrg 67e19dfac4Smrgposix_mkdir= 68e19dfac4Smrg 69e19dfac4Smrg# Desired mode of installed file. 70e19dfac4Smrgmode=0755 7127702724Smrg 7227702724Smrgchgrpcmd= 73e19dfac4Smrgchmodcmd=$chmodprog 74e19dfac4Smrgchowncmd= 75e19dfac4Smrgmvcmd=$mvprog 7627702724Smrgrmcmd="$rmprog -f" 77e19dfac4Smrgstripcmd= 78e19dfac4Smrg 7927702724Smrgsrc= 8027702724Smrgdst= 8127702724Smrgdir_arg= 82e19dfac4Smrgdst_arg= 83e19dfac4Smrg 84e19dfac4Smrgcopy_on_change=false 857cea3689Smrgis_target_a_directory=possibly 8627702724Smrg 87e19dfac4Smrgusage="\ 88e19dfac4SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 8927702724Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 9027702724Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9127702724Smrg or: $0 [OPTION]... -d DIRECTORIES... 9227702724Smrg 9327702724SmrgIn the 1st form, copy SRCFILE to DSTFILE. 9427702724SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 9527702724SmrgIn the 4th, create DIRECTORIES. 9627702724Smrg 9727702724SmrgOptions: 98e19dfac4Smrg --help display this help and exit. 99e19dfac4Smrg --version display version info and exit. 100e19dfac4Smrg 101e19dfac4Smrg -c (ignored) 102e19dfac4Smrg -C install only if different (preserve the last data modification time) 103e19dfac4Smrg -d create directories instead of installing files. 104e19dfac4Smrg -g GROUP $chgrpprog installed files to GROUP. 105e19dfac4Smrg -m MODE $chmodprog installed files to MODE. 106e19dfac4Smrg -o USER $chownprog installed files to USER. 107e19dfac4Smrg -s $stripprog installed files. 108e19dfac4Smrg -t DIRECTORY install into DIRECTORY. 109e19dfac4Smrg -T report an error if DSTFILE is a directory. 11027702724Smrg 11127702724SmrgEnvironment variables override the default commands: 112e19dfac4Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113e19dfac4Smrg RMPROG STRIPPROG 11427702724Smrg" 11527702724Smrg 116e19dfac4Smrgwhile test $# -ne 0; do 11727702724Smrg case $1 in 118e19dfac4Smrg -c) ;; 119e19dfac4Smrg 120e19dfac4Smrg -C) copy_on_change=true;; 12127702724Smrg 122e19dfac4Smrg -d) dir_arg=true;; 12327702724Smrg 12427702724Smrg -g) chgrpcmd="$chgrpprog $2" 1257cea3689Smrg shift;; 12627702724Smrg 12727702724Smrg --help) echo "$usage"; exit $?;; 12827702724Smrg 129e19dfac4Smrg -m) mode=$2 1307cea3689Smrg case $mode in 1317cea3689Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1327cea3689Smrg echo "$0: invalid mode: $mode" >&2 1337cea3689Smrg exit 1;; 1347cea3689Smrg esac 1357cea3689Smrg shift;; 13627702724Smrg 13727702724Smrg -o) chowncmd="$chownprog $2" 1387cea3689Smrg shift;; 13927702724Smrg 140e19dfac4Smrg -s) stripcmd=$stripprog;; 14127702724Smrg 1427cea3689Smrg -t) 1437cea3689Smrg is_target_a_directory=always 1447cea3689Smrg dst_arg=$2 1457cea3689Smrg # Protect names problematic for 'test' and other utilities. 1467cea3689Smrg case $dst_arg in 1477cea3689Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1487cea3689Smrg esac 1497cea3689Smrg shift;; 15027702724Smrg 1517cea3689Smrg -T) is_target_a_directory=never;; 15227702724Smrg 15327702724Smrg --version) echo "$0 $scriptversion"; exit $?;; 15427702724Smrg 1557cea3689Smrg --) shift 1567cea3689Smrg break;; 157e19dfac4Smrg 1587cea3689Smrg -*) echo "$0: invalid option: $1" >&2 1597cea3689Smrg exit 1;; 160e19dfac4Smrg 161e19dfac4Smrg *) break;; 16227702724Smrg esac 163e19dfac4Smrg shift 16427702724Smrgdone 16527702724Smrg 1667cea3689Smrg# We allow the use of options -d and -T together, by making -d 1677cea3689Smrg# take the precedence; this is for compatibility with GNU install. 1687cea3689Smrg 1697cea3689Smrgif test -n "$dir_arg"; then 1707cea3689Smrg if test -n "$dst_arg"; then 1717cea3689Smrg echo "$0: target directory not allowed when installing a directory." >&2 1727cea3689Smrg exit 1 1737cea3689Smrg fi 1747cea3689Smrgfi 1757cea3689Smrg 176e19dfac4Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177e19dfac4Smrg # When -d is used, all remaining arguments are directories to create. 178e19dfac4Smrg # When -t is used, the destination is already specified. 179e19dfac4Smrg # Otherwise, the last argument is the destination. Remove it from $@. 180e19dfac4Smrg for arg 181e19dfac4Smrg do 182e19dfac4Smrg if test -n "$dst_arg"; then 183e19dfac4Smrg # $@ is not empty: it contains at least $arg. 184e19dfac4Smrg set fnord "$@" "$dst_arg" 185e19dfac4Smrg shift # fnord 186e19dfac4Smrg fi 187e19dfac4Smrg shift # arg 188e19dfac4Smrg dst_arg=$arg 189313a12fdSmrg # Protect names problematic for 'test' and other utilities. 190313a12fdSmrg case $dst_arg in 191313a12fdSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192313a12fdSmrg esac 193e19dfac4Smrg done 194e19dfac4Smrgfi 195e19dfac4Smrg 196e19dfac4Smrgif test $# -eq 0; then 19727702724Smrg if test -z "$dir_arg"; then 19827702724Smrg echo "$0: no input file specified." >&2 19927702724Smrg exit 1 20027702724Smrg fi 201313a12fdSmrg # It's OK to call 'install-sh -d' without argument. 20227702724Smrg # This can happen when creating conditional directories. 20327702724Smrg exit 0 20427702724Smrgfi 20527702724Smrg 2067cea3689Smrgif test -z "$dir_arg"; then 2077cea3689Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2087cea3689Smrg if test ! -d "$dst_arg"; then 2097cea3689Smrg echo "$0: $dst_arg: Is not a directory." >&2 2107cea3689Smrg exit 1 2117cea3689Smrg fi 2127cea3689Smrg fi 2137cea3689Smrgfi 2147cea3689Smrg 215e19dfac4Smrgif test -z "$dir_arg"; then 216313a12fdSmrg do_exit='(exit $ret); exit $ret' 217313a12fdSmrg trap "ret=129; $do_exit" 1 218313a12fdSmrg trap "ret=130; $do_exit" 2 219313a12fdSmrg trap "ret=141; $do_exit" 13 220313a12fdSmrg trap "ret=143; $do_exit" 15 221e19dfac4Smrg 222e19dfac4Smrg # Set umask so as not to create temps with too-generous modes. 223e19dfac4Smrg # However, 'strip' requires both read and write access to temps. 224e19dfac4Smrg case $mode in 225e19dfac4Smrg # Optimize common cases. 226e19dfac4Smrg *644) cp_umask=133;; 227e19dfac4Smrg *755) cp_umask=22;; 228e19dfac4Smrg 229e19dfac4Smrg *[0-7]) 230e19dfac4Smrg if test -z "$stripcmd"; then 2317cea3689Smrg u_plus_rw= 232e19dfac4Smrg else 2337cea3689Smrg u_plus_rw='% 200' 234e19dfac4Smrg fi 235e19dfac4Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236e19dfac4Smrg *) 237e19dfac4Smrg if test -z "$stripcmd"; then 2387cea3689Smrg u_plus_rw= 239e19dfac4Smrg else 2407cea3689Smrg u_plus_rw=,u+rw 241e19dfac4Smrg fi 242e19dfac4Smrg cp_umask=$mode$u_plus_rw;; 243e19dfac4Smrg esac 244e19dfac4Smrgfi 245e19dfac4Smrg 24627702724Smrgfor src 24727702724Smrgdo 248313a12fdSmrg # Protect names problematic for 'test' and other utilities. 24927702724Smrg case $src in 250313a12fdSmrg -* | [=\(\)!]) src=./$src;; 25127702724Smrg esac 25227702724Smrg 25327702724Smrg if test -n "$dir_arg"; then 25427702724Smrg dst=$src 255e19dfac4Smrg dstdir=$dst 256e19dfac4Smrg test -d "$dstdir" 257e19dfac4Smrg dstdir_status=$? 25827702724Smrg else 259e19dfac4Smrg 26027702724Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 26127702724Smrg # might cause directories to be created, which would be especially bad 26227702724Smrg # if $src (and thus $dsttmp) contains '*'. 26327702724Smrg if test ! -f "$src" && test ! -d "$src"; then 26427702724Smrg echo "$0: $src does not exist." >&2 26527702724Smrg exit 1 26627702724Smrg fi 26727702724Smrg 268e19dfac4Smrg if test -z "$dst_arg"; then 26927702724Smrg echo "$0: no destination specified." >&2 27027702724Smrg exit 1 27127702724Smrg fi 272e19dfac4Smrg dst=$dst_arg 27327702724Smrg 27427702724Smrg # If destination is a directory, append the input filename; won't work 27527702724Smrg # if double slashes aren't ignored. 27627702724Smrg if test -d "$dst"; then 2777cea3689Smrg if test "$is_target_a_directory" = never; then 2787cea3689Smrg echo "$0: $dst_arg: Is a directory" >&2 2797cea3689Smrg exit 1 28027702724Smrg fi 281e19dfac4Smrg dstdir=$dst 282e19dfac4Smrg dst=$dstdir/`basename "$src"` 283e19dfac4Smrg dstdir_status=0 284e19dfac4Smrg else 2857cea3689Smrg dstdir=`dirname "$dst"` 286e19dfac4Smrg test -d "$dstdir" 287e19dfac4Smrg dstdir_status=$? 28827702724Smrg fi 28927702724Smrg fi 29027702724Smrg 291e19dfac4Smrg obsolete_mkdir_used=false 292e19dfac4Smrg 293e19dfac4Smrg if test $dstdir_status != 0; then 294e19dfac4Smrg case $posix_mkdir in 295e19dfac4Smrg '') 2967cea3689Smrg # Create intermediate dirs using mode 755 as modified by the umask. 2977cea3689Smrg # This is like FreeBSD 'install' as of 1997-10-28. 2987cea3689Smrg umask=`umask` 2997cea3689Smrg case $stripcmd.$umask in 3007cea3689Smrg # Optimize common cases. 3017cea3689Smrg *[2367][2367]) mkdir_umask=$umask;; 3027cea3689Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3037cea3689Smrg 3047cea3689Smrg *[0-7]) 3057cea3689Smrg mkdir_umask=`expr $umask + 22 \ 3067cea3689Smrg - $umask % 100 % 40 + $umask % 20 \ 3077cea3689Smrg - $umask % 10 % 4 + $umask % 2 3087cea3689Smrg `;; 3097cea3689Smrg *) mkdir_umask=$umask,go-w;; 3107cea3689Smrg esac 3117cea3689Smrg 3127cea3689Smrg # With -d, create the new directory with the user-specified mode. 3137cea3689Smrg # Otherwise, rely on $mkdir_umask. 3147cea3689Smrg if test -n "$dir_arg"; then 3157cea3689Smrg mkdir_mode=-m$mode 3167cea3689Smrg else 3177cea3689Smrg mkdir_mode= 3187cea3689Smrg fi 3197cea3689Smrg 3207cea3689Smrg posix_mkdir=false 3217cea3689Smrg case $umask in 3227cea3689Smrg *[123567][0-7][0-7]) 3237cea3689Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3247cea3689Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3257cea3689Smrg ;; 3267cea3689Smrg *) 3277cea3689Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3287cea3689Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3297cea3689Smrg 3307cea3689Smrg if (umask $mkdir_umask && 3317cea3689Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3327cea3689Smrg then 3337cea3689Smrg if test -z "$dir_arg" || { 3347cea3689Smrg # Check for POSIX incompatibilities with -m. 3357cea3689Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3367cea3689Smrg # other-writable bit of parent directory when it shouldn't. 3377cea3689Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3387cea3689Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3397cea3689Smrg case $ls_ld_tmpdir in 3407cea3689Smrg d????-?r-*) different_mode=700;; 3417cea3689Smrg d????-?--*) different_mode=755;; 3427cea3689Smrg *) false;; 3437cea3689Smrg esac && 3447cea3689Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3457cea3689Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3467cea3689Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3477cea3689Smrg } 3487cea3689Smrg } 3497cea3689Smrg then posix_mkdir=: 3507cea3689Smrg fi 3517cea3689Smrg rmdir "$tmpdir/d" "$tmpdir" 3527cea3689Smrg else 3537cea3689Smrg # Remove any dirs left behind by ancient mkdir implementations. 3547cea3689Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3557cea3689Smrg fi 3567cea3689Smrg trap '' 0;; 3577cea3689Smrg esac;; 358e19dfac4Smrg esac 35927702724Smrg 360e19dfac4Smrg if 361e19dfac4Smrg $posix_mkdir && ( 3627cea3689Smrg umask $mkdir_umask && 3637cea3689Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 364e19dfac4Smrg ) 365e19dfac4Smrg then : 366e19dfac4Smrg else 36727702724Smrg 368e19dfac4Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 369e19dfac4Smrg # or it failed possibly due to a race condition. Create the 370e19dfac4Smrg # directory the slow way, step by step, checking for races as we go. 37127702724Smrg 372e19dfac4Smrg case $dstdir in 3737cea3689Smrg /*) prefix='/';; 3747cea3689Smrg [-=\(\)!]*) prefix='./';; 3757cea3689Smrg *) prefix='';; 376e19dfac4Smrg esac 37727702724Smrg 378e19dfac4Smrg oIFS=$IFS 379e19dfac4Smrg IFS=/ 3807cea3689Smrg set -f 381e19dfac4Smrg set fnord $dstdir 38227702724Smrg shift 3837cea3689Smrg set +f 384e19dfac4Smrg IFS=$oIFS 385e19dfac4Smrg 386e19dfac4Smrg prefixes= 387e19dfac4Smrg 388e19dfac4Smrg for d 389e19dfac4Smrg do 3907cea3689Smrg test X"$d" = X && continue 3917cea3689Smrg 3927cea3689Smrg prefix=$prefix$d 3937cea3689Smrg if test -d "$prefix"; then 3947cea3689Smrg prefixes= 3957cea3689Smrg else 3967cea3689Smrg if $posix_mkdir; then 3977cea3689Smrg (umask=$mkdir_umask && 3987cea3689Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 3997cea3689Smrg # Don't fail if two instances are running concurrently. 4007cea3689Smrg test -d "$prefix" || exit 1 4017cea3689Smrg else 4027cea3689Smrg case $prefix in 4037cea3689Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4047cea3689Smrg *) qprefix=$prefix;; 4057cea3689Smrg esac 4067cea3689Smrg prefixes="$prefixes '$qprefix'" 4077cea3689Smrg fi 4087cea3689Smrg fi 4097cea3689Smrg prefix=$prefix/ 410e19dfac4Smrg done 411e19dfac4Smrg 412e19dfac4Smrg if test -n "$prefixes"; then 4137cea3689Smrg # Don't fail if two instances are running concurrently. 4147cea3689Smrg (umask $mkdir_umask && 4157cea3689Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4167cea3689Smrg test -d "$dstdir" || exit 1 4177cea3689Smrg obsolete_mkdir_used=true 41827702724Smrg fi 419e19dfac4Smrg fi 42027702724Smrg fi 42127702724Smrg 42227702724Smrg if test -n "$dir_arg"; then 423e19dfac4Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 424e19dfac4Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 425e19dfac4Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 426e19dfac4Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 42727702724Smrg else 42827702724Smrg 42927702724Smrg # Make a couple of temp file names in the proper directory. 43027702724Smrg dsttmp=$dstdir/_inst.$$_ 43127702724Smrg rmtmp=$dstdir/_rm.$$_ 43227702724Smrg 43327702724Smrg # Trap to clean up those temp files at exit. 43427702724Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 43527702724Smrg 43627702724Smrg # Copy the file name to the temp name. 437e19dfac4Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 43827702724Smrg 43927702724Smrg # and set any options; do chmod last to preserve setuid bits. 44027702724Smrg # 44127702724Smrg # If any of these fail, we abort the whole thing. If we want to 44227702724Smrg # ignore errors from any of these, just make sure not to ignore 44327702724Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 44427702724Smrg # 445e19dfac4Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 446e19dfac4Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 447e19dfac4Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 448e19dfac4Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 449e19dfac4Smrg 450e19dfac4Smrg # If -C, don't bother to copy if it wouldn't change the file. 451e19dfac4Smrg if $copy_on_change && 4527cea3689Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4537cea3689Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4547cea3689Smrg set -f && 455e19dfac4Smrg set X $old && old=:$2:$4:$5:$6 && 456e19dfac4Smrg set X $new && new=:$2:$4:$5:$6 && 4577cea3689Smrg set +f && 458e19dfac4Smrg test "$old" = "$new" && 459e19dfac4Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 460e19dfac4Smrg then 461e19dfac4Smrg rm -f "$dsttmp" 462e19dfac4Smrg else 463e19dfac4Smrg # Rename the file to the real destination. 464e19dfac4Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 465e19dfac4Smrg 466e19dfac4Smrg # The rename failed, perhaps because mv can't rename something else 467e19dfac4Smrg # to itself, or perhaps because mv is so ancient that it does not 468e19dfac4Smrg # support -f. 469e19dfac4Smrg { 4707cea3689Smrg # Now remove or move aside any old file at destination location. 4717cea3689Smrg # We try this two ways since rm can't unlink itself on some 4727cea3689Smrg # systems and the destination file might be busy for other 4737cea3689Smrg # reasons. In this case, the final cleanup might fail but the new 4747cea3689Smrg # file should still install successfully. 4757cea3689Smrg { 4767cea3689Smrg test ! -f "$dst" || 4777cea3689Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 4787cea3689Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 4797cea3689Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 4807cea3689Smrg } || 4817cea3689Smrg { echo "$0: cannot unlink or rename $dst" >&2 4827cea3689Smrg (exit 1); exit 1 4837cea3689Smrg } 4847cea3689Smrg } && 4857cea3689Smrg 4867cea3689Smrg # Now rename the file to the real destination. 4877cea3689Smrg $doit $mvcmd "$dsttmp" "$dst" 488e19dfac4Smrg } 489e19dfac4Smrg fi || exit 1 490e19dfac4Smrg 491e19dfac4Smrg trap '' 0 492e19dfac4Smrg fi 49327702724Smrgdone 49427702724Smrg 49527702724Smrg# Local variables: 49627702724Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 49727702724Smrg# time-stamp-start: "scriptversion=" 49827702724Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 49900084f2cSmrg# time-stamp-time-zone: "UTC" 50000084f2cSmrg# time-stamp-end: "; # UTC" 50127702724Smrg# End: 502