install-sh revision 33dddc75
172b4363aSmrg#!/bin/sh 272b4363aSmrg# install - install a program, script, or datafile 372b4363aSmrg 433dddc75Smrgscriptversion=2013-12-25.23; # UTC 572b4363aSmrg 672b4363aSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 772b4363aSmrg# later released in X11R6 (xc/config/util/install.sh) with the 872b4363aSmrg# following copyright and license. 972b4363aSmrg# 1072b4363aSmrg# Copyright (C) 1994 X Consortium 1172b4363aSmrg# 1272b4363aSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1372b4363aSmrg# of this software and associated documentation files (the "Software"), to 1472b4363aSmrg# deal in the Software without restriction, including without limitation the 1572b4363aSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1672b4363aSmrg# sell copies of the Software, and to permit persons to whom the Software is 1772b4363aSmrg# furnished to do so, subject to the following conditions: 1872b4363aSmrg# 1972b4363aSmrg# The above copyright notice and this permission notice shall be included in 2072b4363aSmrg# all copies or substantial portions of the Software. 2172b4363aSmrg# 2272b4363aSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2372b4363aSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2472b4363aSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2572b4363aSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2672b4363aSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2772b4363aSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2872b4363aSmrg# 2972b4363aSmrg# Except as contained in this notice, the name of the X Consortium shall not 3072b4363aSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 3172b4363aSmrg# ings in this Software without prior written authorization from the X Consor- 3272b4363aSmrg# tium. 3372b4363aSmrg# 3472b4363aSmrg# 3572b4363aSmrg# FSF changes to this file are in the public domain. 3672b4363aSmrg# 3772b4363aSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3833dddc75Smrg# 'make' implicit rules from creating a file called install from it 3972b4363aSmrg# when there is no Makefile. 4072b4363aSmrg# 4172b4363aSmrg# This script is compatible with the BSD install script, but was written 4272b4363aSmrg# from scratch. 4372b4363aSmrg 4433dddc75Smrgtab=' ' 4572b4363aSmrgnl=' 4672b4363aSmrg' 4733dddc75SmrgIFS=" $tab$nl" 4872b4363aSmrg 4933dddc75Smrg# Set DOITPROG to "echo" to test this script. 5072b4363aSmrg 51dd77ae96Smrgdoit=${DOITPROG-} 5233dddc75Smrgdoit_exec=${doit:-exec} 5372b4363aSmrg 5472b4363aSmrg# Put in absolute file names if you don't have them in your path; 5572b4363aSmrg# or use environment vars. 5672b4363aSmrg 57dd77ae96Smrgchgrpprog=${CHGRPPROG-chgrp} 58dd77ae96Smrgchmodprog=${CHMODPROG-chmod} 59dd77ae96Smrgchownprog=${CHOWNPROG-chown} 60dd77ae96Smrgcmpprog=${CMPPROG-cmp} 61dd77ae96Smrgcpprog=${CPPROG-cp} 62dd77ae96Smrgmkdirprog=${MKDIRPROG-mkdir} 63dd77ae96Smrgmvprog=${MVPROG-mv} 64dd77ae96Smrgrmprog=${RMPROG-rm} 65dd77ae96Smrgstripprog=${STRIPPROG-strip} 66dd77ae96Smrg 6772b4363aSmrgposix_mkdir= 6872b4363aSmrg 6972b4363aSmrg# Desired mode of installed file. 7072b4363aSmrgmode=0755 7172b4363aSmrg 72dd77ae96Smrgchgrpcmd= 7372b4363aSmrgchmodcmd=$chmodprog 7472b4363aSmrgchowncmd= 75dd77ae96Smrgmvcmd=$mvprog 7672b4363aSmrgrmcmd="$rmprog -f" 77dd77ae96Smrgstripcmd= 78dd77ae96Smrg 7972b4363aSmrgsrc= 8072b4363aSmrgdst= 8172b4363aSmrgdir_arg= 82dd77ae96Smrgdst_arg= 83dd77ae96Smrg 84dd77ae96Smrgcopy_on_change=false 8533dddc75Smrgis_target_a_directory=possibly 8672b4363aSmrg 87dd77ae96Smrgusage="\ 88dd77ae96SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 8972b4363aSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 9072b4363aSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9172b4363aSmrg or: $0 [OPTION]... -d DIRECTORIES... 9272b4363aSmrg 9372b4363aSmrgIn the 1st form, copy SRCFILE to DSTFILE. 9472b4363aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 9572b4363aSmrgIn the 4th, create DIRECTORIES. 9672b4363aSmrg 9772b4363aSmrgOptions: 98dd77ae96Smrg --help display this help and exit. 99dd77ae96Smrg --version display version info and exit. 100dd77ae96Smrg 101dd77ae96Smrg -c (ignored) 102dd77ae96Smrg -C install only if different (preserve the last data modification time) 103dd77ae96Smrg -d create directories instead of installing files. 104dd77ae96Smrg -g GROUP $chgrpprog installed files to GROUP. 105dd77ae96Smrg -m MODE $chmodprog installed files to MODE. 106dd77ae96Smrg -o USER $chownprog installed files to USER. 107dd77ae96Smrg -s $stripprog installed files. 108dd77ae96Smrg -t DIRECTORY install into DIRECTORY. 109dd77ae96Smrg -T report an error if DSTFILE is a directory. 11072b4363aSmrg 11172b4363aSmrgEnvironment variables override the default commands: 112dd77ae96Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113dd77ae96Smrg RMPROG STRIPPROG 11472b4363aSmrg" 11572b4363aSmrg 11672b4363aSmrgwhile test $# -ne 0; do 11772b4363aSmrg case $1 in 118dd77ae96Smrg -c) ;; 119dd77ae96Smrg 120dd77ae96Smrg -C) copy_on_change=true;; 12172b4363aSmrg 122dd77ae96Smrg -d) dir_arg=true;; 12372b4363aSmrg 12472b4363aSmrg -g) chgrpcmd="$chgrpprog $2" 12533dddc75Smrg shift;; 12672b4363aSmrg 12772b4363aSmrg --help) echo "$usage"; exit $?;; 12872b4363aSmrg 12972b4363aSmrg -m) mode=$2 13033dddc75Smrg case $mode in 13133dddc75Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 13233dddc75Smrg echo "$0: invalid mode: $mode" >&2 13333dddc75Smrg exit 1;; 13433dddc75Smrg esac 13533dddc75Smrg shift;; 13672b4363aSmrg 13772b4363aSmrg -o) chowncmd="$chownprog $2" 13833dddc75Smrg shift;; 13972b4363aSmrg 140dd77ae96Smrg -s) stripcmd=$stripprog;; 14172b4363aSmrg 14233dddc75Smrg -t) 14333dddc75Smrg is_target_a_directory=always 14433dddc75Smrg dst_arg=$2 14533dddc75Smrg # Protect names problematic for 'test' and other utilities. 14633dddc75Smrg case $dst_arg in 14733dddc75Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 14833dddc75Smrg esac 14933dddc75Smrg shift;; 15072b4363aSmrg 15133dddc75Smrg -T) is_target_a_directory=never;; 15272b4363aSmrg 15372b4363aSmrg --version) echo "$0 $scriptversion"; exit $?;; 15472b4363aSmrg 15533dddc75Smrg --) shift 15633dddc75Smrg break;; 15772b4363aSmrg 15833dddc75Smrg -*) echo "$0: invalid option: $1" >&2 15933dddc75Smrg exit 1;; 16072b4363aSmrg 16172b4363aSmrg *) break;; 16272b4363aSmrg esac 163dd77ae96Smrg shift 16472b4363aSmrgdone 16572b4363aSmrg 16633dddc75Smrg# We allow the use of options -d and -T together, by making -d 16733dddc75Smrg# take the precedence; this is for compatibility with GNU install. 16833dddc75Smrg 16933dddc75Smrgif test -n "$dir_arg"; then 17033dddc75Smrg if test -n "$dst_arg"; then 17133dddc75Smrg echo "$0: target directory not allowed when installing a directory." >&2 17233dddc75Smrg exit 1 17333dddc75Smrg fi 17433dddc75Smrgfi 17533dddc75Smrg 176dd77ae96Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17772b4363aSmrg # When -d is used, all remaining arguments are directories to create. 17872b4363aSmrg # When -t is used, the destination is already specified. 17972b4363aSmrg # Otherwise, the last argument is the destination. Remove it from $@. 18072b4363aSmrg for arg 18172b4363aSmrg do 182dd77ae96Smrg if test -n "$dst_arg"; then 18372b4363aSmrg # $@ is not empty: it contains at least $arg. 184dd77ae96Smrg set fnord "$@" "$dst_arg" 18572b4363aSmrg shift # fnord 18672b4363aSmrg fi 18772b4363aSmrg shift # arg 188dd77ae96Smrg dst_arg=$arg 18933dddc75Smrg # Protect names problematic for 'test' and other utilities. 19033dddc75Smrg case $dst_arg in 19133dddc75Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 19233dddc75Smrg esac 19372b4363aSmrg done 19472b4363aSmrgfi 19572b4363aSmrg 19672b4363aSmrgif test $# -eq 0; then 19772b4363aSmrg if test -z "$dir_arg"; then 19872b4363aSmrg echo "$0: no input file specified." >&2 19972b4363aSmrg exit 1 20072b4363aSmrg fi 20133dddc75Smrg # It's OK to call 'install-sh -d' without argument. 20272b4363aSmrg # This can happen when creating conditional directories. 20372b4363aSmrg exit 0 20472b4363aSmrgfi 20572b4363aSmrg 20672b4363aSmrgif test -z "$dir_arg"; then 20733dddc75Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 20833dddc75Smrg if test ! -d "$dst_arg"; then 20933dddc75Smrg echo "$0: $dst_arg: Is not a directory." >&2 21033dddc75Smrg exit 1 21133dddc75Smrg fi 21233dddc75Smrg fi 21333dddc75Smrgfi 21433dddc75Smrg 21533dddc75Smrgif test -z "$dir_arg"; then 21633dddc75Smrg do_exit='(exit $ret); exit $ret' 21733dddc75Smrg trap "ret=129; $do_exit" 1 21833dddc75Smrg trap "ret=130; $do_exit" 2 21933dddc75Smrg trap "ret=141; $do_exit" 13 22033dddc75Smrg trap "ret=143; $do_exit" 15 22172b4363aSmrg 22272b4363aSmrg # Set umask so as not to create temps with too-generous modes. 22372b4363aSmrg # However, 'strip' requires both read and write access to temps. 22472b4363aSmrg case $mode in 22572b4363aSmrg # Optimize common cases. 22672b4363aSmrg *644) cp_umask=133;; 22772b4363aSmrg *755) cp_umask=22;; 22872b4363aSmrg 22972b4363aSmrg *[0-7]) 23072b4363aSmrg if test -z "$stripcmd"; then 23133dddc75Smrg u_plus_rw= 23272b4363aSmrg else 23333dddc75Smrg u_plus_rw='% 200' 23472b4363aSmrg fi 23572b4363aSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23672b4363aSmrg *) 23772b4363aSmrg if test -z "$stripcmd"; then 23833dddc75Smrg u_plus_rw= 23972b4363aSmrg else 24033dddc75Smrg u_plus_rw=,u+rw 24172b4363aSmrg fi 24272b4363aSmrg cp_umask=$mode$u_plus_rw;; 24372b4363aSmrg esac 24472b4363aSmrgfi 24572b4363aSmrg 24672b4363aSmrgfor src 24772b4363aSmrgdo 24833dddc75Smrg # Protect names problematic for 'test' and other utilities. 24972b4363aSmrg case $src in 25033dddc75Smrg -* | [=\(\)!]) src=./$src;; 25172b4363aSmrg esac 25272b4363aSmrg 25372b4363aSmrg if test -n "$dir_arg"; then 25472b4363aSmrg dst=$src 25572b4363aSmrg dstdir=$dst 25672b4363aSmrg test -d "$dstdir" 25772b4363aSmrg dstdir_status=$? 25872b4363aSmrg else 25972b4363aSmrg 26072b4363aSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 26172b4363aSmrg # might cause directories to be created, which would be especially bad 26272b4363aSmrg # if $src (and thus $dsttmp) contains '*'. 26372b4363aSmrg if test ! -f "$src" && test ! -d "$src"; then 26472b4363aSmrg echo "$0: $src does not exist." >&2 26572b4363aSmrg exit 1 26672b4363aSmrg fi 26772b4363aSmrg 268dd77ae96Smrg if test -z "$dst_arg"; then 26972b4363aSmrg echo "$0: no destination specified." >&2 27072b4363aSmrg exit 1 27172b4363aSmrg fi 272dd77ae96Smrg dst=$dst_arg 27372b4363aSmrg 27472b4363aSmrg # If destination is a directory, append the input filename; won't work 27572b4363aSmrg # if double slashes aren't ignored. 27672b4363aSmrg if test -d "$dst"; then 27733dddc75Smrg if test "$is_target_a_directory" = never; then 27833dddc75Smrg echo "$0: $dst_arg: Is a directory" >&2 27933dddc75Smrg exit 1 28072b4363aSmrg fi 28172b4363aSmrg dstdir=$dst 28272b4363aSmrg dst=$dstdir/`basename "$src"` 28372b4363aSmrg dstdir_status=0 28472b4363aSmrg else 28533dddc75Smrg dstdir=`dirname "$dst"` 28672b4363aSmrg test -d "$dstdir" 28772b4363aSmrg dstdir_status=$? 28872b4363aSmrg fi 28972b4363aSmrg fi 29072b4363aSmrg 29172b4363aSmrg obsolete_mkdir_used=false 29272b4363aSmrg 29372b4363aSmrg if test $dstdir_status != 0; then 29472b4363aSmrg case $posix_mkdir in 29572b4363aSmrg '') 29633dddc75Smrg # Create intermediate dirs using mode 755 as modified by the umask. 29733dddc75Smrg # This is like FreeBSD 'install' as of 1997-10-28. 29833dddc75Smrg umask=`umask` 29933dddc75Smrg case $stripcmd.$umask in 30033dddc75Smrg # Optimize common cases. 30133dddc75Smrg *[2367][2367]) mkdir_umask=$umask;; 30233dddc75Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 30333dddc75Smrg 30433dddc75Smrg *[0-7]) 30533dddc75Smrg mkdir_umask=`expr $umask + 22 \ 30633dddc75Smrg - $umask % 100 % 40 + $umask % 20 \ 30733dddc75Smrg - $umask % 10 % 4 + $umask % 2 30833dddc75Smrg `;; 30933dddc75Smrg *) mkdir_umask=$umask,go-w;; 31033dddc75Smrg esac 31133dddc75Smrg 31233dddc75Smrg # With -d, create the new directory with the user-specified mode. 31333dddc75Smrg # Otherwise, rely on $mkdir_umask. 31433dddc75Smrg if test -n "$dir_arg"; then 31533dddc75Smrg mkdir_mode=-m$mode 31633dddc75Smrg else 31733dddc75Smrg mkdir_mode= 31833dddc75Smrg fi 31933dddc75Smrg 32033dddc75Smrg posix_mkdir=false 32133dddc75Smrg case $umask in 32233dddc75Smrg *[123567][0-7][0-7]) 32333dddc75Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 32433dddc75Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 32533dddc75Smrg ;; 32633dddc75Smrg *) 32733dddc75Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 32833dddc75Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 32933dddc75Smrg 33033dddc75Smrg if (umask $mkdir_umask && 33133dddc75Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 33233dddc75Smrg then 33333dddc75Smrg if test -z "$dir_arg" || { 33433dddc75Smrg # Check for POSIX incompatibilities with -m. 33533dddc75Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 33633dddc75Smrg # other-writable bit of parent directory when it shouldn't. 33733dddc75Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 33833dddc75Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 33933dddc75Smrg case $ls_ld_tmpdir in 34033dddc75Smrg d????-?r-*) different_mode=700;; 34133dddc75Smrg d????-?--*) different_mode=755;; 34233dddc75Smrg *) false;; 34333dddc75Smrg esac && 34433dddc75Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 34533dddc75Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 34633dddc75Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 34733dddc75Smrg } 34833dddc75Smrg } 34933dddc75Smrg then posix_mkdir=: 35033dddc75Smrg fi 35133dddc75Smrg rmdir "$tmpdir/d" "$tmpdir" 35233dddc75Smrg else 35333dddc75Smrg # Remove any dirs left behind by ancient mkdir implementations. 35433dddc75Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 35533dddc75Smrg fi 35633dddc75Smrg trap '' 0;; 35733dddc75Smrg esac;; 35872b4363aSmrg esac 35972b4363aSmrg 36072b4363aSmrg if 36172b4363aSmrg $posix_mkdir && ( 36233dddc75Smrg umask $mkdir_umask && 36333dddc75Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 36472b4363aSmrg ) 36572b4363aSmrg then : 36672b4363aSmrg else 36772b4363aSmrg 36872b4363aSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 36972b4363aSmrg # or it failed possibly due to a race condition. Create the 37072b4363aSmrg # directory the slow way, step by step, checking for races as we go. 37172b4363aSmrg 37272b4363aSmrg case $dstdir in 37333dddc75Smrg /*) prefix='/';; 37433dddc75Smrg [-=\(\)!]*) prefix='./';; 37533dddc75Smrg *) prefix='';; 37672b4363aSmrg esac 37772b4363aSmrg 37872b4363aSmrg oIFS=$IFS 37972b4363aSmrg IFS=/ 38033dddc75Smrg set -f 38172b4363aSmrg set fnord $dstdir 38272b4363aSmrg shift 38333dddc75Smrg set +f 38472b4363aSmrg IFS=$oIFS 38572b4363aSmrg 38672b4363aSmrg prefixes= 38772b4363aSmrg 38872b4363aSmrg for d 38972b4363aSmrg do 39033dddc75Smrg test X"$d" = X && continue 39133dddc75Smrg 39233dddc75Smrg prefix=$prefix$d 39333dddc75Smrg if test -d "$prefix"; then 39433dddc75Smrg prefixes= 39533dddc75Smrg else 39633dddc75Smrg if $posix_mkdir; then 39733dddc75Smrg (umask=$mkdir_umask && 39833dddc75Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 39933dddc75Smrg # Don't fail if two instances are running concurrently. 40033dddc75Smrg test -d "$prefix" || exit 1 40133dddc75Smrg else 40233dddc75Smrg case $prefix in 40333dddc75Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 40433dddc75Smrg *) qprefix=$prefix;; 40533dddc75Smrg esac 40633dddc75Smrg prefixes="$prefixes '$qprefix'" 40733dddc75Smrg fi 40833dddc75Smrg fi 40933dddc75Smrg prefix=$prefix/ 41072b4363aSmrg done 41172b4363aSmrg 41272b4363aSmrg if test -n "$prefixes"; then 41333dddc75Smrg # Don't fail if two instances are running concurrently. 41433dddc75Smrg (umask $mkdir_umask && 41533dddc75Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 41633dddc75Smrg test -d "$dstdir" || exit 1 41733dddc75Smrg obsolete_mkdir_used=true 41872b4363aSmrg fi 41972b4363aSmrg fi 42072b4363aSmrg fi 42172b4363aSmrg 42272b4363aSmrg if test -n "$dir_arg"; then 42372b4363aSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 42472b4363aSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 42572b4363aSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 42672b4363aSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 42772b4363aSmrg else 42872b4363aSmrg 42972b4363aSmrg # Make a couple of temp file names in the proper directory. 43072b4363aSmrg dsttmp=$dstdir/_inst.$$_ 43172b4363aSmrg rmtmp=$dstdir/_rm.$$_ 43272b4363aSmrg 43372b4363aSmrg # Trap to clean up those temp files at exit. 43472b4363aSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 43572b4363aSmrg 43672b4363aSmrg # Copy the file name to the temp name. 43772b4363aSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 43872b4363aSmrg 43972b4363aSmrg # and set any options; do chmod last to preserve setuid bits. 44072b4363aSmrg # 44172b4363aSmrg # If any of these fail, we abort the whole thing. If we want to 44272b4363aSmrg # ignore errors from any of these, just make sure not to ignore 44372b4363aSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 44472b4363aSmrg # 445dd77ae96Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 446dd77ae96Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 447dd77ae96Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 448dd77ae96Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 449dd77ae96Smrg 450dd77ae96Smrg # If -C, don't bother to copy if it wouldn't change the file. 451dd77ae96Smrg if $copy_on_change && 45233dddc75Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 45333dddc75Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 45433dddc75Smrg set -f && 455dd77ae96Smrg set X $old && old=:$2:$4:$5:$6 && 456dd77ae96Smrg set X $new && new=:$2:$4:$5:$6 && 45733dddc75Smrg set +f && 458dd77ae96Smrg test "$old" = "$new" && 459dd77ae96Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 460dd77ae96Smrg then 461dd77ae96Smrg rm -f "$dsttmp" 462dd77ae96Smrg else 463dd77ae96Smrg # Rename the file to the real destination. 464dd77ae96Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 465dd77ae96Smrg 466dd77ae96Smrg # The rename failed, perhaps because mv can't rename something else 467dd77ae96Smrg # to itself, or perhaps because mv is so ancient that it does not 468dd77ae96Smrg # support -f. 469dd77ae96Smrg { 47033dddc75Smrg # Now remove or move aside any old file at destination location. 47133dddc75Smrg # We try this two ways since rm can't unlink itself on some 47233dddc75Smrg # systems and the destination file might be busy for other 47333dddc75Smrg # reasons. In this case, the final cleanup might fail but the new 47433dddc75Smrg # file should still install successfully. 47533dddc75Smrg { 47633dddc75Smrg test ! -f "$dst" || 47733dddc75Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 47833dddc75Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 47933dddc75Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 48033dddc75Smrg } || 48133dddc75Smrg { echo "$0: cannot unlink or rename $dst" >&2 48233dddc75Smrg (exit 1); exit 1 48333dddc75Smrg } 48433dddc75Smrg } && 48533dddc75Smrg 48633dddc75Smrg # Now rename the file to the real destination. 48733dddc75Smrg $doit $mvcmd "$dsttmp" "$dst" 488dd77ae96Smrg } 489dd77ae96Smrg fi || exit 1 49072b4363aSmrg 49172b4363aSmrg trap '' 0 49272b4363aSmrg fi 49372b4363aSmrgdone 49472b4363aSmrg 49572b4363aSmrg# Local variables: 49672b4363aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 49772b4363aSmrg# time-stamp-start: "scriptversion=" 49872b4363aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 499dd77ae96Smrg# time-stamp-time-zone: "UTC" 500dd77ae96Smrg# time-stamp-end: "; # UTC" 50172b4363aSmrg# End: 502