install-sh revision 8846b520
1fd0c672fSmrg#!/bin/sh 2fd0c672fSmrg# install - install a program, script, or datafile 3fd0c672fSmrg 48846b520Smrgscriptversion=2013-12-25.23; # UTC 5fd0c672fSmrg 6fd0c672fSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7fd0c672fSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8fd0c672fSmrg# following copyright and license. 9fd0c672fSmrg# 10fd0c672fSmrg# Copyright (C) 1994 X Consortium 11fd0c672fSmrg# 12fd0c672fSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13fd0c672fSmrg# of this software and associated documentation files (the "Software"), to 14fd0c672fSmrg# deal in the Software without restriction, including without limitation the 15fd0c672fSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16fd0c672fSmrg# sell copies of the Software, and to permit persons to whom the Software is 17fd0c672fSmrg# furnished to do so, subject to the following conditions: 18fd0c672fSmrg# 19fd0c672fSmrg# The above copyright notice and this permission notice shall be included in 20fd0c672fSmrg# all copies or substantial portions of the Software. 21fd0c672fSmrg# 22fd0c672fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23fd0c672fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24fd0c672fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25fd0c672fSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26fd0c672fSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27fd0c672fSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28fd0c672fSmrg# 29fd0c672fSmrg# Except as contained in this notice, the name of the X Consortium shall not 30fd0c672fSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31fd0c672fSmrg# ings in this Software without prior written authorization from the X Consor- 32fd0c672fSmrg# tium. 33fd0c672fSmrg# 34fd0c672fSmrg# 35fd0c672fSmrg# FSF changes to this file are in the public domain. 36fd0c672fSmrg# 37fd0c672fSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38953c684bSmrg# 'make' implicit rules from creating a file called install from it 39fd0c672fSmrg# when there is no Makefile. 40fd0c672fSmrg# 41fd0c672fSmrg# This script is compatible with the BSD install script, but was written 4248e69166Smrg# from scratch. 4348e69166Smrg 448846b520Smrgtab=' ' 4548e69166Smrgnl=' 4648e69166Smrg' 478846b520SmrgIFS=" $tab$nl" 48fd0c672fSmrg 498846b520Smrg# Set DOITPROG to "echo" to test this script. 50fd0c672fSmrg 5148e69166Smrgdoit=${DOITPROG-} 528846b520Smrgdoit_exec=${doit:-exec} 53fd0c672fSmrg 5448e69166Smrg# Put in absolute file names if you don't have them in your path; 5548e69166Smrg# or use environment vars. 5648e69166Smrg 5748e69166Smrgchgrpprog=${CHGRPPROG-chgrp} 5848e69166Smrgchmodprog=${CHMODPROG-chmod} 5948e69166Smrgchownprog=${CHOWNPROG-chown} 6048e69166Smrgcmpprog=${CMPPROG-cmp} 6148e69166Smrgcpprog=${CPPROG-cp} 6248e69166Smrgmkdirprog=${MKDIRPROG-mkdir} 6348e69166Smrgmvprog=${MVPROG-mv} 6448e69166Smrgrmprog=${RMPROG-rm} 6548e69166Smrgstripprog=${STRIPPROG-strip} 6648e69166Smrg 6748e69166Smrgposix_mkdir= 6848e69166Smrg 6948e69166Smrg# Desired mode of installed file. 7048e69166Smrgmode=0755 71fd0c672fSmrg 72fd0c672fSmrgchgrpcmd= 7348e69166Smrgchmodcmd=$chmodprog 7448e69166Smrgchowncmd= 7548e69166Smrgmvcmd=$mvprog 76fd0c672fSmrgrmcmd="$rmprog -f" 7748e69166Smrgstripcmd= 7848e69166Smrg 79fd0c672fSmrgsrc= 80fd0c672fSmrgdst= 81fd0c672fSmrgdir_arg= 8248e69166Smrgdst_arg= 8348e69166Smrg 8448e69166Smrgcopy_on_change=false 858846b520Smrgis_target_a_directory=possibly 86fd0c672fSmrg 8748e69166Smrgusage="\ 8848e69166SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89fd0c672fSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90fd0c672fSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91fd0c672fSmrg or: $0 [OPTION]... -d DIRECTORIES... 92fd0c672fSmrg 93fd0c672fSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94fd0c672fSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95fd0c672fSmrgIn the 4th, create DIRECTORIES. 96fd0c672fSmrg 97fd0c672fSmrgOptions: 9848e69166Smrg --help display this help and exit. 9948e69166Smrg --version display version info and exit. 10048e69166Smrg 10148e69166Smrg -c (ignored) 10248e69166Smrg -C install only if different (preserve the last data modification time) 10348e69166Smrg -d create directories instead of installing files. 10448e69166Smrg -g GROUP $chgrpprog installed files to GROUP. 10548e69166Smrg -m MODE $chmodprog installed files to MODE. 10648e69166Smrg -o USER $chownprog installed files to USER. 10748e69166Smrg -s $stripprog installed files. 10848e69166Smrg -t DIRECTORY install into DIRECTORY. 10948e69166Smrg -T report an error if DSTFILE is a directory. 110fd0c672fSmrg 111fd0c672fSmrgEnvironment variables override the default commands: 11248e69166Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11348e69166Smrg RMPROG STRIPPROG 114fd0c672fSmrg" 115fd0c672fSmrg 11648e69166Smrgwhile test $# -ne 0; do 117fd0c672fSmrg case $1 in 11848e69166Smrg -c) ;; 11948e69166Smrg 12048e69166Smrg -C) copy_on_change=true;; 121fd0c672fSmrg 12248e69166Smrg -d) dir_arg=true;; 123fd0c672fSmrg 124fd0c672fSmrg -g) chgrpcmd="$chgrpprog $2" 1258846b520Smrg shift;; 126fd0c672fSmrg 127fd0c672fSmrg --help) echo "$usage"; exit $?;; 128fd0c672fSmrg 12948e69166Smrg -m) mode=$2 1308846b520Smrg case $mode in 1318846b520Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1328846b520Smrg echo "$0: invalid mode: $mode" >&2 1338846b520Smrg exit 1;; 1348846b520Smrg esac 1358846b520Smrg shift;; 136fd0c672fSmrg 137fd0c672fSmrg -o) chowncmd="$chownprog $2" 1388846b520Smrg shift;; 139fd0c672fSmrg 14048e69166Smrg -s) stripcmd=$stripprog;; 141fd0c672fSmrg 1428846b520Smrg -t) 1438846b520Smrg is_target_a_directory=always 1448846b520Smrg dst_arg=$2 1458846b520Smrg # Protect names problematic for 'test' and other utilities. 1468846b520Smrg case $dst_arg in 1478846b520Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1488846b520Smrg esac 1498846b520Smrg shift;; 150fd0c672fSmrg 1518846b520Smrg -T) is_target_a_directory=never;; 152fd0c672fSmrg 153fd0c672fSmrg --version) echo "$0 $scriptversion"; exit $?;; 154fd0c672fSmrg 1558846b520Smrg --) shift 1568846b520Smrg break;; 15748e69166Smrg 1588846b520Smrg -*) echo "$0: invalid option: $1" >&2 1598846b520Smrg exit 1;; 16048e69166Smrg 16148e69166Smrg *) break;; 162fd0c672fSmrg esac 16348e69166Smrg shift 164fd0c672fSmrgdone 165fd0c672fSmrg 1668846b520Smrg# We allow the use of options -d and -T together, by making -d 1678846b520Smrg# take the precedence; this is for compatibility with GNU install. 1688846b520Smrg 1698846b520Smrgif test -n "$dir_arg"; then 1708846b520Smrg if test -n "$dst_arg"; then 1718846b520Smrg echo "$0: target directory not allowed when installing a directory." >&2 1728846b520Smrg exit 1 1738846b520Smrg fi 1748846b520Smrgfi 1758846b520Smrg 17648e69166Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17748e69166Smrg # When -d is used, all remaining arguments are directories to create. 17848e69166Smrg # When -t is used, the destination is already specified. 17948e69166Smrg # Otherwise, the last argument is the destination. Remove it from $@. 18048e69166Smrg for arg 18148e69166Smrg do 18248e69166Smrg if test -n "$dst_arg"; then 18348e69166Smrg # $@ is not empty: it contains at least $arg. 18448e69166Smrg set fnord "$@" "$dst_arg" 18548e69166Smrg shift # fnord 18648e69166Smrg fi 18748e69166Smrg shift # arg 18848e69166Smrg dst_arg=$arg 189953c684bSmrg # Protect names problematic for 'test' and other utilities. 190953c684bSmrg case $dst_arg in 191953c684bSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192953c684bSmrg esac 19348e69166Smrg done 19448e69166Smrgfi 19548e69166Smrg 19648e69166Smrgif test $# -eq 0; then 197fd0c672fSmrg if test -z "$dir_arg"; then 198fd0c672fSmrg echo "$0: no input file specified." >&2 199fd0c672fSmrg exit 1 200fd0c672fSmrg fi 201953c684bSmrg # It's OK to call 'install-sh -d' without argument. 202fd0c672fSmrg # This can happen when creating conditional directories. 203fd0c672fSmrg exit 0 204fd0c672fSmrgfi 205fd0c672fSmrg 2068846b520Smrgif test -z "$dir_arg"; then 2078846b520Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2088846b520Smrg if test ! -d "$dst_arg"; then 2098846b520Smrg echo "$0: $dst_arg: Is not a directory." >&2 2108846b520Smrg exit 1 2118846b520Smrg fi 2128846b520Smrg fi 2138846b520Smrgfi 2148846b520Smrg 21548e69166Smrgif test -z "$dir_arg"; then 216953c684bSmrg do_exit='(exit $ret); exit $ret' 217953c684bSmrg trap "ret=129; $do_exit" 1 218953c684bSmrg trap "ret=130; $do_exit" 2 219953c684bSmrg trap "ret=141; $do_exit" 13 220953c684bSmrg trap "ret=143; $do_exit" 15 22148e69166Smrg 22248e69166Smrg # Set umask so as not to create temps with too-generous modes. 22348e69166Smrg # However, 'strip' requires both read and write access to temps. 22448e69166Smrg case $mode in 22548e69166Smrg # Optimize common cases. 22648e69166Smrg *644) cp_umask=133;; 22748e69166Smrg *755) cp_umask=22;; 22848e69166Smrg 22948e69166Smrg *[0-7]) 23048e69166Smrg if test -z "$stripcmd"; then 2318846b520Smrg u_plus_rw= 23248e69166Smrg else 2338846b520Smrg u_plus_rw='% 200' 23448e69166Smrg fi 23548e69166Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23648e69166Smrg *) 23748e69166Smrg if test -z "$stripcmd"; then 2388846b520Smrg u_plus_rw= 23948e69166Smrg else 2408846b520Smrg u_plus_rw=,u+rw 24148e69166Smrg fi 24248e69166Smrg cp_umask=$mode$u_plus_rw;; 24348e69166Smrg esac 24448e69166Smrgfi 24548e69166Smrg 246fd0c672fSmrgfor src 247fd0c672fSmrgdo 248953c684bSmrg # Protect names problematic for 'test' and other utilities. 249fd0c672fSmrg case $src in 250953c684bSmrg -* | [=\(\)!]) src=./$src;; 251fd0c672fSmrg esac 252fd0c672fSmrg 253fd0c672fSmrg if test -n "$dir_arg"; then 254fd0c672fSmrg dst=$src 25548e69166Smrg dstdir=$dst 25648e69166Smrg test -d "$dstdir" 25748e69166Smrg dstdir_status=$? 258fd0c672fSmrg else 25948e69166Smrg 260fd0c672fSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261fd0c672fSmrg # might cause directories to be created, which would be especially bad 262fd0c672fSmrg # if $src (and thus $dsttmp) contains '*'. 263fd0c672fSmrg if test ! -f "$src" && test ! -d "$src"; then 264fd0c672fSmrg echo "$0: $src does not exist." >&2 265fd0c672fSmrg exit 1 266fd0c672fSmrg fi 267fd0c672fSmrg 26848e69166Smrg if test -z "$dst_arg"; then 269fd0c672fSmrg echo "$0: no destination specified." >&2 270fd0c672fSmrg exit 1 271fd0c672fSmrg fi 27248e69166Smrg dst=$dst_arg 273fd0c672fSmrg 274fd0c672fSmrg # If destination is a directory, append the input filename; won't work 275fd0c672fSmrg # if double slashes aren't ignored. 276fd0c672fSmrg if test -d "$dst"; then 2778846b520Smrg if test "$is_target_a_directory" = never; then 2788846b520Smrg echo "$0: $dst_arg: Is a directory" >&2 2798846b520Smrg exit 1 280fd0c672fSmrg fi 28148e69166Smrg dstdir=$dst 28248e69166Smrg dst=$dstdir/`basename "$src"` 28348e69166Smrg dstdir_status=0 28448e69166Smrg else 2858846b520Smrg dstdir=`dirname "$dst"` 28648e69166Smrg test -d "$dstdir" 28748e69166Smrg dstdir_status=$? 288fd0c672fSmrg fi 289fd0c672fSmrg fi 290fd0c672fSmrg 29148e69166Smrg obsolete_mkdir_used=false 29248e69166Smrg 29348e69166Smrg if test $dstdir_status != 0; then 29448e69166Smrg case $posix_mkdir in 29548e69166Smrg '') 2968846b520Smrg # Create intermediate dirs using mode 755 as modified by the umask. 2978846b520Smrg # This is like FreeBSD 'install' as of 1997-10-28. 2988846b520Smrg umask=`umask` 2998846b520Smrg case $stripcmd.$umask in 3008846b520Smrg # Optimize common cases. 3018846b520Smrg *[2367][2367]) mkdir_umask=$umask;; 3028846b520Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3038846b520Smrg 3048846b520Smrg *[0-7]) 3058846b520Smrg mkdir_umask=`expr $umask + 22 \ 3068846b520Smrg - $umask % 100 % 40 + $umask % 20 \ 3078846b520Smrg - $umask % 10 % 4 + $umask % 2 3088846b520Smrg `;; 3098846b520Smrg *) mkdir_umask=$umask,go-w;; 3108846b520Smrg esac 3118846b520Smrg 3128846b520Smrg # With -d, create the new directory with the user-specified mode. 3138846b520Smrg # Otherwise, rely on $mkdir_umask. 3148846b520Smrg if test -n "$dir_arg"; then 3158846b520Smrg mkdir_mode=-m$mode 3168846b520Smrg else 3178846b520Smrg mkdir_mode= 3188846b520Smrg fi 3198846b520Smrg 3208846b520Smrg posix_mkdir=false 3218846b520Smrg case $umask in 3228846b520Smrg *[123567][0-7][0-7]) 3238846b520Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3248846b520Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3258846b520Smrg ;; 3268846b520Smrg *) 3278846b520Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3288846b520Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3298846b520Smrg 3308846b520Smrg if (umask $mkdir_umask && 3318846b520Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3328846b520Smrg then 3338846b520Smrg if test -z "$dir_arg" || { 3348846b520Smrg # Check for POSIX incompatibilities with -m. 3358846b520Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3368846b520Smrg # other-writable bit of parent directory when it shouldn't. 3378846b520Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3388846b520Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3398846b520Smrg case $ls_ld_tmpdir in 3408846b520Smrg d????-?r-*) different_mode=700;; 3418846b520Smrg d????-?--*) different_mode=755;; 3428846b520Smrg *) false;; 3438846b520Smrg esac && 3448846b520Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3458846b520Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3468846b520Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3478846b520Smrg } 3488846b520Smrg } 3498846b520Smrg then posix_mkdir=: 3508846b520Smrg fi 3518846b520Smrg rmdir "$tmpdir/d" "$tmpdir" 3528846b520Smrg else 3538846b520Smrg # Remove any dirs left behind by ancient mkdir implementations. 3548846b520Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3558846b520Smrg fi 3568846b520Smrg trap '' 0;; 3578846b520Smrg esac;; 35848e69166Smrg esac 359fd0c672fSmrg 36048e69166Smrg if 36148e69166Smrg $posix_mkdir && ( 3628846b520Smrg umask $mkdir_umask && 3638846b520Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 36448e69166Smrg ) 36548e69166Smrg then : 36648e69166Smrg else 367fd0c672fSmrg 36848e69166Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 36948e69166Smrg # or it failed possibly due to a race condition. Create the 37048e69166Smrg # directory the slow way, step by step, checking for races as we go. 371fd0c672fSmrg 37248e69166Smrg case $dstdir in 3738846b520Smrg /*) prefix='/';; 3748846b520Smrg [-=\(\)!]*) prefix='./';; 3758846b520Smrg *) prefix='';; 37648e69166Smrg esac 377fd0c672fSmrg 37848e69166Smrg oIFS=$IFS 37948e69166Smrg IFS=/ 3808846b520Smrg set -f 38148e69166Smrg set fnord $dstdir 382fd0c672fSmrg shift 3838846b520Smrg set +f 38448e69166Smrg IFS=$oIFS 38548e69166Smrg 38648e69166Smrg prefixes= 38748e69166Smrg 38848e69166Smrg for d 38948e69166Smrg do 3908846b520Smrg test X"$d" = X && continue 3918846b520Smrg 3928846b520Smrg prefix=$prefix$d 3938846b520Smrg if test -d "$prefix"; then 3948846b520Smrg prefixes= 3958846b520Smrg else 3968846b520Smrg if $posix_mkdir; then 3978846b520Smrg (umask=$mkdir_umask && 3988846b520Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 3998846b520Smrg # Don't fail if two instances are running concurrently. 4008846b520Smrg test -d "$prefix" || exit 1 4018846b520Smrg else 4028846b520Smrg case $prefix in 4038846b520Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4048846b520Smrg *) qprefix=$prefix;; 4058846b520Smrg esac 4068846b520Smrg prefixes="$prefixes '$qprefix'" 4078846b520Smrg fi 4088846b520Smrg fi 4098846b520Smrg prefix=$prefix/ 41048e69166Smrg done 41148e69166Smrg 41248e69166Smrg if test -n "$prefixes"; then 4138846b520Smrg # Don't fail if two instances are running concurrently. 4148846b520Smrg (umask $mkdir_umask && 4158846b520Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4168846b520Smrg test -d "$dstdir" || exit 1 4178846b520Smrg obsolete_mkdir_used=true 418fd0c672fSmrg fi 41948e69166Smrg fi 420fd0c672fSmrg fi 421fd0c672fSmrg 422fd0c672fSmrg if test -n "$dir_arg"; then 42348e69166Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 42448e69166Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 42548e69166Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 42648e69166Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 427fd0c672fSmrg else 428fd0c672fSmrg 429fd0c672fSmrg # Make a couple of temp file names in the proper directory. 430fd0c672fSmrg dsttmp=$dstdir/_inst.$$_ 431fd0c672fSmrg rmtmp=$dstdir/_rm.$$_ 432fd0c672fSmrg 433fd0c672fSmrg # Trap to clean up those temp files at exit. 434fd0c672fSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 435fd0c672fSmrg 436fd0c672fSmrg # Copy the file name to the temp name. 43748e69166Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 438fd0c672fSmrg 439fd0c672fSmrg # and set any options; do chmod last to preserve setuid bits. 440fd0c672fSmrg # 441fd0c672fSmrg # If any of these fail, we abort the whole thing. If we want to 442fd0c672fSmrg # ignore errors from any of these, just make sure not to ignore 443fd0c672fSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 444fd0c672fSmrg # 44548e69166Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 44648e69166Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 44748e69166Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 44848e69166Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 44948e69166Smrg 45048e69166Smrg # If -C, don't bother to copy if it wouldn't change the file. 45148e69166Smrg if $copy_on_change && 4528846b520Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4538846b520Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4548846b520Smrg set -f && 45548e69166Smrg set X $old && old=:$2:$4:$5:$6 && 45648e69166Smrg set X $new && new=:$2:$4:$5:$6 && 4578846b520Smrg set +f && 45848e69166Smrg test "$old" = "$new" && 45948e69166Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 46048e69166Smrg then 46148e69166Smrg rm -f "$dsttmp" 46248e69166Smrg else 46348e69166Smrg # Rename the file to the real destination. 46448e69166Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 46548e69166Smrg 46648e69166Smrg # The rename failed, perhaps because mv can't rename something else 46748e69166Smrg # to itself, or perhaps because mv is so ancient that it does not 46848e69166Smrg # support -f. 46948e69166Smrg { 4708846b520Smrg # Now remove or move aside any old file at destination location. 4718846b520Smrg # We try this two ways since rm can't unlink itself on some 4728846b520Smrg # systems and the destination file might be busy for other 4738846b520Smrg # reasons. In this case, the final cleanup might fail but the new 4748846b520Smrg # file should still install successfully. 4758846b520Smrg { 4768846b520Smrg test ! -f "$dst" || 4778846b520Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 4788846b520Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 4798846b520Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 4808846b520Smrg } || 4818846b520Smrg { echo "$0: cannot unlink or rename $dst" >&2 4828846b520Smrg (exit 1); exit 1 4838846b520Smrg } 4848846b520Smrg } && 4858846b520Smrg 4868846b520Smrg # Now rename the file to the real destination. 4878846b520Smrg $doit $mvcmd "$dsttmp" "$dst" 48848e69166Smrg } 48948e69166Smrg fi || exit 1 49048e69166Smrg 49148e69166Smrg trap '' 0 49248e69166Smrg fi 493fd0c672fSmrgdone 494fd0c672fSmrg 495fd0c672fSmrg# Local variables: 496fd0c672fSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 497fd0c672fSmrg# time-stamp-start: "scriptversion=" 498fd0c672fSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 49948e69166Smrg# time-stamp-time-zone: "UTC" 50048e69166Smrg# time-stamp-end: "; # UTC" 501fd0c672fSmrg# End: 502