install-sh revision 04449c54
18440cca4Smrg#!/bin/sh 28440cca4Smrg# install - install a program, script, or datafile 3d1c293acSmrg 404449c54Smrgscriptversion=2013-12-25.23; # UTC 5d1c293acSmrg 68440cca4Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 78440cca4Smrg# later released in X11R6 (xc/config/util/install.sh) with the 88440cca4Smrg# following copyright and license. 98440cca4Smrg# 108440cca4Smrg# Copyright (C) 1994 X Consortium 118440cca4Smrg# 128440cca4Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 138440cca4Smrg# of this software and associated documentation files (the "Software"), to 148440cca4Smrg# deal in the Software without restriction, including without limitation the 158440cca4Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 168440cca4Smrg# sell copies of the Software, and to permit persons to whom the Software is 178440cca4Smrg# furnished to do so, subject to the following conditions: 188440cca4Smrg# 198440cca4Smrg# The above copyright notice and this permission notice shall be included in 208440cca4Smrg# all copies or substantial portions of the Software. 218440cca4Smrg# 228440cca4Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 238440cca4Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 248440cca4Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 258440cca4Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 268440cca4Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 278440cca4Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 288440cca4Smrg# 298440cca4Smrg# Except as contained in this notice, the name of the X Consortium shall not 308440cca4Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 318440cca4Smrg# ings in this Software without prior written authorization from the X Consor- 328440cca4Smrg# tium. 338440cca4Smrg# 348440cca4Smrg# 358440cca4Smrg# FSF changes to this file are in the public domain. 368440cca4Smrg# 378440cca4Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3804449c54Smrg# 'make' implicit rules from creating a file called install from it 398440cca4Smrg# when there is no Makefile. 408440cca4Smrg# 418440cca4Smrg# This script is compatible with the BSD install script, but was written 42d1c293acSmrg# from scratch. 438440cca4Smrg 4404449c54Smrgtab=' ' 45d1c293acSmrgnl=' 46d1c293acSmrg' 4704449c54SmrgIFS=" $tab$nl" 488440cca4Smrg 4904449c54Smrg# Set DOITPROG to "echo" to test this script. 508440cca4Smrg 51d1c293acSmrgdoit=${DOITPROG-} 5204449c54Smrgdoit_exec=${doit:-exec} 538440cca4Smrg 54d1c293acSmrg# Put in absolute file names if you don't have them in your path; 55d1c293acSmrg# or use environment vars. 56d1c293acSmrg 57d1c293acSmrgchgrpprog=${CHGRPPROG-chgrp} 58d1c293acSmrgchmodprog=${CHMODPROG-chmod} 59d1c293acSmrgchownprog=${CHOWNPROG-chown} 60d1c293acSmrgcmpprog=${CMPPROG-cmp} 61d1c293acSmrgcpprog=${CPPROG-cp} 62d1c293acSmrgmkdirprog=${MKDIRPROG-mkdir} 63d1c293acSmrgmvprog=${MVPROG-mv} 64d1c293acSmrgrmprog=${RMPROG-rm} 65d1c293acSmrgstripprog=${STRIPPROG-strip} 66d1c293acSmrg 67d1c293acSmrgposix_mkdir= 68d1c293acSmrg 69d1c293acSmrg# Desired mode of installed file. 70d1c293acSmrgmode=0755 71d1c293acSmrg 72d1c293acSmrgchgrpcmd= 73d1c293acSmrgchmodcmd=$chmodprog 74d1c293acSmrgchowncmd= 75d1c293acSmrgmvcmd=$mvprog 76d1c293acSmrgrmcmd="$rmprog -f" 77d1c293acSmrgstripcmd= 788440cca4Smrg 79d1c293acSmrgsrc= 80d1c293acSmrgdst= 81d1c293acSmrgdir_arg= 82d1c293acSmrgdst_arg= 838440cca4Smrg 84d1c293acSmrgcopy_on_change=false 8504449c54Smrgis_target_a_directory=possibly 868440cca4Smrg 87d1c293acSmrgusage="\ 88d1c293acSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89d1c293acSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90d1c293acSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91d1c293acSmrg or: $0 [OPTION]... -d DIRECTORIES... 928440cca4Smrg 93d1c293acSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94d1c293acSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95d1c293acSmrgIn the 4th, create DIRECTORIES. 968440cca4Smrg 97d1c293acSmrgOptions: 98d1c293acSmrg --help display this help and exit. 99d1c293acSmrg --version display version info and exit. 1008440cca4Smrg 101d1c293acSmrg -c (ignored) 102d1c293acSmrg -C install only if different (preserve the last data modification time) 103d1c293acSmrg -d create directories instead of installing files. 104d1c293acSmrg -g GROUP $chgrpprog installed files to GROUP. 105d1c293acSmrg -m MODE $chmodprog installed files to MODE. 106d1c293acSmrg -o USER $chownprog installed files to USER. 107d1c293acSmrg -s $stripprog installed files. 108d1c293acSmrg -t DIRECTORY install into DIRECTORY. 109d1c293acSmrg -T report an error if DSTFILE is a directory. 1108440cca4Smrg 111d1c293acSmrgEnvironment variables override the default commands: 112d1c293acSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113d1c293acSmrg RMPROG STRIPPROG 114d1c293acSmrg" 1158440cca4Smrg 116d1c293acSmrgwhile test $# -ne 0; do 117d1c293acSmrg case $1 in 118d1c293acSmrg -c) ;; 1198440cca4Smrg 120d1c293acSmrg -C) copy_on_change=true;; 1218440cca4Smrg 122d1c293acSmrg -d) dir_arg=true;; 1238440cca4Smrg 124d1c293acSmrg -g) chgrpcmd="$chgrpprog $2" 12504449c54Smrg shift;; 1268440cca4Smrg 127d1c293acSmrg --help) echo "$usage"; exit $?;; 1288440cca4Smrg 129d1c293acSmrg -m) mode=$2 13004449c54Smrg case $mode in 13104449c54Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 13204449c54Smrg echo "$0: invalid mode: $mode" >&2 13304449c54Smrg exit 1;; 13404449c54Smrg esac 13504449c54Smrg shift;; 1368440cca4Smrg 137d1c293acSmrg -o) chowncmd="$chownprog $2" 13804449c54Smrg shift;; 1398440cca4Smrg 140d1c293acSmrg -s) stripcmd=$stripprog;; 1418440cca4Smrg 14204449c54Smrg -t) 14304449c54Smrg is_target_a_directory=always 14404449c54Smrg dst_arg=$2 14504449c54Smrg # Protect names problematic for 'test' and other utilities. 14604449c54Smrg case $dst_arg in 14704449c54Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 14804449c54Smrg esac 14904449c54Smrg shift;; 1508440cca4Smrg 15104449c54Smrg -T) is_target_a_directory=never;; 1528440cca4Smrg 153d1c293acSmrg --version) echo "$0 $scriptversion"; exit $?;; 1548440cca4Smrg 15504449c54Smrg --) shift 15604449c54Smrg break;; 1578440cca4Smrg 15804449c54Smrg -*) echo "$0: invalid option: $1" >&2 15904449c54Smrg exit 1;; 1608440cca4Smrg 161d1c293acSmrg *) break;; 162d1c293acSmrg esac 163d1c293acSmrg shift 164d1c293acSmrgdone 1658440cca4Smrg 16604449c54Smrg# We allow the use of options -d and -T together, by making -d 16704449c54Smrg# take the precedence; this is for compatibility with GNU install. 16804449c54Smrg 16904449c54Smrgif test -n "$dir_arg"; then 17004449c54Smrg if test -n "$dst_arg"; then 17104449c54Smrg echo "$0: target directory not allowed when installing a directory." >&2 17204449c54Smrg exit 1 17304449c54Smrg fi 17404449c54Smrgfi 17504449c54Smrg 176d1c293acSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177d1c293acSmrg # When -d is used, all remaining arguments are directories to create. 178d1c293acSmrg # When -t is used, the destination is already specified. 179d1c293acSmrg # Otherwise, the last argument is the destination. Remove it from $@. 180d1c293acSmrg for arg 181d1c293acSmrg do 182d1c293acSmrg if test -n "$dst_arg"; then 183d1c293acSmrg # $@ is not empty: it contains at least $arg. 184d1c293acSmrg set fnord "$@" "$dst_arg" 185d1c293acSmrg shift # fnord 186d1c293acSmrg fi 187d1c293acSmrg shift # arg 188d1c293acSmrg dst_arg=$arg 18904449c54Smrg # Protect names problematic for 'test' and other utilities. 19020915927Smrg case $dst_arg in 19120915927Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 19220915927Smrg esac 193d1c293acSmrg done 194d1c293acSmrgfi 1958440cca4Smrg 196d1c293acSmrgif test $# -eq 0; then 197d1c293acSmrg if test -z "$dir_arg"; then 198d1c293acSmrg echo "$0: no input file specified." >&2 199d1c293acSmrg exit 1 200d1c293acSmrg fi 20104449c54Smrg # It's OK to call 'install-sh -d' without argument. 202d1c293acSmrg # This can happen when creating conditional directories. 203d1c293acSmrg exit 0 204d1c293acSmrgfi 2058440cca4Smrg 20604449c54Smrgif test -z "$dir_arg"; then 20704449c54Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 20804449c54Smrg if test ! -d "$dst_arg"; then 20904449c54Smrg echo "$0: $dst_arg: Is not a directory." >&2 21004449c54Smrg exit 1 21104449c54Smrg fi 21204449c54Smrg fi 21304449c54Smrgfi 21404449c54Smrg 215d1c293acSmrgif test -z "$dir_arg"; then 21620915927Smrg do_exit='(exit $ret); exit $ret' 21720915927Smrg trap "ret=129; $do_exit" 1 21820915927Smrg trap "ret=130; $do_exit" 2 21920915927Smrg trap "ret=141; $do_exit" 13 22020915927Smrg trap "ret=143; $do_exit" 15 221d1c293acSmrg 222d1c293acSmrg # Set umask so as not to create temps with too-generous modes. 223d1c293acSmrg # However, 'strip' requires both read and write access to temps. 224d1c293acSmrg case $mode in 225d1c293acSmrg # Optimize common cases. 226d1c293acSmrg *644) cp_umask=133;; 227d1c293acSmrg *755) cp_umask=22;; 228d1c293acSmrg 229d1c293acSmrg *[0-7]) 230d1c293acSmrg if test -z "$stripcmd"; then 23104449c54Smrg u_plus_rw= 232d1c293acSmrg else 23304449c54Smrg u_plus_rw='% 200' 234d1c293acSmrg fi 235d1c293acSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236d1c293acSmrg *) 237d1c293acSmrg if test -z "$stripcmd"; then 23804449c54Smrg u_plus_rw= 239d1c293acSmrg else 24004449c54Smrg u_plus_rw=,u+rw 241d1c293acSmrg fi 242d1c293acSmrg cp_umask=$mode$u_plus_rw;; 243d1c293acSmrg esac 244d1c293acSmrgfi 2458440cca4Smrg 246d1c293acSmrgfor src 247d1c293acSmrgdo 24804449c54Smrg # Protect names problematic for 'test' and other utilities. 249d1c293acSmrg case $src in 25020915927Smrg -* | [=\(\)!]) src=./$src;; 251d1c293acSmrg esac 252d1c293acSmrg 253d1c293acSmrg if test -n "$dir_arg"; then 254d1c293acSmrg dst=$src 255d1c293acSmrg dstdir=$dst 256d1c293acSmrg test -d "$dstdir" 257d1c293acSmrg dstdir_status=$? 258d1c293acSmrg else 259d1c293acSmrg 260d1c293acSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261d1c293acSmrg # might cause directories to be created, which would be especially bad 262d1c293acSmrg # if $src (and thus $dsttmp) contains '*'. 263d1c293acSmrg if test ! -f "$src" && test ! -d "$src"; then 264d1c293acSmrg echo "$0: $src does not exist." >&2 265d1c293acSmrg exit 1 266d1c293acSmrg fi 267d1c293acSmrg 268d1c293acSmrg if test -z "$dst_arg"; then 269d1c293acSmrg echo "$0: no destination specified." >&2 270d1c293acSmrg exit 1 271d1c293acSmrg fi 272d1c293acSmrg dst=$dst_arg 2738440cca4Smrg 274d1c293acSmrg # If destination is a directory, append the input filename; won't work 275d1c293acSmrg # if double slashes aren't ignored. 276d1c293acSmrg if test -d "$dst"; then 27704449c54Smrg if test "$is_target_a_directory" = never; then 27804449c54Smrg echo "$0: $dst_arg: Is a directory" >&2 27904449c54Smrg exit 1 280d1c293acSmrg fi 281d1c293acSmrg dstdir=$dst 282d1c293acSmrg dst=$dstdir/`basename "$src"` 283d1c293acSmrg dstdir_status=0 284d1c293acSmrg else 28504449c54Smrg dstdir=`dirname "$dst"` 286d1c293acSmrg test -d "$dstdir" 287d1c293acSmrg dstdir_status=$? 288d1c293acSmrg fi 289d1c293acSmrg fi 290d1c293acSmrg 291d1c293acSmrg obsolete_mkdir_used=false 292d1c293acSmrg 293d1c293acSmrg if test $dstdir_status != 0; then 294d1c293acSmrg case $posix_mkdir in 295d1c293acSmrg '') 29604449c54Smrg # Create intermediate dirs using mode 755 as modified by the umask. 29704449c54Smrg # This is like FreeBSD 'install' as of 1997-10-28. 29804449c54Smrg umask=`umask` 29904449c54Smrg case $stripcmd.$umask in 30004449c54Smrg # Optimize common cases. 30104449c54Smrg *[2367][2367]) mkdir_umask=$umask;; 30204449c54Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 30304449c54Smrg 30404449c54Smrg *[0-7]) 30504449c54Smrg mkdir_umask=`expr $umask + 22 \ 30604449c54Smrg - $umask % 100 % 40 + $umask % 20 \ 30704449c54Smrg - $umask % 10 % 4 + $umask % 2 30804449c54Smrg `;; 30904449c54Smrg *) mkdir_umask=$umask,go-w;; 31004449c54Smrg esac 31104449c54Smrg 31204449c54Smrg # With -d, create the new directory with the user-specified mode. 31304449c54Smrg # Otherwise, rely on $mkdir_umask. 31404449c54Smrg if test -n "$dir_arg"; then 31504449c54Smrg mkdir_mode=-m$mode 31604449c54Smrg else 31704449c54Smrg mkdir_mode= 31804449c54Smrg fi 31904449c54Smrg 32004449c54Smrg posix_mkdir=false 32104449c54Smrg case $umask in 32204449c54Smrg *[123567][0-7][0-7]) 32304449c54Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 32404449c54Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 32504449c54Smrg ;; 32604449c54Smrg *) 32704449c54Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 32804449c54Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 32904449c54Smrg 33004449c54Smrg if (umask $mkdir_umask && 33104449c54Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 33204449c54Smrg then 33304449c54Smrg if test -z "$dir_arg" || { 33404449c54Smrg # Check for POSIX incompatibilities with -m. 33504449c54Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 33604449c54Smrg # other-writable bit of parent directory when it shouldn't. 33704449c54Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 33804449c54Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 33904449c54Smrg case $ls_ld_tmpdir in 34004449c54Smrg d????-?r-*) different_mode=700;; 34104449c54Smrg d????-?--*) different_mode=755;; 34204449c54Smrg *) false;; 34304449c54Smrg esac && 34404449c54Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 34504449c54Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 34604449c54Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 34704449c54Smrg } 34804449c54Smrg } 34904449c54Smrg then posix_mkdir=: 35004449c54Smrg fi 35104449c54Smrg rmdir "$tmpdir/d" "$tmpdir" 35204449c54Smrg else 35304449c54Smrg # Remove any dirs left behind by ancient mkdir implementations. 35404449c54Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 35504449c54Smrg fi 35604449c54Smrg trap '' 0;; 35704449c54Smrg esac;; 358d1c293acSmrg esac 3598440cca4Smrg 360d1c293acSmrg if 361d1c293acSmrg $posix_mkdir && ( 36204449c54Smrg umask $mkdir_umask && 36304449c54Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 364d1c293acSmrg ) 365d1c293acSmrg then : 366d1c293acSmrg else 367d1c293acSmrg 368d1c293acSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 369d1c293acSmrg # or it failed possibly due to a race condition. Create the 370d1c293acSmrg # directory the slow way, step by step, checking for races as we go. 371d1c293acSmrg 372d1c293acSmrg case $dstdir in 37304449c54Smrg /*) prefix='/';; 37404449c54Smrg [-=\(\)!]*) prefix='./';; 37504449c54Smrg *) prefix='';; 376d1c293acSmrg esac 377d1c293acSmrg 378d1c293acSmrg oIFS=$IFS 379d1c293acSmrg IFS=/ 38004449c54Smrg set -f 381d1c293acSmrg set fnord $dstdir 382d1c293acSmrg shift 38304449c54Smrg set +f 384d1c293acSmrg IFS=$oIFS 385d1c293acSmrg 386d1c293acSmrg prefixes= 387d1c293acSmrg 388d1c293acSmrg for d 389d1c293acSmrg do 39004449c54Smrg test X"$d" = X && continue 39104449c54Smrg 39204449c54Smrg prefix=$prefix$d 39304449c54Smrg if test -d "$prefix"; then 39404449c54Smrg prefixes= 39504449c54Smrg else 39604449c54Smrg if $posix_mkdir; then 39704449c54Smrg (umask=$mkdir_umask && 39804449c54Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 39904449c54Smrg # Don't fail if two instances are running concurrently. 40004449c54Smrg test -d "$prefix" || exit 1 40104449c54Smrg else 40204449c54Smrg case $prefix in 40304449c54Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 40404449c54Smrg *) qprefix=$prefix;; 40504449c54Smrg esac 40604449c54Smrg prefixes="$prefixes '$qprefix'" 40704449c54Smrg fi 40804449c54Smrg fi 40904449c54Smrg prefix=$prefix/ 410d1c293acSmrg done 411d1c293acSmrg 412d1c293acSmrg if test -n "$prefixes"; then 41304449c54Smrg # Don't fail if two instances are running concurrently. 41404449c54Smrg (umask $mkdir_umask && 41504449c54Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 41604449c54Smrg test -d "$dstdir" || exit 1 41704449c54Smrg obsolete_mkdir_used=true 418d1c293acSmrg fi 419d1c293acSmrg fi 420d1c293acSmrg fi 421d1c293acSmrg 422d1c293acSmrg if test -n "$dir_arg"; then 423d1c293acSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 424d1c293acSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 425d1c293acSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 426d1c293acSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 427d1c293acSmrg else 428d1c293acSmrg 429d1c293acSmrg # Make a couple of temp file names in the proper directory. 430d1c293acSmrg dsttmp=$dstdir/_inst.$$_ 431d1c293acSmrg rmtmp=$dstdir/_rm.$$_ 432d1c293acSmrg 433d1c293acSmrg # Trap to clean up those temp files at exit. 434d1c293acSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 435d1c293acSmrg 436d1c293acSmrg # Copy the file name to the temp name. 437d1c293acSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 438d1c293acSmrg 439d1c293acSmrg # and set any options; do chmod last to preserve setuid bits. 440d1c293acSmrg # 441d1c293acSmrg # If any of these fail, we abort the whole thing. If we want to 442d1c293acSmrg # ignore errors from any of these, just make sure not to ignore 443d1c293acSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 444d1c293acSmrg # 445d1c293acSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 446d1c293acSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 447d1c293acSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 448d1c293acSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 449d1c293acSmrg 450d1c293acSmrg # If -C, don't bother to copy if it wouldn't change the file. 451d1c293acSmrg if $copy_on_change && 45204449c54Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 45304449c54Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 45404449c54Smrg set -f && 455d1c293acSmrg set X $old && old=:$2:$4:$5:$6 && 456d1c293acSmrg set X $new && new=:$2:$4:$5:$6 && 45704449c54Smrg set +f && 458d1c293acSmrg test "$old" = "$new" && 459d1c293acSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 460d1c293acSmrg then 461d1c293acSmrg rm -f "$dsttmp" 462d1c293acSmrg else 463d1c293acSmrg # Rename the file to the real destination. 464d1c293acSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 465d1c293acSmrg 466d1c293acSmrg # The rename failed, perhaps because mv can't rename something else 467d1c293acSmrg # to itself, or perhaps because mv is so ancient that it does not 468d1c293acSmrg # support -f. 469d1c293acSmrg { 47004449c54Smrg # Now remove or move aside any old file at destination location. 47104449c54Smrg # We try this two ways since rm can't unlink itself on some 47204449c54Smrg # systems and the destination file might be busy for other 47304449c54Smrg # reasons. In this case, the final cleanup might fail but the new 47404449c54Smrg # file should still install successfully. 47504449c54Smrg { 47604449c54Smrg test ! -f "$dst" || 47704449c54Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 47804449c54Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 47904449c54Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 48004449c54Smrg } || 48104449c54Smrg { echo "$0: cannot unlink or rename $dst" >&2 48204449c54Smrg (exit 1); exit 1 48304449c54Smrg } 48404449c54Smrg } && 48504449c54Smrg 48604449c54Smrg # Now rename the file to the real destination. 48704449c54Smrg $doit $mvcmd "$dsttmp" "$dst" 488d1c293acSmrg } 489d1c293acSmrg fi || exit 1 490d1c293acSmrg 491d1c293acSmrg trap '' 0 492d1c293acSmrg fi 493d1c293acSmrgdone 4948440cca4Smrg 495d1c293acSmrg# Local variables: 496d1c293acSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 497d1c293acSmrg# time-stamp-start: "scriptversion=" 498d1c293acSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 499d1c293acSmrg# time-stamp-time-zone: "UTC" 500d1c293acSmrg# time-stamp-end: "; # UTC" 501d1c293acSmrg# End: 502