install-sh revision b2f5b1db
10eb10989Smrg#!/bin/sh 20eb10989Smrg# install - install a program, script, or datafile 30eb10989Smrg 4b2f5b1dbSmrgscriptversion=2013-12-25.23; # UTC 50eb10989Smrg 60eb10989Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 70eb10989Smrg# later released in X11R6 (xc/config/util/install.sh) with the 80eb10989Smrg# following copyright and license. 90eb10989Smrg# 100eb10989Smrg# Copyright (C) 1994 X Consortium 110eb10989Smrg# 120eb10989Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 130eb10989Smrg# of this software and associated documentation files (the "Software"), to 140eb10989Smrg# deal in the Software without restriction, including without limitation the 150eb10989Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 160eb10989Smrg# sell copies of the Software, and to permit persons to whom the Software is 170eb10989Smrg# furnished to do so, subject to the following conditions: 180eb10989Smrg# 190eb10989Smrg# The above copyright notice and this permission notice shall be included in 200eb10989Smrg# all copies or substantial portions of the Software. 210eb10989Smrg# 220eb10989Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 230eb10989Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 240eb10989Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 250eb10989Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 260eb10989Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 270eb10989Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 280eb10989Smrg# 290eb10989Smrg# Except as contained in this notice, the name of the X Consortium shall not 300eb10989Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 310eb10989Smrg# ings in this Software without prior written authorization from the X Consor- 320eb10989Smrg# tium. 330eb10989Smrg# 340eb10989Smrg# 350eb10989Smrg# FSF changes to this file are in the public domain. 360eb10989Smrg# 370eb10989Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38079e7944Smrg# 'make' implicit rules from creating a file called install from it 390eb10989Smrg# when there is no Makefile. 400eb10989Smrg# 410eb10989Smrg# This script is compatible with the BSD install script, but was written 4263165362Smrg# from scratch. 4363165362Smrg 44b2f5b1dbSmrgtab=' ' 4563165362Smrgnl=' 4663165362Smrg' 47b2f5b1dbSmrgIFS=" $tab$nl" 480eb10989Smrg 49b2f5b1dbSmrg# Set DOITPROG to "echo" to test this script. 500eb10989Smrg 5163165362Smrgdoit=${DOITPROG-} 52b2f5b1dbSmrgdoit_exec=${doit:-exec} 530eb10989Smrg 5463165362Smrg# Put in absolute file names if you don't have them in your path; 5563165362Smrg# or use environment vars. 5663165362Smrg 5763165362Smrgchgrpprog=${CHGRPPROG-chgrp} 5863165362Smrgchmodprog=${CHMODPROG-chmod} 5963165362Smrgchownprog=${CHOWNPROG-chown} 6063165362Smrgcmpprog=${CMPPROG-cmp} 6163165362Smrgcpprog=${CPPROG-cp} 6263165362Smrgmkdirprog=${MKDIRPROG-mkdir} 6363165362Smrgmvprog=${MVPROG-mv} 6463165362Smrgrmprog=${RMPROG-rm} 6563165362Smrgstripprog=${STRIPPROG-strip} 6663165362Smrg 6763165362Smrgposix_mkdir= 6863165362Smrg 6963165362Smrg# Desired mode of installed file. 7063165362Smrgmode=0755 710eb10989Smrg 720eb10989Smrgchgrpcmd= 7363165362Smrgchmodcmd=$chmodprog 7463165362Smrgchowncmd= 7563165362Smrgmvcmd=$mvprog 760eb10989Smrgrmcmd="$rmprog -f" 7763165362Smrgstripcmd= 7863165362Smrg 790eb10989Smrgsrc= 800eb10989Smrgdst= 810eb10989Smrgdir_arg= 8263165362Smrgdst_arg= 8363165362Smrg 8463165362Smrgcopy_on_change=false 85b2f5b1dbSmrgis_target_a_directory=possibly 860eb10989Smrg 8763165362Smrgusage="\ 8863165362SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 890eb10989Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 900eb10989Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 910eb10989Smrg or: $0 [OPTION]... -d DIRECTORIES... 920eb10989Smrg 930eb10989SmrgIn the 1st form, copy SRCFILE to DSTFILE. 940eb10989SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 950eb10989SmrgIn the 4th, create DIRECTORIES. 960eb10989Smrg 970eb10989SmrgOptions: 9863165362Smrg --help display this help and exit. 9963165362Smrg --version display version info and exit. 10063165362Smrg 10163165362Smrg -c (ignored) 10263165362Smrg -C install only if different (preserve the last data modification time) 10363165362Smrg -d create directories instead of installing files. 10463165362Smrg -g GROUP $chgrpprog installed files to GROUP. 10563165362Smrg -m MODE $chmodprog installed files to MODE. 10663165362Smrg -o USER $chownprog installed files to USER. 10763165362Smrg -s $stripprog installed files. 10863165362Smrg -t DIRECTORY install into DIRECTORY. 10963165362Smrg -T report an error if DSTFILE is a directory. 1100eb10989Smrg 1110eb10989SmrgEnvironment variables override the default commands: 11263165362Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11363165362Smrg RMPROG STRIPPROG 1140eb10989Smrg" 1150eb10989Smrg 11663165362Smrgwhile test $# -ne 0; do 1170eb10989Smrg case $1 in 11863165362Smrg -c) ;; 11963165362Smrg 12063165362Smrg -C) copy_on_change=true;; 1210eb10989Smrg 12263165362Smrg -d) dir_arg=true;; 1230eb10989Smrg 1240eb10989Smrg -g) chgrpcmd="$chgrpprog $2" 125b2f5b1dbSmrg shift;; 1260eb10989Smrg 1270eb10989Smrg --help) echo "$usage"; exit $?;; 1280eb10989Smrg 12963165362Smrg -m) mode=$2 130b2f5b1dbSmrg case $mode in 131b2f5b1dbSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132b2f5b1dbSmrg echo "$0: invalid mode: $mode" >&2 133b2f5b1dbSmrg exit 1;; 134b2f5b1dbSmrg esac 135b2f5b1dbSmrg shift;; 1360eb10989Smrg 1370eb10989Smrg -o) chowncmd="$chownprog $2" 138b2f5b1dbSmrg shift;; 1390eb10989Smrg 14063165362Smrg -s) stripcmd=$stripprog;; 1410eb10989Smrg 142b2f5b1dbSmrg -t) 143b2f5b1dbSmrg is_target_a_directory=always 144b2f5b1dbSmrg dst_arg=$2 145b2f5b1dbSmrg # Protect names problematic for 'test' and other utilities. 146b2f5b1dbSmrg case $dst_arg in 147b2f5b1dbSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148b2f5b1dbSmrg esac 149b2f5b1dbSmrg shift;; 1500eb10989Smrg 151b2f5b1dbSmrg -T) is_target_a_directory=never;; 1520eb10989Smrg 1530eb10989Smrg --version) echo "$0 $scriptversion"; exit $?;; 1540eb10989Smrg 155b2f5b1dbSmrg --) shift 156b2f5b1dbSmrg break;; 15763165362Smrg 158b2f5b1dbSmrg -*) echo "$0: invalid option: $1" >&2 159b2f5b1dbSmrg exit 1;; 16063165362Smrg 16163165362Smrg *) break;; 1620eb10989Smrg esac 16363165362Smrg shift 1640eb10989Smrgdone 1650eb10989Smrg 166b2f5b1dbSmrg# We allow the use of options -d and -T together, by making -d 167b2f5b1dbSmrg# take the precedence; this is for compatibility with GNU install. 168b2f5b1dbSmrg 169b2f5b1dbSmrgif test -n "$dir_arg"; then 170b2f5b1dbSmrg if test -n "$dst_arg"; then 171b2f5b1dbSmrg echo "$0: target directory not allowed when installing a directory." >&2 172b2f5b1dbSmrg exit 1 173b2f5b1dbSmrg fi 174b2f5b1dbSmrgfi 175b2f5b1dbSmrg 17663165362Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17763165362Smrg # When -d is used, all remaining arguments are directories to create. 17863165362Smrg # When -t is used, the destination is already specified. 17963165362Smrg # Otherwise, the last argument is the destination. Remove it from $@. 18063165362Smrg for arg 18163165362Smrg do 18263165362Smrg if test -n "$dst_arg"; then 18363165362Smrg # $@ is not empty: it contains at least $arg. 18463165362Smrg set fnord "$@" "$dst_arg" 18563165362Smrg shift # fnord 18663165362Smrg fi 18763165362Smrg shift # arg 18863165362Smrg dst_arg=$arg 189079e7944Smrg # Protect names problematic for 'test' and other utilities. 190079e7944Smrg case $dst_arg in 191079e7944Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192079e7944Smrg esac 19363165362Smrg done 19463165362Smrgfi 19563165362Smrg 19663165362Smrgif test $# -eq 0; then 1970eb10989Smrg if test -z "$dir_arg"; then 1980eb10989Smrg echo "$0: no input file specified." >&2 1990eb10989Smrg exit 1 2000eb10989Smrg fi 201079e7944Smrg # It's OK to call 'install-sh -d' without argument. 2020eb10989Smrg # This can happen when creating conditional directories. 2030eb10989Smrg exit 0 2040eb10989Smrgfi 2050eb10989Smrg 206b2f5b1dbSmrgif test -z "$dir_arg"; then 207b2f5b1dbSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208b2f5b1dbSmrg if test ! -d "$dst_arg"; then 209b2f5b1dbSmrg echo "$0: $dst_arg: Is not a directory." >&2 210b2f5b1dbSmrg exit 1 211b2f5b1dbSmrg fi 212b2f5b1dbSmrg fi 213b2f5b1dbSmrgfi 214b2f5b1dbSmrg 21563165362Smrgif test -z "$dir_arg"; then 216079e7944Smrg do_exit='(exit $ret); exit $ret' 217079e7944Smrg trap "ret=129; $do_exit" 1 218079e7944Smrg trap "ret=130; $do_exit" 2 219079e7944Smrg trap "ret=141; $do_exit" 13 220079e7944Smrg trap "ret=143; $do_exit" 15 22163165362Smrg 22263165362Smrg # Set umask so as not to create temps with too-generous modes. 22363165362Smrg # However, 'strip' requires both read and write access to temps. 22463165362Smrg case $mode in 22563165362Smrg # Optimize common cases. 22663165362Smrg *644) cp_umask=133;; 22763165362Smrg *755) cp_umask=22;; 22863165362Smrg 22963165362Smrg *[0-7]) 23063165362Smrg if test -z "$stripcmd"; then 231b2f5b1dbSmrg u_plus_rw= 23263165362Smrg else 233b2f5b1dbSmrg u_plus_rw='% 200' 23463165362Smrg fi 23563165362Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23663165362Smrg *) 23763165362Smrg if test -z "$stripcmd"; then 238b2f5b1dbSmrg u_plus_rw= 23963165362Smrg else 240b2f5b1dbSmrg u_plus_rw=,u+rw 24163165362Smrg fi 24263165362Smrg cp_umask=$mode$u_plus_rw;; 24363165362Smrg esac 24463165362Smrgfi 24563165362Smrg 2460eb10989Smrgfor src 2470eb10989Smrgdo 248079e7944Smrg # Protect names problematic for 'test' and other utilities. 2490eb10989Smrg case $src in 250079e7944Smrg -* | [=\(\)!]) src=./$src;; 2510eb10989Smrg esac 2520eb10989Smrg 2530eb10989Smrg if test -n "$dir_arg"; then 2540eb10989Smrg dst=$src 25563165362Smrg dstdir=$dst 25663165362Smrg test -d "$dstdir" 25763165362Smrg dstdir_status=$? 2580eb10989Smrg else 25963165362Smrg 2600eb10989Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2610eb10989Smrg # might cause directories to be created, which would be especially bad 2620eb10989Smrg # if $src (and thus $dsttmp) contains '*'. 2630eb10989Smrg if test ! -f "$src" && test ! -d "$src"; then 2640eb10989Smrg echo "$0: $src does not exist." >&2 2650eb10989Smrg exit 1 2660eb10989Smrg fi 2670eb10989Smrg 26863165362Smrg if test -z "$dst_arg"; then 2690eb10989Smrg echo "$0: no destination specified." >&2 2700eb10989Smrg exit 1 2710eb10989Smrg fi 27263165362Smrg dst=$dst_arg 2730eb10989Smrg 2740eb10989Smrg # If destination is a directory, append the input filename; won't work 2750eb10989Smrg # if double slashes aren't ignored. 2760eb10989Smrg if test -d "$dst"; then 277b2f5b1dbSmrg if test "$is_target_a_directory" = never; then 278b2f5b1dbSmrg echo "$0: $dst_arg: Is a directory" >&2 279b2f5b1dbSmrg exit 1 2800eb10989Smrg fi 28163165362Smrg dstdir=$dst 28263165362Smrg dst=$dstdir/`basename "$src"` 28363165362Smrg dstdir_status=0 28463165362Smrg else 285b2f5b1dbSmrg dstdir=`dirname "$dst"` 28663165362Smrg test -d "$dstdir" 28763165362Smrg dstdir_status=$? 2880eb10989Smrg fi 2890eb10989Smrg fi 2900eb10989Smrg 29163165362Smrg obsolete_mkdir_used=false 29263165362Smrg 29363165362Smrg if test $dstdir_status != 0; then 29463165362Smrg case $posix_mkdir in 29563165362Smrg '') 296b2f5b1dbSmrg # Create intermediate dirs using mode 755 as modified by the umask. 297b2f5b1dbSmrg # This is like FreeBSD 'install' as of 1997-10-28. 298b2f5b1dbSmrg umask=`umask` 299b2f5b1dbSmrg case $stripcmd.$umask in 300b2f5b1dbSmrg # Optimize common cases. 301b2f5b1dbSmrg *[2367][2367]) mkdir_umask=$umask;; 302b2f5b1dbSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303b2f5b1dbSmrg 304b2f5b1dbSmrg *[0-7]) 305b2f5b1dbSmrg mkdir_umask=`expr $umask + 22 \ 306b2f5b1dbSmrg - $umask % 100 % 40 + $umask % 20 \ 307b2f5b1dbSmrg - $umask % 10 % 4 + $umask % 2 308b2f5b1dbSmrg `;; 309b2f5b1dbSmrg *) mkdir_umask=$umask,go-w;; 310b2f5b1dbSmrg esac 311b2f5b1dbSmrg 312b2f5b1dbSmrg # With -d, create the new directory with the user-specified mode. 313b2f5b1dbSmrg # Otherwise, rely on $mkdir_umask. 314b2f5b1dbSmrg if test -n "$dir_arg"; then 315b2f5b1dbSmrg mkdir_mode=-m$mode 316b2f5b1dbSmrg else 317b2f5b1dbSmrg mkdir_mode= 318b2f5b1dbSmrg fi 319b2f5b1dbSmrg 320b2f5b1dbSmrg posix_mkdir=false 321b2f5b1dbSmrg case $umask in 322b2f5b1dbSmrg *[123567][0-7][0-7]) 323b2f5b1dbSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324b2f5b1dbSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325b2f5b1dbSmrg ;; 326b2f5b1dbSmrg *) 327b2f5b1dbSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328b2f5b1dbSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329b2f5b1dbSmrg 330b2f5b1dbSmrg if (umask $mkdir_umask && 331b2f5b1dbSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332b2f5b1dbSmrg then 333b2f5b1dbSmrg if test -z "$dir_arg" || { 334b2f5b1dbSmrg # Check for POSIX incompatibilities with -m. 335b2f5b1dbSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336b2f5b1dbSmrg # other-writable bit of parent directory when it shouldn't. 337b2f5b1dbSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338b2f5b1dbSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339b2f5b1dbSmrg case $ls_ld_tmpdir in 340b2f5b1dbSmrg d????-?r-*) different_mode=700;; 341b2f5b1dbSmrg d????-?--*) different_mode=755;; 342b2f5b1dbSmrg *) false;; 343b2f5b1dbSmrg esac && 344b2f5b1dbSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345b2f5b1dbSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346b2f5b1dbSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347b2f5b1dbSmrg } 348b2f5b1dbSmrg } 349b2f5b1dbSmrg then posix_mkdir=: 350b2f5b1dbSmrg fi 351b2f5b1dbSmrg rmdir "$tmpdir/d" "$tmpdir" 352b2f5b1dbSmrg else 353b2f5b1dbSmrg # Remove any dirs left behind by ancient mkdir implementations. 354b2f5b1dbSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355b2f5b1dbSmrg fi 356b2f5b1dbSmrg trap '' 0;; 357b2f5b1dbSmrg esac;; 35863165362Smrg esac 3590eb10989Smrg 36063165362Smrg if 36163165362Smrg $posix_mkdir && ( 362b2f5b1dbSmrg umask $mkdir_umask && 363b2f5b1dbSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 36463165362Smrg ) 36563165362Smrg then : 36663165362Smrg else 3670eb10989Smrg 36863165362Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 36963165362Smrg # or it failed possibly due to a race condition. Create the 37063165362Smrg # directory the slow way, step by step, checking for races as we go. 3710eb10989Smrg 37263165362Smrg case $dstdir in 373b2f5b1dbSmrg /*) prefix='/';; 374b2f5b1dbSmrg [-=\(\)!]*) prefix='./';; 375b2f5b1dbSmrg *) prefix='';; 37663165362Smrg esac 3770eb10989Smrg 37863165362Smrg oIFS=$IFS 37963165362Smrg IFS=/ 380b2f5b1dbSmrg set -f 38163165362Smrg set fnord $dstdir 3820eb10989Smrg shift 383b2f5b1dbSmrg set +f 38463165362Smrg IFS=$oIFS 38563165362Smrg 38663165362Smrg prefixes= 38763165362Smrg 38863165362Smrg for d 38963165362Smrg do 390b2f5b1dbSmrg test X"$d" = X && continue 391b2f5b1dbSmrg 392b2f5b1dbSmrg prefix=$prefix$d 393b2f5b1dbSmrg if test -d "$prefix"; then 394b2f5b1dbSmrg prefixes= 395b2f5b1dbSmrg else 396b2f5b1dbSmrg if $posix_mkdir; then 397b2f5b1dbSmrg (umask=$mkdir_umask && 398b2f5b1dbSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399b2f5b1dbSmrg # Don't fail if two instances are running concurrently. 400b2f5b1dbSmrg test -d "$prefix" || exit 1 401b2f5b1dbSmrg else 402b2f5b1dbSmrg case $prefix in 403b2f5b1dbSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404b2f5b1dbSmrg *) qprefix=$prefix;; 405b2f5b1dbSmrg esac 406b2f5b1dbSmrg prefixes="$prefixes '$qprefix'" 407b2f5b1dbSmrg fi 408b2f5b1dbSmrg fi 409b2f5b1dbSmrg prefix=$prefix/ 41063165362Smrg done 41163165362Smrg 41263165362Smrg if test -n "$prefixes"; then 413b2f5b1dbSmrg # Don't fail if two instances are running concurrently. 414b2f5b1dbSmrg (umask $mkdir_umask && 415b2f5b1dbSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 416b2f5b1dbSmrg test -d "$dstdir" || exit 1 417b2f5b1dbSmrg obsolete_mkdir_used=true 4180eb10989Smrg fi 41963165362Smrg fi 4200eb10989Smrg fi 4210eb10989Smrg 4220eb10989Smrg if test -n "$dir_arg"; then 42363165362Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 42463165362Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 42563165362Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 42663165362Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4270eb10989Smrg else 4280eb10989Smrg 4290eb10989Smrg # Make a couple of temp file names in the proper directory. 4300eb10989Smrg dsttmp=$dstdir/_inst.$$_ 4310eb10989Smrg rmtmp=$dstdir/_rm.$$_ 4320eb10989Smrg 4330eb10989Smrg # Trap to clean up those temp files at exit. 4340eb10989Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4350eb10989Smrg 4360eb10989Smrg # Copy the file name to the temp name. 43763165362Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4380eb10989Smrg 4390eb10989Smrg # and set any options; do chmod last to preserve setuid bits. 4400eb10989Smrg # 4410eb10989Smrg # If any of these fail, we abort the whole thing. If we want to 4420eb10989Smrg # ignore errors from any of these, just make sure not to ignore 4430eb10989Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4440eb10989Smrg # 44563165362Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 44663165362Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 44763165362Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 44863165362Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 44963165362Smrg 45063165362Smrg # If -C, don't bother to copy if it wouldn't change the file. 45163165362Smrg if $copy_on_change && 452b2f5b1dbSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453b2f5b1dbSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454b2f5b1dbSmrg set -f && 45563165362Smrg set X $old && old=:$2:$4:$5:$6 && 45663165362Smrg set X $new && new=:$2:$4:$5:$6 && 457b2f5b1dbSmrg set +f && 45863165362Smrg test "$old" = "$new" && 45963165362Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 46063165362Smrg then 46163165362Smrg rm -f "$dsttmp" 46263165362Smrg else 46363165362Smrg # Rename the file to the real destination. 46463165362Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 46563165362Smrg 46663165362Smrg # The rename failed, perhaps because mv can't rename something else 46763165362Smrg # to itself, or perhaps because mv is so ancient that it does not 46863165362Smrg # support -f. 46963165362Smrg { 470b2f5b1dbSmrg # Now remove or move aside any old file at destination location. 471b2f5b1dbSmrg # We try this two ways since rm can't unlink itself on some 472b2f5b1dbSmrg # systems and the destination file might be busy for other 473b2f5b1dbSmrg # reasons. In this case, the final cleanup might fail but the new 474b2f5b1dbSmrg # file should still install successfully. 475b2f5b1dbSmrg { 476b2f5b1dbSmrg test ! -f "$dst" || 477b2f5b1dbSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 478b2f5b1dbSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479b2f5b1dbSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480b2f5b1dbSmrg } || 481b2f5b1dbSmrg { echo "$0: cannot unlink or rename $dst" >&2 482b2f5b1dbSmrg (exit 1); exit 1 483b2f5b1dbSmrg } 484b2f5b1dbSmrg } && 485b2f5b1dbSmrg 486b2f5b1dbSmrg # Now rename the file to the real destination. 487b2f5b1dbSmrg $doit $mvcmd "$dsttmp" "$dst" 48863165362Smrg } 48963165362Smrg fi || exit 1 49063165362Smrg 49163165362Smrg trap '' 0 49263165362Smrg fi 4930eb10989Smrgdone 4940eb10989Smrg 4950eb10989Smrg# Local variables: 4960eb10989Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 4970eb10989Smrg# time-stamp-start: "scriptversion=" 4980eb10989Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 49963165362Smrg# time-stamp-time-zone: "UTC" 50063165362Smrg# time-stamp-end: "; # UTC" 5010eb10989Smrg# End: 502