install-sh revision 0c91c449
1ff7e0accSmrg#!/bin/sh 2ff7e0accSmrg# install - install a program, script, or datafile 3ff7e0accSmrg 40c91c449Smrgscriptversion=2013-12-25.23; # UTC 5ff7e0accSmrg 6ff7e0accSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7ff7e0accSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8ff7e0accSmrg# following copyright and license. 9ff7e0accSmrg# 10ff7e0accSmrg# Copyright (C) 1994 X Consortium 11ff7e0accSmrg# 12ff7e0accSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13ff7e0accSmrg# of this software and associated documentation files (the "Software"), to 14ff7e0accSmrg# deal in the Software without restriction, including without limitation the 15ff7e0accSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16ff7e0accSmrg# sell copies of the Software, and to permit persons to whom the Software is 17ff7e0accSmrg# furnished to do so, subject to the following conditions: 18ff7e0accSmrg# 19ff7e0accSmrg# The above copyright notice and this permission notice shall be included in 20ff7e0accSmrg# all copies or substantial portions of the Software. 21ff7e0accSmrg# 22ff7e0accSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23ff7e0accSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24ff7e0accSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25ff7e0accSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26ff7e0accSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27ff7e0accSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28ff7e0accSmrg# 29ff7e0accSmrg# Except as contained in this notice, the name of the X Consortium shall not 30ff7e0accSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31ff7e0accSmrg# ings in this Software without prior written authorization from the X Consor- 32ff7e0accSmrg# tium. 33ff7e0accSmrg# 34ff7e0accSmrg# 35ff7e0accSmrg# FSF changes to this file are in the public domain. 36ff7e0accSmrg# 37ff7e0accSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3805bee9bcSmrg# 'make' implicit rules from creating a file called install from it 39ff7e0accSmrg# when there is no Makefile. 40ff7e0accSmrg# 41ff7e0accSmrg# This script is compatible with the BSD install script, but was written 42ff7e0accSmrg# from scratch. 43ff7e0accSmrg 440c91c449Smrgtab=' ' 45ff7e0accSmrgnl=' 46ff7e0accSmrg' 470c91c449SmrgIFS=" $tab$nl" 48ff7e0accSmrg 490c91c449Smrg# Set DOITPROG to "echo" to test this script. 50ff7e0accSmrg 51a005d216Smrgdoit=${DOITPROG-} 520c91c449Smrgdoit_exec=${doit:-exec} 53ff7e0accSmrg 54ff7e0accSmrg# Put in absolute file names if you don't have them in your path; 55ff7e0accSmrg# or use environment vars. 56ff7e0accSmrg 57a005d216Smrgchgrpprog=${CHGRPPROG-chgrp} 58a005d216Smrgchmodprog=${CHMODPROG-chmod} 59a005d216Smrgchownprog=${CHOWNPROG-chown} 60a005d216Smrgcmpprog=${CMPPROG-cmp} 61a005d216Smrgcpprog=${CPPROG-cp} 62a005d216Smrgmkdirprog=${MKDIRPROG-mkdir} 63a005d216Smrgmvprog=${MVPROG-mv} 64a005d216Smrgrmprog=${RMPROG-rm} 65a005d216Smrgstripprog=${STRIPPROG-strip} 66a005d216Smrg 67ff7e0accSmrgposix_mkdir= 68ff7e0accSmrg 69ff7e0accSmrg# Desired mode of installed file. 70ff7e0accSmrgmode=0755 71ff7e0accSmrg 72a005d216Smrgchgrpcmd= 73ff7e0accSmrgchmodcmd=$chmodprog 74ff7e0accSmrgchowncmd= 75a005d216Smrgmvcmd=$mvprog 76ff7e0accSmrgrmcmd="$rmprog -f" 77a005d216Smrgstripcmd= 78a005d216Smrg 79ff7e0accSmrgsrc= 80ff7e0accSmrgdst= 81ff7e0accSmrgdir_arg= 82a005d216Smrgdst_arg= 83a005d216Smrg 84a005d216Smrgcopy_on_change=false 850c91c449Smrgis_target_a_directory=possibly 86ff7e0accSmrg 87a005d216Smrgusage="\ 88a005d216SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89ff7e0accSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90ff7e0accSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91ff7e0accSmrg or: $0 [OPTION]... -d DIRECTORIES... 92ff7e0accSmrg 93ff7e0accSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94ff7e0accSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95ff7e0accSmrgIn the 4th, create DIRECTORIES. 96ff7e0accSmrg 97ff7e0accSmrgOptions: 98a005d216Smrg --help display this help and exit. 99a005d216Smrg --version display version info and exit. 100a005d216Smrg 101a005d216Smrg -c (ignored) 102a005d216Smrg -C install only if different (preserve the last data modification time) 103a005d216Smrg -d create directories instead of installing files. 104a005d216Smrg -g GROUP $chgrpprog installed files to GROUP. 105a005d216Smrg -m MODE $chmodprog installed files to MODE. 106a005d216Smrg -o USER $chownprog installed files to USER. 107a005d216Smrg -s $stripprog installed files. 108a005d216Smrg -t DIRECTORY install into DIRECTORY. 109a005d216Smrg -T report an error if DSTFILE is a directory. 110ff7e0accSmrg 111ff7e0accSmrgEnvironment variables override the default commands: 112a005d216Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113a005d216Smrg RMPROG STRIPPROG 114ff7e0accSmrg" 115ff7e0accSmrg 116ff7e0accSmrgwhile test $# -ne 0; do 117ff7e0accSmrg case $1 in 118a005d216Smrg -c) ;; 119a005d216Smrg 120a005d216Smrg -C) copy_on_change=true;; 121ff7e0accSmrg 122a005d216Smrg -d) dir_arg=true;; 123ff7e0accSmrg 124ff7e0accSmrg -g) chgrpcmd="$chgrpprog $2" 1250c91c449Smrg shift;; 126ff7e0accSmrg 127ff7e0accSmrg --help) echo "$usage"; exit $?;; 128ff7e0accSmrg 129ff7e0accSmrg -m) mode=$2 1300c91c449Smrg case $mode in 1310c91c449Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1320c91c449Smrg echo "$0: invalid mode: $mode" >&2 1330c91c449Smrg exit 1;; 1340c91c449Smrg esac 1350c91c449Smrg shift;; 136ff7e0accSmrg 137ff7e0accSmrg -o) chowncmd="$chownprog $2" 1380c91c449Smrg shift;; 139ff7e0accSmrg 140a005d216Smrg -s) stripcmd=$stripprog;; 141ff7e0accSmrg 1420c91c449Smrg -t) 1430c91c449Smrg is_target_a_directory=always 1440c91c449Smrg dst_arg=$2 1450c91c449Smrg # Protect names problematic for 'test' and other utilities. 1460c91c449Smrg case $dst_arg in 1470c91c449Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1480c91c449Smrg esac 1490c91c449Smrg shift;; 150ff7e0accSmrg 1510c91c449Smrg -T) is_target_a_directory=never;; 152ff7e0accSmrg 153ff7e0accSmrg --version) echo "$0 $scriptversion"; exit $?;; 154ff7e0accSmrg 1550c91c449Smrg --) shift 1560c91c449Smrg break;; 157ff7e0accSmrg 1580c91c449Smrg -*) echo "$0: invalid option: $1" >&2 1590c91c449Smrg exit 1;; 160ff7e0accSmrg 161ff7e0accSmrg *) break;; 162ff7e0accSmrg esac 163a005d216Smrg shift 164ff7e0accSmrgdone 165ff7e0accSmrg 1660c91c449Smrg# We allow the use of options -d and -T together, by making -d 1670c91c449Smrg# take the precedence; this is for compatibility with GNU install. 1680c91c449Smrg 1690c91c449Smrgif test -n "$dir_arg"; then 1700c91c449Smrg if test -n "$dst_arg"; then 1710c91c449Smrg echo "$0: target directory not allowed when installing a directory." >&2 1720c91c449Smrg exit 1 1730c91c449Smrg fi 1740c91c449Smrgfi 1750c91c449Smrg 176a005d216Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177ff7e0accSmrg # When -d is used, all remaining arguments are directories to create. 178ff7e0accSmrg # When -t is used, the destination is already specified. 179ff7e0accSmrg # Otherwise, the last argument is the destination. Remove it from $@. 180ff7e0accSmrg for arg 181ff7e0accSmrg do 182a005d216Smrg if test -n "$dst_arg"; then 183ff7e0accSmrg # $@ is not empty: it contains at least $arg. 184a005d216Smrg set fnord "$@" "$dst_arg" 185ff7e0accSmrg shift # fnord 186ff7e0accSmrg fi 187ff7e0accSmrg shift # arg 188a005d216Smrg dst_arg=$arg 18905bee9bcSmrg # Protect names problematic for 'test' and other utilities. 19005bee9bcSmrg case $dst_arg in 19105bee9bcSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 19205bee9bcSmrg esac 193ff7e0accSmrg done 194ff7e0accSmrgfi 195ff7e0accSmrg 196ff7e0accSmrgif test $# -eq 0; then 197ff7e0accSmrg if test -z "$dir_arg"; then 198ff7e0accSmrg echo "$0: no input file specified." >&2 199ff7e0accSmrg exit 1 200ff7e0accSmrg fi 20105bee9bcSmrg # It's OK to call 'install-sh -d' without argument. 202ff7e0accSmrg # This can happen when creating conditional directories. 203ff7e0accSmrg exit 0 204ff7e0accSmrgfi 205ff7e0accSmrg 2060c91c449Smrgif test -z "$dir_arg"; then 2070c91c449Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2080c91c449Smrg if test ! -d "$dst_arg"; then 2090c91c449Smrg echo "$0: $dst_arg: Is not a directory." >&2 2100c91c449Smrg exit 1 2110c91c449Smrg fi 2120c91c449Smrg fi 2130c91c449Smrgfi 2140c91c449Smrg 215ff7e0accSmrgif test -z "$dir_arg"; then 21605bee9bcSmrg do_exit='(exit $ret); exit $ret' 21705bee9bcSmrg trap "ret=129; $do_exit" 1 21805bee9bcSmrg trap "ret=130; $do_exit" 2 21905bee9bcSmrg trap "ret=141; $do_exit" 13 22005bee9bcSmrg trap "ret=143; $do_exit" 15 221ff7e0accSmrg 222ff7e0accSmrg # Set umask so as not to create temps with too-generous modes. 223ff7e0accSmrg # However, 'strip' requires both read and write access to temps. 224ff7e0accSmrg case $mode in 225ff7e0accSmrg # Optimize common cases. 226ff7e0accSmrg *644) cp_umask=133;; 227ff7e0accSmrg *755) cp_umask=22;; 228ff7e0accSmrg 229ff7e0accSmrg *[0-7]) 230ff7e0accSmrg if test -z "$stripcmd"; then 2310c91c449Smrg u_plus_rw= 232ff7e0accSmrg else 2330c91c449Smrg u_plus_rw='% 200' 234ff7e0accSmrg fi 235ff7e0accSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236ff7e0accSmrg *) 237ff7e0accSmrg if test -z "$stripcmd"; then 2380c91c449Smrg u_plus_rw= 239ff7e0accSmrg else 2400c91c449Smrg u_plus_rw=,u+rw 241ff7e0accSmrg fi 242ff7e0accSmrg cp_umask=$mode$u_plus_rw;; 243ff7e0accSmrg esac 244ff7e0accSmrgfi 245ff7e0accSmrg 246ff7e0accSmrgfor src 247ff7e0accSmrgdo 24805bee9bcSmrg # Protect names problematic for 'test' and other utilities. 249ff7e0accSmrg case $src in 25005bee9bcSmrg -* | [=\(\)!]) src=./$src;; 251ff7e0accSmrg esac 252ff7e0accSmrg 253ff7e0accSmrg if test -n "$dir_arg"; then 254ff7e0accSmrg dst=$src 255ff7e0accSmrg dstdir=$dst 256ff7e0accSmrg test -d "$dstdir" 257ff7e0accSmrg dstdir_status=$? 258ff7e0accSmrg else 259ff7e0accSmrg 260ff7e0accSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261ff7e0accSmrg # might cause directories to be created, which would be especially bad 262ff7e0accSmrg # if $src (and thus $dsttmp) contains '*'. 263ff7e0accSmrg if test ! -f "$src" && test ! -d "$src"; then 264ff7e0accSmrg echo "$0: $src does not exist." >&2 265ff7e0accSmrg exit 1 266ff7e0accSmrg fi 267ff7e0accSmrg 268a005d216Smrg if test -z "$dst_arg"; then 269ff7e0accSmrg echo "$0: no destination specified." >&2 270ff7e0accSmrg exit 1 271ff7e0accSmrg fi 272a005d216Smrg dst=$dst_arg 273ff7e0accSmrg 274ff7e0accSmrg # If destination is a directory, append the input filename; won't work 275ff7e0accSmrg # if double slashes aren't ignored. 276ff7e0accSmrg if test -d "$dst"; then 2770c91c449Smrg if test "$is_target_a_directory" = never; then 2780c91c449Smrg echo "$0: $dst_arg: Is a directory" >&2 2790c91c449Smrg exit 1 280ff7e0accSmrg fi 281ff7e0accSmrg dstdir=$dst 282ff7e0accSmrg dst=$dstdir/`basename "$src"` 283ff7e0accSmrg dstdir_status=0 284ff7e0accSmrg else 2850c91c449Smrg dstdir=`dirname "$dst"` 286ff7e0accSmrg test -d "$dstdir" 287ff7e0accSmrg dstdir_status=$? 288ff7e0accSmrg fi 289ff7e0accSmrg fi 290ff7e0accSmrg 291ff7e0accSmrg obsolete_mkdir_used=false 292ff7e0accSmrg 293ff7e0accSmrg if test $dstdir_status != 0; then 294ff7e0accSmrg case $posix_mkdir in 295ff7e0accSmrg '') 2960c91c449Smrg # Create intermediate dirs using mode 755 as modified by the umask. 2970c91c449Smrg # This is like FreeBSD 'install' as of 1997-10-28. 2980c91c449Smrg umask=`umask` 2990c91c449Smrg case $stripcmd.$umask in 3000c91c449Smrg # Optimize common cases. 3010c91c449Smrg *[2367][2367]) mkdir_umask=$umask;; 3020c91c449Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3030c91c449Smrg 3040c91c449Smrg *[0-7]) 3050c91c449Smrg mkdir_umask=`expr $umask + 22 \ 3060c91c449Smrg - $umask % 100 % 40 + $umask % 20 \ 3070c91c449Smrg - $umask % 10 % 4 + $umask % 2 3080c91c449Smrg `;; 3090c91c449Smrg *) mkdir_umask=$umask,go-w;; 3100c91c449Smrg esac 3110c91c449Smrg 3120c91c449Smrg # With -d, create the new directory with the user-specified mode. 3130c91c449Smrg # Otherwise, rely on $mkdir_umask. 3140c91c449Smrg if test -n "$dir_arg"; then 3150c91c449Smrg mkdir_mode=-m$mode 3160c91c449Smrg else 3170c91c449Smrg mkdir_mode= 3180c91c449Smrg fi 3190c91c449Smrg 3200c91c449Smrg posix_mkdir=false 3210c91c449Smrg case $umask in 3220c91c449Smrg *[123567][0-7][0-7]) 3230c91c449Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3240c91c449Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3250c91c449Smrg ;; 3260c91c449Smrg *) 3270c91c449Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3280c91c449Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3290c91c449Smrg 3300c91c449Smrg if (umask $mkdir_umask && 3310c91c449Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3320c91c449Smrg then 3330c91c449Smrg if test -z "$dir_arg" || { 3340c91c449Smrg # Check for POSIX incompatibilities with -m. 3350c91c449Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3360c91c449Smrg # other-writable bit of parent directory when it shouldn't. 3370c91c449Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3380c91c449Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3390c91c449Smrg case $ls_ld_tmpdir in 3400c91c449Smrg d????-?r-*) different_mode=700;; 3410c91c449Smrg d????-?--*) different_mode=755;; 3420c91c449Smrg *) false;; 3430c91c449Smrg esac && 3440c91c449Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3450c91c449Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3460c91c449Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3470c91c449Smrg } 3480c91c449Smrg } 3490c91c449Smrg then posix_mkdir=: 3500c91c449Smrg fi 3510c91c449Smrg rmdir "$tmpdir/d" "$tmpdir" 3520c91c449Smrg else 3530c91c449Smrg # Remove any dirs left behind by ancient mkdir implementations. 3540c91c449Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3550c91c449Smrg fi 3560c91c449Smrg trap '' 0;; 3570c91c449Smrg esac;; 358ff7e0accSmrg esac 359ff7e0accSmrg 360ff7e0accSmrg if 361ff7e0accSmrg $posix_mkdir && ( 3620c91c449Smrg umask $mkdir_umask && 3630c91c449Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 364ff7e0accSmrg ) 365ff7e0accSmrg then : 366ff7e0accSmrg else 367ff7e0accSmrg 368ff7e0accSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 369ff7e0accSmrg # or it failed possibly due to a race condition. Create the 370ff7e0accSmrg # directory the slow way, step by step, checking for races as we go. 371ff7e0accSmrg 372ff7e0accSmrg case $dstdir in 3730c91c449Smrg /*) prefix='/';; 3740c91c449Smrg [-=\(\)!]*) prefix='./';; 3750c91c449Smrg *) prefix='';; 376ff7e0accSmrg esac 377ff7e0accSmrg 378ff7e0accSmrg oIFS=$IFS 379ff7e0accSmrg IFS=/ 3800c91c449Smrg set -f 381ff7e0accSmrg set fnord $dstdir 382ff7e0accSmrg shift 3830c91c449Smrg set +f 384ff7e0accSmrg IFS=$oIFS 385ff7e0accSmrg 386ff7e0accSmrg prefixes= 387ff7e0accSmrg 388ff7e0accSmrg for d 389ff7e0accSmrg do 3900c91c449Smrg test X"$d" = X && continue 3910c91c449Smrg 3920c91c449Smrg prefix=$prefix$d 3930c91c449Smrg if test -d "$prefix"; then 3940c91c449Smrg prefixes= 3950c91c449Smrg else 3960c91c449Smrg if $posix_mkdir; then 3970c91c449Smrg (umask=$mkdir_umask && 3980c91c449Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 3990c91c449Smrg # Don't fail if two instances are running concurrently. 4000c91c449Smrg test -d "$prefix" || exit 1 4010c91c449Smrg else 4020c91c449Smrg case $prefix in 4030c91c449Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4040c91c449Smrg *) qprefix=$prefix;; 4050c91c449Smrg esac 4060c91c449Smrg prefixes="$prefixes '$qprefix'" 4070c91c449Smrg fi 4080c91c449Smrg fi 4090c91c449Smrg prefix=$prefix/ 410ff7e0accSmrg done 411ff7e0accSmrg 412ff7e0accSmrg if test -n "$prefixes"; then 4130c91c449Smrg # Don't fail if two instances are running concurrently. 4140c91c449Smrg (umask $mkdir_umask && 4150c91c449Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4160c91c449Smrg test -d "$dstdir" || exit 1 4170c91c449Smrg obsolete_mkdir_used=true 418ff7e0accSmrg fi 419ff7e0accSmrg fi 420ff7e0accSmrg fi 421ff7e0accSmrg 422ff7e0accSmrg if test -n "$dir_arg"; then 423ff7e0accSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 424ff7e0accSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 425ff7e0accSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 426ff7e0accSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 427ff7e0accSmrg else 428ff7e0accSmrg 429ff7e0accSmrg # Make a couple of temp file names in the proper directory. 430ff7e0accSmrg dsttmp=$dstdir/_inst.$$_ 431ff7e0accSmrg rmtmp=$dstdir/_rm.$$_ 432ff7e0accSmrg 433ff7e0accSmrg # Trap to clean up those temp files at exit. 434ff7e0accSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 435ff7e0accSmrg 436ff7e0accSmrg # Copy the file name to the temp name. 437ff7e0accSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 438ff7e0accSmrg 439ff7e0accSmrg # and set any options; do chmod last to preserve setuid bits. 440ff7e0accSmrg # 441ff7e0accSmrg # If any of these fail, we abort the whole thing. If we want to 442ff7e0accSmrg # ignore errors from any of these, just make sure not to ignore 443ff7e0accSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 444ff7e0accSmrg # 445a005d216Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 446a005d216Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 447a005d216Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 448a005d216Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 449a005d216Smrg 450a005d216Smrg # If -C, don't bother to copy if it wouldn't change the file. 451a005d216Smrg if $copy_on_change && 4520c91c449Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4530c91c449Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4540c91c449Smrg set -f && 455a005d216Smrg set X $old && old=:$2:$4:$5:$6 && 456a005d216Smrg set X $new && new=:$2:$4:$5:$6 && 4570c91c449Smrg set +f && 458a005d216Smrg test "$old" = "$new" && 459a005d216Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 460a005d216Smrg then 461a005d216Smrg rm -f "$dsttmp" 462a005d216Smrg else 463a005d216Smrg # Rename the file to the real destination. 464a005d216Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 465a005d216Smrg 466a005d216Smrg # The rename failed, perhaps because mv can't rename something else 467a005d216Smrg # to itself, or perhaps because mv is so ancient that it does not 468a005d216Smrg # support -f. 469a005d216Smrg { 4700c91c449Smrg # Now remove or move aside any old file at destination location. 4710c91c449Smrg # We try this two ways since rm can't unlink itself on some 4720c91c449Smrg # systems and the destination file might be busy for other 4730c91c449Smrg # reasons. In this case, the final cleanup might fail but the new 4740c91c449Smrg # file should still install successfully. 4750c91c449Smrg { 4760c91c449Smrg test ! -f "$dst" || 4770c91c449Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 4780c91c449Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 4790c91c449Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 4800c91c449Smrg } || 4810c91c449Smrg { echo "$0: cannot unlink or rename $dst" >&2 4820c91c449Smrg (exit 1); exit 1 4830c91c449Smrg } 4840c91c449Smrg } && 4850c91c449Smrg 4860c91c449Smrg # Now rename the file to the real destination. 4870c91c449Smrg $doit $mvcmd "$dsttmp" "$dst" 488a005d216Smrg } 489a005d216Smrg fi || exit 1 490ff7e0accSmrg 491ff7e0accSmrg trap '' 0 492ff7e0accSmrg fi 493ff7e0accSmrgdone 494ff7e0accSmrg 495ff7e0accSmrg# Local variables: 496ff7e0accSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 497ff7e0accSmrg# time-stamp-start: "scriptversion=" 498ff7e0accSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 49910998002Smrg# time-stamp-time-zone: "UTC" 50010998002Smrg# time-stamp-end: "; # UTC" 501ff7e0accSmrg# End: 502