install-sh revision 6ef05171
143f32c10Smrg#!/bin/sh 243f32c10Smrg# install - install a program, script, or datafile 343f32c10Smrg 46ef05171Smrgscriptversion=2016-01-11.22; # UTC 543f32c10Smrg 643f32c10Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 743f32c10Smrg# later released in X11R6 (xc/config/util/install.sh) with the 843f32c10Smrg# following copyright and license. 943f32c10Smrg# 1043f32c10Smrg# Copyright (C) 1994 X Consortium 1143f32c10Smrg# 1243f32c10Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1343f32c10Smrg# of this software and associated documentation files (the "Software"), to 1443f32c10Smrg# deal in the Software without restriction, including without limitation the 1543f32c10Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1643f32c10Smrg# sell copies of the Software, and to permit persons to whom the Software is 1743f32c10Smrg# furnished to do so, subject to the following conditions: 1843f32c10Smrg# 1943f32c10Smrg# The above copyright notice and this permission notice shall be included in 2043f32c10Smrg# all copies or substantial portions of the Software. 2143f32c10Smrg# 2243f32c10Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2343f32c10Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2443f32c10Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2543f32c10Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2643f32c10Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2743f32c10Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2843f32c10Smrg# 2943f32c10Smrg# Except as contained in this notice, the name of the X Consortium shall not 3043f32c10Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3143f32c10Smrg# ings in this Software without prior written authorization from the X Consor- 3243f32c10Smrg# tium. 3343f32c10Smrg# 3443f32c10Smrg# 3543f32c10Smrg# FSF changes to this file are in the public domain. 3643f32c10Smrg# 3743f32c10Smrg# Calling this script install-sh is preferred over install.sh, to prevent 386ef05171Smrg# 'make' implicit rules from creating a file called install from it 3943f32c10Smrg# when there is no Makefile. 4043f32c10Smrg# 4143f32c10Smrg# This script is compatible with the BSD install script, but was written 4243f32c10Smrg# from scratch. 4343f32c10Smrg 446ef05171Smrgtab=' ' 4543f32c10Smrgnl=' 4643f32c10Smrg' 476ef05171SmrgIFS=" $tab$nl" 4843f32c10Smrg 496ef05171Smrg# Set DOITPROG to "echo" to test this script. 5043f32c10Smrg 5143f32c10Smrgdoit=${DOITPROG-} 526ef05171Smrgdoit_exec=${doit:-exec} 5343f32c10Smrg 5443f32c10Smrg# Put in absolute file names if you don't have them in your path; 5543f32c10Smrg# or use environment vars. 5643f32c10Smrg 5743f32c10Smrgchgrpprog=${CHGRPPROG-chgrp} 5843f32c10Smrgchmodprog=${CHMODPROG-chmod} 5943f32c10Smrgchownprog=${CHOWNPROG-chown} 6043f32c10Smrgcmpprog=${CMPPROG-cmp} 6143f32c10Smrgcpprog=${CPPROG-cp} 6243f32c10Smrgmkdirprog=${MKDIRPROG-mkdir} 6343f32c10Smrgmvprog=${MVPROG-mv} 6443f32c10Smrgrmprog=${RMPROG-rm} 6543f32c10Smrgstripprog=${STRIPPROG-strip} 6643f32c10Smrg 6743f32c10Smrgposix_mkdir= 6843f32c10Smrg 6943f32c10Smrg# Desired mode of installed file. 7043f32c10Smrgmode=0755 7143f32c10Smrg 7243f32c10Smrgchgrpcmd= 7343f32c10Smrgchmodcmd=$chmodprog 7443f32c10Smrgchowncmd= 7543f32c10Smrgmvcmd=$mvprog 7643f32c10Smrgrmcmd="$rmprog -f" 7743f32c10Smrgstripcmd= 7843f32c10Smrg 7943f32c10Smrgsrc= 8043f32c10Smrgdst= 8143f32c10Smrgdir_arg= 8243f32c10Smrgdst_arg= 8343f32c10Smrg 8443f32c10Smrgcopy_on_change=false 856ef05171Smrgis_target_a_directory=possibly 8643f32c10Smrg 8743f32c10Smrgusage="\ 8843f32c10SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 8943f32c10Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 9043f32c10Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9143f32c10Smrg or: $0 [OPTION]... -d DIRECTORIES... 9243f32c10Smrg 9343f32c10SmrgIn the 1st form, copy SRCFILE to DSTFILE. 9443f32c10SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 9543f32c10SmrgIn the 4th, create DIRECTORIES. 9643f32c10Smrg 9743f32c10SmrgOptions: 9843f32c10Smrg --help display this help and exit. 9943f32c10Smrg --version display version info and exit. 10043f32c10Smrg 10143f32c10Smrg -c (ignored) 10243f32c10Smrg -C install only if different (preserve the last data modification time) 10343f32c10Smrg -d create directories instead of installing files. 10443f32c10Smrg -g GROUP $chgrpprog installed files to GROUP. 10543f32c10Smrg -m MODE $chmodprog installed files to MODE. 10643f32c10Smrg -o USER $chownprog installed files to USER. 10743f32c10Smrg -s $stripprog installed files. 10843f32c10Smrg -t DIRECTORY install into DIRECTORY. 10943f32c10Smrg -T report an error if DSTFILE is a directory. 11043f32c10Smrg 11143f32c10SmrgEnvironment variables override the default commands: 11243f32c10Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11343f32c10Smrg RMPROG STRIPPROG 11443f32c10Smrg" 11543f32c10Smrg 11643f32c10Smrgwhile test $# -ne 0; do 11743f32c10Smrg case $1 in 11843f32c10Smrg -c) ;; 11943f32c10Smrg 12043f32c10Smrg -C) copy_on_change=true;; 12143f32c10Smrg 12243f32c10Smrg -d) dir_arg=true;; 12343f32c10Smrg 12443f32c10Smrg -g) chgrpcmd="$chgrpprog $2" 1256ef05171Smrg shift;; 12643f32c10Smrg 12743f32c10Smrg --help) echo "$usage"; exit $?;; 12843f32c10Smrg 12943f32c10Smrg -m) mode=$2 1306ef05171Smrg case $mode in 1316ef05171Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1326ef05171Smrg echo "$0: invalid mode: $mode" >&2 1336ef05171Smrg exit 1;; 1346ef05171Smrg esac 1356ef05171Smrg shift;; 13643f32c10Smrg 13743f32c10Smrg -o) chowncmd="$chownprog $2" 1386ef05171Smrg shift;; 13943f32c10Smrg 14043f32c10Smrg -s) stripcmd=$stripprog;; 14143f32c10Smrg 1426ef05171Smrg -t) 1436ef05171Smrg is_target_a_directory=always 1446ef05171Smrg dst_arg=$2 1456ef05171Smrg # Protect names problematic for 'test' and other utilities. 1466ef05171Smrg case $dst_arg in 1476ef05171Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1486ef05171Smrg esac 1496ef05171Smrg shift;; 15043f32c10Smrg 1516ef05171Smrg -T) is_target_a_directory=never;; 15243f32c10Smrg 15343f32c10Smrg --version) echo "$0 $scriptversion"; exit $?;; 15443f32c10Smrg 1556ef05171Smrg --) shift 1566ef05171Smrg break;; 15743f32c10Smrg 1586ef05171Smrg -*) echo "$0: invalid option: $1" >&2 1596ef05171Smrg exit 1;; 16043f32c10Smrg 16143f32c10Smrg *) break;; 16243f32c10Smrg esac 16343f32c10Smrg shift 16443f32c10Smrgdone 16543f32c10Smrg 1666ef05171Smrg# We allow the use of options -d and -T together, by making -d 1676ef05171Smrg# take the precedence; this is for compatibility with GNU install. 1686ef05171Smrg 1696ef05171Smrgif test -n "$dir_arg"; then 1706ef05171Smrg if test -n "$dst_arg"; then 1716ef05171Smrg echo "$0: target directory not allowed when installing a directory." >&2 1726ef05171Smrg exit 1 1736ef05171Smrg fi 1746ef05171Smrgfi 1756ef05171Smrg 17643f32c10Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17743f32c10Smrg # When -d is used, all remaining arguments are directories to create. 17843f32c10Smrg # When -t is used, the destination is already specified. 17943f32c10Smrg # Otherwise, the last argument is the destination. Remove it from $@. 18043f32c10Smrg for arg 18143f32c10Smrg do 18243f32c10Smrg if test -n "$dst_arg"; then 18343f32c10Smrg # $@ is not empty: it contains at least $arg. 18443f32c10Smrg set fnord "$@" "$dst_arg" 18543f32c10Smrg shift # fnord 18643f32c10Smrg fi 18743f32c10Smrg shift # arg 18843f32c10Smrg dst_arg=$arg 1896ef05171Smrg # Protect names problematic for 'test' and other utilities. 1906ef05171Smrg case $dst_arg in 1916ef05171Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1926ef05171Smrg esac 19343f32c10Smrg done 19443f32c10Smrgfi 19543f32c10Smrg 19643f32c10Smrgif test $# -eq 0; then 19743f32c10Smrg if test -z "$dir_arg"; then 19843f32c10Smrg echo "$0: no input file specified." >&2 19943f32c10Smrg exit 1 20043f32c10Smrg fi 2016ef05171Smrg # It's OK to call 'install-sh -d' without argument. 20243f32c10Smrg # This can happen when creating conditional directories. 20343f32c10Smrg exit 0 20443f32c10Smrgfi 20543f32c10Smrg 20643f32c10Smrgif test -z "$dir_arg"; then 2076ef05171Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2086ef05171Smrg if test ! -d "$dst_arg"; then 2096ef05171Smrg echo "$0: $dst_arg: Is not a directory." >&2 2106ef05171Smrg exit 1 2116ef05171Smrg fi 2126ef05171Smrg fi 2136ef05171Smrgfi 2146ef05171Smrg 2156ef05171Smrgif test -z "$dir_arg"; then 2166ef05171Smrg do_exit='(exit $ret); exit $ret' 2176ef05171Smrg trap "ret=129; $do_exit" 1 2186ef05171Smrg trap "ret=130; $do_exit" 2 2196ef05171Smrg trap "ret=141; $do_exit" 13 2206ef05171Smrg trap "ret=143; $do_exit" 15 22143f32c10Smrg 22243f32c10Smrg # Set umask so as not to create temps with too-generous modes. 22343f32c10Smrg # However, 'strip' requires both read and write access to temps. 22443f32c10Smrg case $mode in 22543f32c10Smrg # Optimize common cases. 22643f32c10Smrg *644) cp_umask=133;; 22743f32c10Smrg *755) cp_umask=22;; 22843f32c10Smrg 22943f32c10Smrg *[0-7]) 23043f32c10Smrg if test -z "$stripcmd"; then 2316ef05171Smrg u_plus_rw= 23243f32c10Smrg else 2336ef05171Smrg u_plus_rw='% 200' 23443f32c10Smrg fi 23543f32c10Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23643f32c10Smrg *) 23743f32c10Smrg if test -z "$stripcmd"; then 2386ef05171Smrg u_plus_rw= 23943f32c10Smrg else 2406ef05171Smrg u_plus_rw=,u+rw 24143f32c10Smrg fi 24243f32c10Smrg cp_umask=$mode$u_plus_rw;; 24343f32c10Smrg esac 24443f32c10Smrgfi 24543f32c10Smrg 24643f32c10Smrgfor src 24743f32c10Smrgdo 2486ef05171Smrg # Protect names problematic for 'test' and other utilities. 24943f32c10Smrg case $src in 2506ef05171Smrg -* | [=\(\)!]) src=./$src;; 25143f32c10Smrg esac 25243f32c10Smrg 25343f32c10Smrg if test -n "$dir_arg"; then 25443f32c10Smrg dst=$src 25543f32c10Smrg dstdir=$dst 25643f32c10Smrg test -d "$dstdir" 25743f32c10Smrg dstdir_status=$? 25843f32c10Smrg else 25943f32c10Smrg 26043f32c10Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 26143f32c10Smrg # might cause directories to be created, which would be especially bad 26243f32c10Smrg # if $src (and thus $dsttmp) contains '*'. 26343f32c10Smrg if test ! -f "$src" && test ! -d "$src"; then 26443f32c10Smrg echo "$0: $src does not exist." >&2 26543f32c10Smrg exit 1 26643f32c10Smrg fi 26743f32c10Smrg 26843f32c10Smrg if test -z "$dst_arg"; then 26943f32c10Smrg echo "$0: no destination specified." >&2 27043f32c10Smrg exit 1 27143f32c10Smrg fi 27243f32c10Smrg dst=$dst_arg 27343f32c10Smrg 27443f32c10Smrg # If destination is a directory, append the input filename; won't work 27543f32c10Smrg # if double slashes aren't ignored. 27643f32c10Smrg if test -d "$dst"; then 2776ef05171Smrg if test "$is_target_a_directory" = never; then 2786ef05171Smrg echo "$0: $dst_arg: Is a directory" >&2 2796ef05171Smrg exit 1 28043f32c10Smrg fi 28143f32c10Smrg dstdir=$dst 28243f32c10Smrg dst=$dstdir/`basename "$src"` 28343f32c10Smrg dstdir_status=0 28443f32c10Smrg else 2856ef05171Smrg dstdir=`dirname "$dst"` 28643f32c10Smrg test -d "$dstdir" 28743f32c10Smrg dstdir_status=$? 28843f32c10Smrg fi 28943f32c10Smrg fi 29043f32c10Smrg 29143f32c10Smrg obsolete_mkdir_used=false 29243f32c10Smrg 29343f32c10Smrg if test $dstdir_status != 0; then 29443f32c10Smrg case $posix_mkdir in 29543f32c10Smrg '') 2966ef05171Smrg # Create intermediate dirs using mode 755 as modified by the umask. 2976ef05171Smrg # This is like FreeBSD 'install' as of 1997-10-28. 2986ef05171Smrg umask=`umask` 2996ef05171Smrg case $stripcmd.$umask in 3006ef05171Smrg # Optimize common cases. 3016ef05171Smrg *[2367][2367]) mkdir_umask=$umask;; 3026ef05171Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3036ef05171Smrg 3046ef05171Smrg *[0-7]) 3056ef05171Smrg mkdir_umask=`expr $umask + 22 \ 3066ef05171Smrg - $umask % 100 % 40 + $umask % 20 \ 3076ef05171Smrg - $umask % 10 % 4 + $umask % 2 3086ef05171Smrg `;; 3096ef05171Smrg *) mkdir_umask=$umask,go-w;; 3106ef05171Smrg esac 3116ef05171Smrg 3126ef05171Smrg # With -d, create the new directory with the user-specified mode. 3136ef05171Smrg # Otherwise, rely on $mkdir_umask. 3146ef05171Smrg if test -n "$dir_arg"; then 3156ef05171Smrg mkdir_mode=-m$mode 3166ef05171Smrg else 3176ef05171Smrg mkdir_mode= 3186ef05171Smrg fi 3196ef05171Smrg 3206ef05171Smrg posix_mkdir=false 3216ef05171Smrg case $umask in 3226ef05171Smrg *[123567][0-7][0-7]) 3236ef05171Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3246ef05171Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3256ef05171Smrg ;; 3266ef05171Smrg *) 3276ef05171Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3286ef05171Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3296ef05171Smrg 3306ef05171Smrg if (umask $mkdir_umask && 3316ef05171Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3326ef05171Smrg then 3336ef05171Smrg if test -z "$dir_arg" || { 3346ef05171Smrg # Check for POSIX incompatibilities with -m. 3356ef05171Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3366ef05171Smrg # other-writable bit of parent directory when it shouldn't. 3376ef05171Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3386ef05171Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3396ef05171Smrg case $ls_ld_tmpdir in 3406ef05171Smrg d????-?r-*) different_mode=700;; 3416ef05171Smrg d????-?--*) different_mode=755;; 3426ef05171Smrg *) false;; 3436ef05171Smrg esac && 3446ef05171Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3456ef05171Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3466ef05171Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3476ef05171Smrg } 3486ef05171Smrg } 3496ef05171Smrg then posix_mkdir=: 3506ef05171Smrg fi 3516ef05171Smrg rmdir "$tmpdir/d" "$tmpdir" 3526ef05171Smrg else 3536ef05171Smrg # Remove any dirs left behind by ancient mkdir implementations. 3546ef05171Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3556ef05171Smrg fi 3566ef05171Smrg trap '' 0;; 3576ef05171Smrg esac;; 35843f32c10Smrg esac 35943f32c10Smrg 36043f32c10Smrg if 36143f32c10Smrg $posix_mkdir && ( 3626ef05171Smrg umask $mkdir_umask && 3636ef05171Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 36443f32c10Smrg ) 36543f32c10Smrg then : 36643f32c10Smrg else 36743f32c10Smrg 36843f32c10Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 36943f32c10Smrg # or it failed possibly due to a race condition. Create the 37043f32c10Smrg # directory the slow way, step by step, checking for races as we go. 37143f32c10Smrg 37243f32c10Smrg case $dstdir in 3736ef05171Smrg /*) prefix='/';; 3746ef05171Smrg [-=\(\)!]*) prefix='./';; 3756ef05171Smrg *) prefix='';; 37643f32c10Smrg esac 37743f32c10Smrg 37843f32c10Smrg oIFS=$IFS 37943f32c10Smrg IFS=/ 3806ef05171Smrg set -f 38143f32c10Smrg set fnord $dstdir 38243f32c10Smrg shift 3836ef05171Smrg set +f 38443f32c10Smrg IFS=$oIFS 38543f32c10Smrg 38643f32c10Smrg prefixes= 38743f32c10Smrg 38843f32c10Smrg for d 38943f32c10Smrg do 3906ef05171Smrg test X"$d" = X && continue 3916ef05171Smrg 3926ef05171Smrg prefix=$prefix$d 3936ef05171Smrg if test -d "$prefix"; then 3946ef05171Smrg prefixes= 3956ef05171Smrg else 3966ef05171Smrg if $posix_mkdir; then 3976ef05171Smrg (umask=$mkdir_umask && 3986ef05171Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 3996ef05171Smrg # Don't fail if two instances are running concurrently. 4006ef05171Smrg test -d "$prefix" || exit 1 4016ef05171Smrg else 4026ef05171Smrg case $prefix in 4036ef05171Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4046ef05171Smrg *) qprefix=$prefix;; 4056ef05171Smrg esac 4066ef05171Smrg prefixes="$prefixes '$qprefix'" 4076ef05171Smrg fi 4086ef05171Smrg fi 4096ef05171Smrg prefix=$prefix/ 41043f32c10Smrg done 41143f32c10Smrg 41243f32c10Smrg if test -n "$prefixes"; then 4136ef05171Smrg # Don't fail if two instances are running concurrently. 4146ef05171Smrg (umask $mkdir_umask && 4156ef05171Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4166ef05171Smrg test -d "$dstdir" || exit 1 4176ef05171Smrg obsolete_mkdir_used=true 41843f32c10Smrg fi 41943f32c10Smrg fi 42043f32c10Smrg fi 42143f32c10Smrg 42243f32c10Smrg if test -n "$dir_arg"; then 42343f32c10Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 42443f32c10Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 42543f32c10Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 42643f32c10Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 42743f32c10Smrg else 42843f32c10Smrg 42943f32c10Smrg # Make a couple of temp file names in the proper directory. 43043f32c10Smrg dsttmp=$dstdir/_inst.$$_ 43143f32c10Smrg rmtmp=$dstdir/_rm.$$_ 43243f32c10Smrg 43343f32c10Smrg # Trap to clean up those temp files at exit. 43443f32c10Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 43543f32c10Smrg 43643f32c10Smrg # Copy the file name to the temp name. 43743f32c10Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 43843f32c10Smrg 43943f32c10Smrg # and set any options; do chmod last to preserve setuid bits. 44043f32c10Smrg # 44143f32c10Smrg # If any of these fail, we abort the whole thing. If we want to 44243f32c10Smrg # ignore errors from any of these, just make sure not to ignore 44343f32c10Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 44443f32c10Smrg # 44543f32c10Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 44643f32c10Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 44743f32c10Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 44843f32c10Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 44943f32c10Smrg 45043f32c10Smrg # If -C, don't bother to copy if it wouldn't change the file. 45143f32c10Smrg if $copy_on_change && 4526ef05171Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4536ef05171Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4546ef05171Smrg set -f && 45543f32c10Smrg set X $old && old=:$2:$4:$5:$6 && 45643f32c10Smrg set X $new && new=:$2:$4:$5:$6 && 4576ef05171Smrg set +f && 45843f32c10Smrg test "$old" = "$new" && 45943f32c10Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 46043f32c10Smrg then 46143f32c10Smrg rm -f "$dsttmp" 46243f32c10Smrg else 46343f32c10Smrg # Rename the file to the real destination. 46443f32c10Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 46543f32c10Smrg 46643f32c10Smrg # The rename failed, perhaps because mv can't rename something else 46743f32c10Smrg # to itself, or perhaps because mv is so ancient that it does not 46843f32c10Smrg # support -f. 46943f32c10Smrg { 4706ef05171Smrg # Now remove or move aside any old file at destination location. 4716ef05171Smrg # We try this two ways since rm can't unlink itself on some 4726ef05171Smrg # systems and the destination file might be busy for other 4736ef05171Smrg # reasons. In this case, the final cleanup might fail but the new 4746ef05171Smrg # file should still install successfully. 4756ef05171Smrg { 4766ef05171Smrg test ! -f "$dst" || 4776ef05171Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 4786ef05171Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 4796ef05171Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 4806ef05171Smrg } || 4816ef05171Smrg { echo "$0: cannot unlink or rename $dst" >&2 4826ef05171Smrg (exit 1); exit 1 4836ef05171Smrg } 4846ef05171Smrg } && 4856ef05171Smrg 4866ef05171Smrg # Now rename the file to the real destination. 4876ef05171Smrg $doit $mvcmd "$dsttmp" "$dst" 48843f32c10Smrg } 48943f32c10Smrg fi || exit 1 49043f32c10Smrg 49143f32c10Smrg trap '' 0 49243f32c10Smrg fi 49343f32c10Smrgdone 49443f32c10Smrg 49543f32c10Smrg# Local variables: 49643f32c10Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 49743f32c10Smrg# time-stamp-start: "scriptversion=" 49843f32c10Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 4996ef05171Smrg# time-stamp-time-zone: "UTC0" 5006ef05171Smrg# time-stamp-end: "; # UTC" 50143f32c10Smrg# End: 502