install-sh revision fa2b3b63
129459361Smrg#!/bin/sh 229459361Smrg# install - install a program, script, or datafile 329459361Smrg 4fa2b3b63Smrgscriptversion=2016-01-11.22; # UTC 529459361Smrg 629459361Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 729459361Smrg# later released in X11R6 (xc/config/util/install.sh) with the 829459361Smrg# following copyright and license. 929459361Smrg# 1029459361Smrg# Copyright (C) 1994 X Consortium 1129459361Smrg# 1229459361Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1329459361Smrg# of this software and associated documentation files (the "Software"), to 1429459361Smrg# deal in the Software without restriction, including without limitation the 1529459361Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1629459361Smrg# sell copies of the Software, and to permit persons to whom the Software is 1729459361Smrg# furnished to do so, subject to the following conditions: 1829459361Smrg# 1929459361Smrg# The above copyright notice and this permission notice shall be included in 2029459361Smrg# all copies or substantial portions of the Software. 2129459361Smrg# 2229459361Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2329459361Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2429459361Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2529459361Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2629459361Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2729459361Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2829459361Smrg# 2929459361Smrg# Except as contained in this notice, the name of the X Consortium shall not 3029459361Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3129459361Smrg# ings in this Software without prior written authorization from the X Consor- 3229459361Smrg# tium. 3329459361Smrg# 3429459361Smrg# 3529459361Smrg# FSF changes to this file are in the public domain. 3629459361Smrg# 3729459361Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38fb4ebca8Smrg# 'make' implicit rules from creating a file called install from it 3929459361Smrg# when there is no Makefile. 4029459361Smrg# 4129459361Smrg# This script is compatible with the BSD install script, but was written 4247202d7bSmrg# from scratch. 4347202d7bSmrg 44fa2b3b63Smrgtab=' ' 4547202d7bSmrgnl=' 4647202d7bSmrg' 47fa2b3b63SmrgIFS=" $tab$nl" 4829459361Smrg 49fa2b3b63Smrg# Set DOITPROG to "echo" to test this script. 5029459361Smrg 5147202d7bSmrgdoit=${DOITPROG-} 52fa2b3b63Smrgdoit_exec=${doit:-exec} 5329459361Smrg 5447202d7bSmrg# Put in absolute file names if you don't have them in your path; 5547202d7bSmrg# or use environment vars. 5647202d7bSmrg 5747202d7bSmrgchgrpprog=${CHGRPPROG-chgrp} 5847202d7bSmrgchmodprog=${CHMODPROG-chmod} 5947202d7bSmrgchownprog=${CHOWNPROG-chown} 6047202d7bSmrgcmpprog=${CMPPROG-cmp} 6147202d7bSmrgcpprog=${CPPROG-cp} 6247202d7bSmrgmkdirprog=${MKDIRPROG-mkdir} 6347202d7bSmrgmvprog=${MVPROG-mv} 6447202d7bSmrgrmprog=${RMPROG-rm} 6547202d7bSmrgstripprog=${STRIPPROG-strip} 6647202d7bSmrg 6747202d7bSmrgposix_mkdir= 6847202d7bSmrg 6947202d7bSmrg# Desired mode of installed file. 7047202d7bSmrgmode=0755 7129459361Smrg 7229459361Smrgchgrpcmd= 7347202d7bSmrgchmodcmd=$chmodprog 7447202d7bSmrgchowncmd= 7547202d7bSmrgmvcmd=$mvprog 7629459361Smrgrmcmd="$rmprog -f" 7747202d7bSmrgstripcmd= 7847202d7bSmrg 7929459361Smrgsrc= 8029459361Smrgdst= 8129459361Smrgdir_arg= 8247202d7bSmrgdst_arg= 8347202d7bSmrg 8447202d7bSmrgcopy_on_change=false 85fa2b3b63Smrgis_target_a_directory=possibly 8629459361Smrg 8747202d7bSmrgusage="\ 8847202d7bSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 8929459361Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 9029459361Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9129459361Smrg or: $0 [OPTION]... -d DIRECTORIES... 9229459361Smrg 9329459361SmrgIn the 1st form, copy SRCFILE to DSTFILE. 9429459361SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 9529459361SmrgIn the 4th, create DIRECTORIES. 9629459361Smrg 9729459361SmrgOptions: 9847202d7bSmrg --help display this help and exit. 9947202d7bSmrg --version display version info and exit. 10047202d7bSmrg 10147202d7bSmrg -c (ignored) 10247202d7bSmrg -C install only if different (preserve the last data modification time) 10347202d7bSmrg -d create directories instead of installing files. 10447202d7bSmrg -g GROUP $chgrpprog installed files to GROUP. 10547202d7bSmrg -m MODE $chmodprog installed files to MODE. 10647202d7bSmrg -o USER $chownprog installed files to USER. 10747202d7bSmrg -s $stripprog installed files. 10847202d7bSmrg -t DIRECTORY install into DIRECTORY. 10947202d7bSmrg -T report an error if DSTFILE is a directory. 11029459361Smrg 11129459361SmrgEnvironment variables override the default commands: 11247202d7bSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11347202d7bSmrg RMPROG STRIPPROG 11429459361Smrg" 11529459361Smrg 11647202d7bSmrgwhile test $# -ne 0; do 11729459361Smrg case $1 in 11847202d7bSmrg -c) ;; 11947202d7bSmrg 12047202d7bSmrg -C) copy_on_change=true;; 12129459361Smrg 12247202d7bSmrg -d) dir_arg=true;; 12329459361Smrg 12429459361Smrg -g) chgrpcmd="$chgrpprog $2" 125fa2b3b63Smrg shift;; 12629459361Smrg 12729459361Smrg --help) echo "$usage"; exit $?;; 12829459361Smrg 12947202d7bSmrg -m) mode=$2 130fa2b3b63Smrg case $mode in 131fa2b3b63Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132fa2b3b63Smrg echo "$0: invalid mode: $mode" >&2 133fa2b3b63Smrg exit 1;; 134fa2b3b63Smrg esac 135fa2b3b63Smrg shift;; 13629459361Smrg 13729459361Smrg -o) chowncmd="$chownprog $2" 138fa2b3b63Smrg shift;; 13929459361Smrg 14047202d7bSmrg -s) stripcmd=$stripprog;; 14129459361Smrg 142fa2b3b63Smrg -t) 143fa2b3b63Smrg is_target_a_directory=always 144fa2b3b63Smrg dst_arg=$2 145fa2b3b63Smrg # Protect names problematic for 'test' and other utilities. 146fa2b3b63Smrg case $dst_arg in 147fa2b3b63Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148fa2b3b63Smrg esac 149fa2b3b63Smrg shift;; 15029459361Smrg 151fa2b3b63Smrg -T) is_target_a_directory=never;; 15229459361Smrg 15329459361Smrg --version) echo "$0 $scriptversion"; exit $?;; 15429459361Smrg 155fa2b3b63Smrg --) shift 156fa2b3b63Smrg break;; 15747202d7bSmrg 158fa2b3b63Smrg -*) echo "$0: invalid option: $1" >&2 159fa2b3b63Smrg exit 1;; 16047202d7bSmrg 16147202d7bSmrg *) break;; 16229459361Smrg esac 16347202d7bSmrg shift 16429459361Smrgdone 16529459361Smrg 166fa2b3b63Smrg# We allow the use of options -d and -T together, by making -d 167fa2b3b63Smrg# take the precedence; this is for compatibility with GNU install. 168fa2b3b63Smrg 169fa2b3b63Smrgif test -n "$dir_arg"; then 170fa2b3b63Smrg if test -n "$dst_arg"; then 171fa2b3b63Smrg echo "$0: target directory not allowed when installing a directory." >&2 172fa2b3b63Smrg exit 1 173fa2b3b63Smrg fi 174fa2b3b63Smrgfi 175fa2b3b63Smrg 17647202d7bSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17747202d7bSmrg # When -d is used, all remaining arguments are directories to create. 17847202d7bSmrg # When -t is used, the destination is already specified. 17947202d7bSmrg # Otherwise, the last argument is the destination. Remove it from $@. 18047202d7bSmrg for arg 18147202d7bSmrg do 18247202d7bSmrg if test -n "$dst_arg"; then 18347202d7bSmrg # $@ is not empty: it contains at least $arg. 18447202d7bSmrg set fnord "$@" "$dst_arg" 18547202d7bSmrg shift # fnord 18647202d7bSmrg fi 18747202d7bSmrg shift # arg 18847202d7bSmrg dst_arg=$arg 189fb4ebca8Smrg # Protect names problematic for 'test' and other utilities. 1905dd2154eSmrg case $dst_arg in 1915dd2154eSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1925dd2154eSmrg esac 19347202d7bSmrg done 19447202d7bSmrgfi 19547202d7bSmrg 19647202d7bSmrgif test $# -eq 0; then 19729459361Smrg if test -z "$dir_arg"; then 19829459361Smrg echo "$0: no input file specified." >&2 19929459361Smrg exit 1 20029459361Smrg fi 201fb4ebca8Smrg # It's OK to call 'install-sh -d' without argument. 20229459361Smrg # This can happen when creating conditional directories. 20329459361Smrg exit 0 20429459361Smrgfi 20529459361Smrg 206fa2b3b63Smrgif test -z "$dir_arg"; then 207fa2b3b63Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208fa2b3b63Smrg if test ! -d "$dst_arg"; then 209fa2b3b63Smrg echo "$0: $dst_arg: Is not a directory." >&2 210fa2b3b63Smrg exit 1 211fa2b3b63Smrg fi 212fa2b3b63Smrg fi 213fa2b3b63Smrgfi 214fa2b3b63Smrg 21547202d7bSmrgif test -z "$dir_arg"; then 2165dd2154eSmrg do_exit='(exit $ret); exit $ret' 2175dd2154eSmrg trap "ret=129; $do_exit" 1 2185dd2154eSmrg trap "ret=130; $do_exit" 2 2195dd2154eSmrg trap "ret=141; $do_exit" 13 2205dd2154eSmrg trap "ret=143; $do_exit" 15 22147202d7bSmrg 22247202d7bSmrg # Set umask so as not to create temps with too-generous modes. 22347202d7bSmrg # However, 'strip' requires both read and write access to temps. 22447202d7bSmrg case $mode in 22547202d7bSmrg # Optimize common cases. 22647202d7bSmrg *644) cp_umask=133;; 22747202d7bSmrg *755) cp_umask=22;; 22847202d7bSmrg 22947202d7bSmrg *[0-7]) 23047202d7bSmrg if test -z "$stripcmd"; then 231fa2b3b63Smrg u_plus_rw= 23247202d7bSmrg else 233fa2b3b63Smrg u_plus_rw='% 200' 23447202d7bSmrg fi 23547202d7bSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23647202d7bSmrg *) 23747202d7bSmrg if test -z "$stripcmd"; then 238fa2b3b63Smrg u_plus_rw= 23947202d7bSmrg else 240fa2b3b63Smrg u_plus_rw=,u+rw 24147202d7bSmrg fi 24247202d7bSmrg cp_umask=$mode$u_plus_rw;; 24347202d7bSmrg esac 24447202d7bSmrgfi 24547202d7bSmrg 24629459361Smrgfor src 24729459361Smrgdo 248fb4ebca8Smrg # Protect names problematic for 'test' and other utilities. 24929459361Smrg case $src in 2505dd2154eSmrg -* | [=\(\)!]) src=./$src;; 25129459361Smrg esac 25229459361Smrg 25329459361Smrg if test -n "$dir_arg"; then 25429459361Smrg dst=$src 25547202d7bSmrg dstdir=$dst 25647202d7bSmrg test -d "$dstdir" 25747202d7bSmrg dstdir_status=$? 25829459361Smrg else 25947202d7bSmrg 26029459361Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 26129459361Smrg # might cause directories to be created, which would be especially bad 26229459361Smrg # if $src (and thus $dsttmp) contains '*'. 26329459361Smrg if test ! -f "$src" && test ! -d "$src"; then 26429459361Smrg echo "$0: $src does not exist." >&2 26529459361Smrg exit 1 26629459361Smrg fi 26729459361Smrg 26847202d7bSmrg if test -z "$dst_arg"; then 26929459361Smrg echo "$0: no destination specified." >&2 27029459361Smrg exit 1 27129459361Smrg fi 27247202d7bSmrg dst=$dst_arg 27329459361Smrg 27429459361Smrg # If destination is a directory, append the input filename; won't work 27529459361Smrg # if double slashes aren't ignored. 27629459361Smrg if test -d "$dst"; then 277fa2b3b63Smrg if test "$is_target_a_directory" = never; then 278fa2b3b63Smrg echo "$0: $dst_arg: Is a directory" >&2 279fa2b3b63Smrg exit 1 28029459361Smrg fi 28147202d7bSmrg dstdir=$dst 28247202d7bSmrg dst=$dstdir/`basename "$src"` 28347202d7bSmrg dstdir_status=0 28447202d7bSmrg else 285fa2b3b63Smrg dstdir=`dirname "$dst"` 28647202d7bSmrg test -d "$dstdir" 28747202d7bSmrg dstdir_status=$? 28829459361Smrg fi 28929459361Smrg fi 29029459361Smrg 29147202d7bSmrg obsolete_mkdir_used=false 29247202d7bSmrg 29347202d7bSmrg if test $dstdir_status != 0; then 29447202d7bSmrg case $posix_mkdir in 29547202d7bSmrg '') 296fa2b3b63Smrg # Create intermediate dirs using mode 755 as modified by the umask. 297fa2b3b63Smrg # This is like FreeBSD 'install' as of 1997-10-28. 298fa2b3b63Smrg umask=`umask` 299fa2b3b63Smrg case $stripcmd.$umask in 300fa2b3b63Smrg # Optimize common cases. 301fa2b3b63Smrg *[2367][2367]) mkdir_umask=$umask;; 302fa2b3b63Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303fa2b3b63Smrg 304fa2b3b63Smrg *[0-7]) 305fa2b3b63Smrg mkdir_umask=`expr $umask + 22 \ 306fa2b3b63Smrg - $umask % 100 % 40 + $umask % 20 \ 307fa2b3b63Smrg - $umask % 10 % 4 + $umask % 2 308fa2b3b63Smrg `;; 309fa2b3b63Smrg *) mkdir_umask=$umask,go-w;; 310fa2b3b63Smrg esac 311fa2b3b63Smrg 312fa2b3b63Smrg # With -d, create the new directory with the user-specified mode. 313fa2b3b63Smrg # Otherwise, rely on $mkdir_umask. 314fa2b3b63Smrg if test -n "$dir_arg"; then 315fa2b3b63Smrg mkdir_mode=-m$mode 316fa2b3b63Smrg else 317fa2b3b63Smrg mkdir_mode= 318fa2b3b63Smrg fi 319fa2b3b63Smrg 320fa2b3b63Smrg posix_mkdir=false 321fa2b3b63Smrg case $umask in 322fa2b3b63Smrg *[123567][0-7][0-7]) 323fa2b3b63Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324fa2b3b63Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325fa2b3b63Smrg ;; 326fa2b3b63Smrg *) 327fa2b3b63Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328fa2b3b63Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329fa2b3b63Smrg 330fa2b3b63Smrg if (umask $mkdir_umask && 331fa2b3b63Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332fa2b3b63Smrg then 333fa2b3b63Smrg if test -z "$dir_arg" || { 334fa2b3b63Smrg # Check for POSIX incompatibilities with -m. 335fa2b3b63Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336fa2b3b63Smrg # other-writable bit of parent directory when it shouldn't. 337fa2b3b63Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338fa2b3b63Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339fa2b3b63Smrg case $ls_ld_tmpdir in 340fa2b3b63Smrg d????-?r-*) different_mode=700;; 341fa2b3b63Smrg d????-?--*) different_mode=755;; 342fa2b3b63Smrg *) false;; 343fa2b3b63Smrg esac && 344fa2b3b63Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345fa2b3b63Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346fa2b3b63Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347fa2b3b63Smrg } 348fa2b3b63Smrg } 349fa2b3b63Smrg then posix_mkdir=: 350fa2b3b63Smrg fi 351fa2b3b63Smrg rmdir "$tmpdir/d" "$tmpdir" 352fa2b3b63Smrg else 353fa2b3b63Smrg # Remove any dirs left behind by ancient mkdir implementations. 354fa2b3b63Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355fa2b3b63Smrg fi 356fa2b3b63Smrg trap '' 0;; 357fa2b3b63Smrg esac;; 35847202d7bSmrg esac 35929459361Smrg 36047202d7bSmrg if 36147202d7bSmrg $posix_mkdir && ( 362fa2b3b63Smrg umask $mkdir_umask && 363fa2b3b63Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 36447202d7bSmrg ) 36547202d7bSmrg then : 36647202d7bSmrg else 36729459361Smrg 36847202d7bSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 36947202d7bSmrg # or it failed possibly due to a race condition. Create the 37047202d7bSmrg # directory the slow way, step by step, checking for races as we go. 37129459361Smrg 37247202d7bSmrg case $dstdir in 373fa2b3b63Smrg /*) prefix='/';; 374fa2b3b63Smrg [-=\(\)!]*) prefix='./';; 375fa2b3b63Smrg *) prefix='';; 37647202d7bSmrg esac 37729459361Smrg 37847202d7bSmrg oIFS=$IFS 37947202d7bSmrg IFS=/ 380fa2b3b63Smrg set -f 38147202d7bSmrg set fnord $dstdir 38229459361Smrg shift 383fa2b3b63Smrg set +f 38447202d7bSmrg IFS=$oIFS 38547202d7bSmrg 38647202d7bSmrg prefixes= 38747202d7bSmrg 38847202d7bSmrg for d 38947202d7bSmrg do 390fa2b3b63Smrg test X"$d" = X && continue 391fa2b3b63Smrg 392fa2b3b63Smrg prefix=$prefix$d 393fa2b3b63Smrg if test -d "$prefix"; then 394fa2b3b63Smrg prefixes= 395fa2b3b63Smrg else 396fa2b3b63Smrg if $posix_mkdir; then 397fa2b3b63Smrg (umask=$mkdir_umask && 398fa2b3b63Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399fa2b3b63Smrg # Don't fail if two instances are running concurrently. 400fa2b3b63Smrg test -d "$prefix" || exit 1 401fa2b3b63Smrg else 402fa2b3b63Smrg case $prefix in 403fa2b3b63Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404fa2b3b63Smrg *) qprefix=$prefix;; 405fa2b3b63Smrg esac 406fa2b3b63Smrg prefixes="$prefixes '$qprefix'" 407fa2b3b63Smrg fi 408fa2b3b63Smrg fi 409fa2b3b63Smrg prefix=$prefix/ 41047202d7bSmrg done 41147202d7bSmrg 41247202d7bSmrg if test -n "$prefixes"; then 413fa2b3b63Smrg # Don't fail if two instances are running concurrently. 414fa2b3b63Smrg (umask $mkdir_umask && 415fa2b3b63Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 416fa2b3b63Smrg test -d "$dstdir" || exit 1 417fa2b3b63Smrg obsolete_mkdir_used=true 41829459361Smrg fi 41947202d7bSmrg fi 42029459361Smrg fi 42129459361Smrg 42229459361Smrg if test -n "$dir_arg"; then 42347202d7bSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 42447202d7bSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 42547202d7bSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 42647202d7bSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 42729459361Smrg else 42829459361Smrg 42929459361Smrg # Make a couple of temp file names in the proper directory. 43029459361Smrg dsttmp=$dstdir/_inst.$$_ 43129459361Smrg rmtmp=$dstdir/_rm.$$_ 43229459361Smrg 43329459361Smrg # Trap to clean up those temp files at exit. 43429459361Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 43529459361Smrg 43629459361Smrg # Copy the file name to the temp name. 43747202d7bSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 43829459361Smrg 43929459361Smrg # and set any options; do chmod last to preserve setuid bits. 44029459361Smrg # 44129459361Smrg # If any of these fail, we abort the whole thing. If we want to 44229459361Smrg # ignore errors from any of these, just make sure not to ignore 44329459361Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 44429459361Smrg # 44547202d7bSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 44647202d7bSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 44747202d7bSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 44847202d7bSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 44947202d7bSmrg 45047202d7bSmrg # If -C, don't bother to copy if it wouldn't change the file. 45147202d7bSmrg if $copy_on_change && 452fa2b3b63Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453fa2b3b63Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454fa2b3b63Smrg set -f && 45547202d7bSmrg set X $old && old=:$2:$4:$5:$6 && 45647202d7bSmrg set X $new && new=:$2:$4:$5:$6 && 457fa2b3b63Smrg set +f && 45847202d7bSmrg test "$old" = "$new" && 45947202d7bSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 46047202d7bSmrg then 46147202d7bSmrg rm -f "$dsttmp" 46247202d7bSmrg else 46347202d7bSmrg # Rename the file to the real destination. 46447202d7bSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 46547202d7bSmrg 46647202d7bSmrg # The rename failed, perhaps because mv can't rename something else 46747202d7bSmrg # to itself, or perhaps because mv is so ancient that it does not 46847202d7bSmrg # support -f. 46947202d7bSmrg { 470fa2b3b63Smrg # Now remove or move aside any old file at destination location. 471fa2b3b63Smrg # We try this two ways since rm can't unlink itself on some 472fa2b3b63Smrg # systems and the destination file might be busy for other 473fa2b3b63Smrg # reasons. In this case, the final cleanup might fail but the new 474fa2b3b63Smrg # file should still install successfully. 475fa2b3b63Smrg { 476fa2b3b63Smrg test ! -f "$dst" || 477fa2b3b63Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 478fa2b3b63Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479fa2b3b63Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480fa2b3b63Smrg } || 481fa2b3b63Smrg { echo "$0: cannot unlink or rename $dst" >&2 482fa2b3b63Smrg (exit 1); exit 1 483fa2b3b63Smrg } 484fa2b3b63Smrg } && 485fa2b3b63Smrg 486fa2b3b63Smrg # Now rename the file to the real destination. 487fa2b3b63Smrg $doit $mvcmd "$dsttmp" "$dst" 48847202d7bSmrg } 48947202d7bSmrg fi || exit 1 49047202d7bSmrg 49147202d7bSmrg trap '' 0 49247202d7bSmrg fi 49329459361Smrgdone 49429459361Smrg 49529459361Smrg# Local variables: 49629459361Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 49729459361Smrg# time-stamp-start: "scriptversion=" 49829459361Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 499fa2b3b63Smrg# time-stamp-time-zone: "UTC0" 50047202d7bSmrg# time-stamp-end: "; # UTC" 50129459361Smrg# End: 502