install-sh revision fc544a13
1ff559fabSmrg#!/bin/sh 2ff559fabSmrg# install - install a program, script, or datafile 3ff559fabSmrg 4fc544a13Smrgscriptversion=2013-12-25.23; # UTC 5ff559fabSmrg 6ff559fabSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7ff559fabSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8ff559fabSmrg# following copyright and license. 9ff559fabSmrg# 10ff559fabSmrg# Copyright (C) 1994 X Consortium 11ff559fabSmrg# 12ff559fabSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13ff559fabSmrg# of this software and associated documentation files (the "Software"), to 14ff559fabSmrg# deal in the Software without restriction, including without limitation the 15ff559fabSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16ff559fabSmrg# sell copies of the Software, and to permit persons to whom the Software is 17ff559fabSmrg# furnished to do so, subject to the following conditions: 18ff559fabSmrg# 19ff559fabSmrg# The above copyright notice and this permission notice shall be included in 20ff559fabSmrg# all copies or substantial portions of the Software. 21ff559fabSmrg# 22ff559fabSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23ff559fabSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24ff559fabSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25ff559fabSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26ff559fabSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27ff559fabSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28ff559fabSmrg# 29ff559fabSmrg# Except as contained in this notice, the name of the X Consortium shall not 30ff559fabSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31ff559fabSmrg# ings in this Software without prior written authorization from the X Consor- 32ff559fabSmrg# tium. 33ff559fabSmrg# 34ff559fabSmrg# 35ff559fabSmrg# FSF changes to this file are in the public domain. 36ff559fabSmrg# 37ff559fabSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38fc544a13Smrg# 'make' implicit rules from creating a file called install from it 39ff559fabSmrg# when there is no Makefile. 40ff559fabSmrg# 41ff559fabSmrg# This script is compatible with the BSD install script, but was written 427a3b38f7Smrg# from scratch. 437a3b38f7Smrg 44fc544a13Smrgtab=' ' 457a3b38f7Smrgnl=' 467a3b38f7Smrg' 47fc544a13SmrgIFS=" $tab$nl" 48ff559fabSmrg 49fc544a13Smrg# Set DOITPROG to "echo" to test this script. 50ff559fabSmrg 517a3b38f7Smrgdoit=${DOITPROG-} 52fc544a13Smrgdoit_exec=${doit:-exec} 53ff559fabSmrg 547a3b38f7Smrg# Put in absolute file names if you don't have them in your path; 557a3b38f7Smrg# or use environment vars. 567a3b38f7Smrg 577a3b38f7Smrgchgrpprog=${CHGRPPROG-chgrp} 587a3b38f7Smrgchmodprog=${CHMODPROG-chmod} 597a3b38f7Smrgchownprog=${CHOWNPROG-chown} 607a3b38f7Smrgcmpprog=${CMPPROG-cmp} 617a3b38f7Smrgcpprog=${CPPROG-cp} 627a3b38f7Smrgmkdirprog=${MKDIRPROG-mkdir} 637a3b38f7Smrgmvprog=${MVPROG-mv} 647a3b38f7Smrgrmprog=${RMPROG-rm} 657a3b38f7Smrgstripprog=${STRIPPROG-strip} 667a3b38f7Smrg 677a3b38f7Smrgposix_mkdir= 687a3b38f7Smrg 697a3b38f7Smrg# Desired mode of installed file. 707a3b38f7Smrgmode=0755 71ff559fabSmrg 72ff559fabSmrgchgrpcmd= 737a3b38f7Smrgchmodcmd=$chmodprog 747a3b38f7Smrgchowncmd= 757a3b38f7Smrgmvcmd=$mvprog 76ff559fabSmrgrmcmd="$rmprog -f" 777a3b38f7Smrgstripcmd= 787a3b38f7Smrg 79ff559fabSmrgsrc= 80ff559fabSmrgdst= 81ff559fabSmrgdir_arg= 827a3b38f7Smrgdst_arg= 837a3b38f7Smrg 847a3b38f7Smrgcopy_on_change=false 85fc544a13Smrgis_target_a_directory=possibly 86ff559fabSmrg 877a3b38f7Smrgusage="\ 887a3b38f7SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89ff559fabSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90ff559fabSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91ff559fabSmrg or: $0 [OPTION]... -d DIRECTORIES... 92ff559fabSmrg 93ff559fabSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94ff559fabSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95ff559fabSmrgIn the 4th, create DIRECTORIES. 96ff559fabSmrg 97ff559fabSmrgOptions: 987a3b38f7Smrg --help display this help and exit. 997a3b38f7Smrg --version display version info and exit. 1007a3b38f7Smrg 1017a3b38f7Smrg -c (ignored) 1027a3b38f7Smrg -C install only if different (preserve the last data modification time) 1037a3b38f7Smrg -d create directories instead of installing files. 1047a3b38f7Smrg -g GROUP $chgrpprog installed files to GROUP. 1057a3b38f7Smrg -m MODE $chmodprog installed files to MODE. 1067a3b38f7Smrg -o USER $chownprog installed files to USER. 1077a3b38f7Smrg -s $stripprog installed files. 1087a3b38f7Smrg -t DIRECTORY install into DIRECTORY. 1097a3b38f7Smrg -T report an error if DSTFILE is a directory. 110ff559fabSmrg 111ff559fabSmrgEnvironment variables override the default commands: 1127a3b38f7Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1137a3b38f7Smrg RMPROG STRIPPROG 114ff559fabSmrg" 115ff559fabSmrg 1167a3b38f7Smrgwhile test $# -ne 0; do 117ff559fabSmrg case $1 in 1187a3b38f7Smrg -c) ;; 1197a3b38f7Smrg 1207a3b38f7Smrg -C) copy_on_change=true;; 121ff559fabSmrg 1227a3b38f7Smrg -d) dir_arg=true;; 123ff559fabSmrg 124ff559fabSmrg -g) chgrpcmd="$chgrpprog $2" 125fc544a13Smrg shift;; 126ff559fabSmrg 127ff559fabSmrg --help) echo "$usage"; exit $?;; 128ff559fabSmrg 1297a3b38f7Smrg -m) mode=$2 130fc544a13Smrg case $mode in 131fc544a13Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132fc544a13Smrg echo "$0: invalid mode: $mode" >&2 133fc544a13Smrg exit 1;; 134fc544a13Smrg esac 135fc544a13Smrg shift;; 136ff559fabSmrg 137ff559fabSmrg -o) chowncmd="$chownprog $2" 138fc544a13Smrg shift;; 139ff559fabSmrg 1407a3b38f7Smrg -s) stripcmd=$stripprog;; 141ff559fabSmrg 142fc544a13Smrg -t) 143fc544a13Smrg is_target_a_directory=always 144fc544a13Smrg dst_arg=$2 145fc544a13Smrg # Protect names problematic for 'test' and other utilities. 146fc544a13Smrg case $dst_arg in 147fc544a13Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148fc544a13Smrg esac 149fc544a13Smrg shift;; 150ff559fabSmrg 151fc544a13Smrg -T) is_target_a_directory=never;; 152ff559fabSmrg 153ff559fabSmrg --version) echo "$0 $scriptversion"; exit $?;; 154ff559fabSmrg 155fc544a13Smrg --) shift 156fc544a13Smrg break;; 1577a3b38f7Smrg 158fc544a13Smrg -*) echo "$0: invalid option: $1" >&2 159fc544a13Smrg exit 1;; 1607a3b38f7Smrg 1617a3b38f7Smrg *) break;; 162ff559fabSmrg esac 1637a3b38f7Smrg shift 164ff559fabSmrgdone 165ff559fabSmrg 166fc544a13Smrg# We allow the use of options -d and -T together, by making -d 167fc544a13Smrg# take the precedence; this is for compatibility with GNU install. 168fc544a13Smrg 169fc544a13Smrgif test -n "$dir_arg"; then 170fc544a13Smrg if test -n "$dst_arg"; then 171fc544a13Smrg echo "$0: target directory not allowed when installing a directory." >&2 172fc544a13Smrg exit 1 173fc544a13Smrg fi 174fc544a13Smrgfi 175fc544a13Smrg 1767a3b38f7Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1777a3b38f7Smrg # When -d is used, all remaining arguments are directories to create. 1787a3b38f7Smrg # When -t is used, the destination is already specified. 1797a3b38f7Smrg # Otherwise, the last argument is the destination. Remove it from $@. 1807a3b38f7Smrg for arg 1817a3b38f7Smrg do 1827a3b38f7Smrg if test -n "$dst_arg"; then 1837a3b38f7Smrg # $@ is not empty: it contains at least $arg. 1847a3b38f7Smrg set fnord "$@" "$dst_arg" 1857a3b38f7Smrg shift # fnord 1867a3b38f7Smrg fi 1877a3b38f7Smrg shift # arg 1887a3b38f7Smrg dst_arg=$arg 189fc544a13Smrg # Protect names problematic for 'test' and other utilities. 190fc544a13Smrg case $dst_arg in 191fc544a13Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192fc544a13Smrg esac 1937a3b38f7Smrg done 1947a3b38f7Smrgfi 1957a3b38f7Smrg 1967a3b38f7Smrgif test $# -eq 0; then 197ff559fabSmrg if test -z "$dir_arg"; then 198ff559fabSmrg echo "$0: no input file specified." >&2 199ff559fabSmrg exit 1 200ff559fabSmrg fi 201fc544a13Smrg # It's OK to call 'install-sh -d' without argument. 202ff559fabSmrg # This can happen when creating conditional directories. 203ff559fabSmrg exit 0 204ff559fabSmrgfi 205ff559fabSmrg 2067a3b38f7Smrgif test -z "$dir_arg"; then 207fc544a13Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208fc544a13Smrg if test ! -d "$dst_arg"; then 209fc544a13Smrg echo "$0: $dst_arg: Is not a directory." >&2 210fc544a13Smrg exit 1 211fc544a13Smrg fi 212fc544a13Smrg fi 213fc544a13Smrgfi 214fc544a13Smrg 215fc544a13Smrgif test -z "$dir_arg"; then 216fc544a13Smrg do_exit='(exit $ret); exit $ret' 217fc544a13Smrg trap "ret=129; $do_exit" 1 218fc544a13Smrg trap "ret=130; $do_exit" 2 219fc544a13Smrg trap "ret=141; $do_exit" 13 220fc544a13Smrg trap "ret=143; $do_exit" 15 2217a3b38f7Smrg 2227a3b38f7Smrg # Set umask so as not to create temps with too-generous modes. 2237a3b38f7Smrg # However, 'strip' requires both read and write access to temps. 2247a3b38f7Smrg case $mode in 2257a3b38f7Smrg # Optimize common cases. 2267a3b38f7Smrg *644) cp_umask=133;; 2277a3b38f7Smrg *755) cp_umask=22;; 2287a3b38f7Smrg 2297a3b38f7Smrg *[0-7]) 2307a3b38f7Smrg if test -z "$stripcmd"; then 231fc544a13Smrg u_plus_rw= 2327a3b38f7Smrg else 233fc544a13Smrg u_plus_rw='% 200' 2347a3b38f7Smrg fi 2357a3b38f7Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2367a3b38f7Smrg *) 2377a3b38f7Smrg if test -z "$stripcmd"; then 238fc544a13Smrg u_plus_rw= 2397a3b38f7Smrg else 240fc544a13Smrg u_plus_rw=,u+rw 2417a3b38f7Smrg fi 2427a3b38f7Smrg cp_umask=$mode$u_plus_rw;; 2437a3b38f7Smrg esac 2447a3b38f7Smrgfi 2457a3b38f7Smrg 246ff559fabSmrgfor src 247ff559fabSmrgdo 248fc544a13Smrg # Protect names problematic for 'test' and other utilities. 249ff559fabSmrg case $src in 250fc544a13Smrg -* | [=\(\)!]) src=./$src;; 251ff559fabSmrg esac 252ff559fabSmrg 253ff559fabSmrg if test -n "$dir_arg"; then 254ff559fabSmrg dst=$src 2557a3b38f7Smrg dstdir=$dst 2567a3b38f7Smrg test -d "$dstdir" 2577a3b38f7Smrg dstdir_status=$? 258ff559fabSmrg else 2597a3b38f7Smrg 260ff559fabSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261ff559fabSmrg # might cause directories to be created, which would be especially bad 262ff559fabSmrg # if $src (and thus $dsttmp) contains '*'. 263ff559fabSmrg if test ! -f "$src" && test ! -d "$src"; then 264ff559fabSmrg echo "$0: $src does not exist." >&2 265ff559fabSmrg exit 1 266ff559fabSmrg fi 267ff559fabSmrg 2687a3b38f7Smrg if test -z "$dst_arg"; then 269ff559fabSmrg echo "$0: no destination specified." >&2 270ff559fabSmrg exit 1 271ff559fabSmrg fi 2727a3b38f7Smrg dst=$dst_arg 273ff559fabSmrg 274ff559fabSmrg # If destination is a directory, append the input filename; won't work 275ff559fabSmrg # if double slashes aren't ignored. 276ff559fabSmrg if test -d "$dst"; then 277fc544a13Smrg if test "$is_target_a_directory" = never; then 278fc544a13Smrg echo "$0: $dst_arg: Is a directory" >&2 279fc544a13Smrg exit 1 280ff559fabSmrg fi 2817a3b38f7Smrg dstdir=$dst 2827a3b38f7Smrg dst=$dstdir/`basename "$src"` 2837a3b38f7Smrg dstdir_status=0 2847a3b38f7Smrg else 285fc544a13Smrg dstdir=`dirname "$dst"` 2867a3b38f7Smrg test -d "$dstdir" 2877a3b38f7Smrg dstdir_status=$? 288ff559fabSmrg fi 289ff559fabSmrg fi 290ff559fabSmrg 2917a3b38f7Smrg obsolete_mkdir_used=false 2927a3b38f7Smrg 2937a3b38f7Smrg if test $dstdir_status != 0; then 2947a3b38f7Smrg case $posix_mkdir in 2957a3b38f7Smrg '') 296fc544a13Smrg # Create intermediate dirs using mode 755 as modified by the umask. 297fc544a13Smrg # This is like FreeBSD 'install' as of 1997-10-28. 298fc544a13Smrg umask=`umask` 299fc544a13Smrg case $stripcmd.$umask in 300fc544a13Smrg # Optimize common cases. 301fc544a13Smrg *[2367][2367]) mkdir_umask=$umask;; 302fc544a13Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303fc544a13Smrg 304fc544a13Smrg *[0-7]) 305fc544a13Smrg mkdir_umask=`expr $umask + 22 \ 306fc544a13Smrg - $umask % 100 % 40 + $umask % 20 \ 307fc544a13Smrg - $umask % 10 % 4 + $umask % 2 308fc544a13Smrg `;; 309fc544a13Smrg *) mkdir_umask=$umask,go-w;; 310fc544a13Smrg esac 311fc544a13Smrg 312fc544a13Smrg # With -d, create the new directory with the user-specified mode. 313fc544a13Smrg # Otherwise, rely on $mkdir_umask. 314fc544a13Smrg if test -n "$dir_arg"; then 315fc544a13Smrg mkdir_mode=-m$mode 316fc544a13Smrg else 317fc544a13Smrg mkdir_mode= 318fc544a13Smrg fi 319fc544a13Smrg 320fc544a13Smrg posix_mkdir=false 321fc544a13Smrg case $umask in 322fc544a13Smrg *[123567][0-7][0-7]) 323fc544a13Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324fc544a13Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325fc544a13Smrg ;; 326fc544a13Smrg *) 327fc544a13Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328fc544a13Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329fc544a13Smrg 330fc544a13Smrg if (umask $mkdir_umask && 331fc544a13Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332fc544a13Smrg then 333fc544a13Smrg if test -z "$dir_arg" || { 334fc544a13Smrg # Check for POSIX incompatibilities with -m. 335fc544a13Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336fc544a13Smrg # other-writable bit of parent directory when it shouldn't. 337fc544a13Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338fc544a13Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339fc544a13Smrg case $ls_ld_tmpdir in 340fc544a13Smrg d????-?r-*) different_mode=700;; 341fc544a13Smrg d????-?--*) different_mode=755;; 342fc544a13Smrg *) false;; 343fc544a13Smrg esac && 344fc544a13Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345fc544a13Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346fc544a13Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347fc544a13Smrg } 348fc544a13Smrg } 349fc544a13Smrg then posix_mkdir=: 350fc544a13Smrg fi 351fc544a13Smrg rmdir "$tmpdir/d" "$tmpdir" 352fc544a13Smrg else 353fc544a13Smrg # Remove any dirs left behind by ancient mkdir implementations. 354fc544a13Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355fc544a13Smrg fi 356fc544a13Smrg trap '' 0;; 357fc544a13Smrg esac;; 3587a3b38f7Smrg esac 359ff559fabSmrg 3607a3b38f7Smrg if 3617a3b38f7Smrg $posix_mkdir && ( 362fc544a13Smrg umask $mkdir_umask && 363fc544a13Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3647a3b38f7Smrg ) 3657a3b38f7Smrg then : 3667a3b38f7Smrg else 367ff559fabSmrg 3687a3b38f7Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3697a3b38f7Smrg # or it failed possibly due to a race condition. Create the 3707a3b38f7Smrg # directory the slow way, step by step, checking for races as we go. 371ff559fabSmrg 3727a3b38f7Smrg case $dstdir in 373fc544a13Smrg /*) prefix='/';; 374fc544a13Smrg [-=\(\)!]*) prefix='./';; 375fc544a13Smrg *) prefix='';; 3767a3b38f7Smrg esac 377ff559fabSmrg 3787a3b38f7Smrg oIFS=$IFS 3797a3b38f7Smrg IFS=/ 380fc544a13Smrg set -f 3817a3b38f7Smrg set fnord $dstdir 382ff559fabSmrg shift 383fc544a13Smrg set +f 3847a3b38f7Smrg IFS=$oIFS 3857a3b38f7Smrg 3867a3b38f7Smrg prefixes= 3877a3b38f7Smrg 3887a3b38f7Smrg for d 3897a3b38f7Smrg do 390fc544a13Smrg test X"$d" = X && continue 391fc544a13Smrg 392fc544a13Smrg prefix=$prefix$d 393fc544a13Smrg if test -d "$prefix"; then 394fc544a13Smrg prefixes= 395fc544a13Smrg else 396fc544a13Smrg if $posix_mkdir; then 397fc544a13Smrg (umask=$mkdir_umask && 398fc544a13Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399fc544a13Smrg # Don't fail if two instances are running concurrently. 400fc544a13Smrg test -d "$prefix" || exit 1 401fc544a13Smrg else 402fc544a13Smrg case $prefix in 403fc544a13Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404fc544a13Smrg *) qprefix=$prefix;; 405fc544a13Smrg esac 406fc544a13Smrg prefixes="$prefixes '$qprefix'" 407fc544a13Smrg fi 408fc544a13Smrg fi 409fc544a13Smrg prefix=$prefix/ 4107a3b38f7Smrg done 4117a3b38f7Smrg 4127a3b38f7Smrg if test -n "$prefixes"; then 413fc544a13Smrg # Don't fail if two instances are running concurrently. 414fc544a13Smrg (umask $mkdir_umask && 415fc544a13Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 416fc544a13Smrg test -d "$dstdir" || exit 1 417fc544a13Smrg obsolete_mkdir_used=true 418ff559fabSmrg fi 4197a3b38f7Smrg fi 420ff559fabSmrg fi 421ff559fabSmrg 422ff559fabSmrg if test -n "$dir_arg"; then 4237a3b38f7Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4247a3b38f7Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4257a3b38f7Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4267a3b38f7Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 427ff559fabSmrg else 428ff559fabSmrg 429ff559fabSmrg # Make a couple of temp file names in the proper directory. 430ff559fabSmrg dsttmp=$dstdir/_inst.$$_ 431ff559fabSmrg rmtmp=$dstdir/_rm.$$_ 432ff559fabSmrg 433ff559fabSmrg # Trap to clean up those temp files at exit. 434ff559fabSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 435ff559fabSmrg 436ff559fabSmrg # Copy the file name to the temp name. 4377a3b38f7Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 438ff559fabSmrg 439ff559fabSmrg # and set any options; do chmod last to preserve setuid bits. 440ff559fabSmrg # 441ff559fabSmrg # If any of these fail, we abort the whole thing. If we want to 442ff559fabSmrg # ignore errors from any of these, just make sure not to ignore 443ff559fabSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 444ff559fabSmrg # 4457a3b38f7Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4467a3b38f7Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4477a3b38f7Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4487a3b38f7Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4497a3b38f7Smrg 4507a3b38f7Smrg # If -C, don't bother to copy if it wouldn't change the file. 4517a3b38f7Smrg if $copy_on_change && 452fc544a13Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453fc544a13Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454fc544a13Smrg set -f && 4557a3b38f7Smrg set X $old && old=:$2:$4:$5:$6 && 4567a3b38f7Smrg set X $new && new=:$2:$4:$5:$6 && 457fc544a13Smrg set +f && 4587a3b38f7Smrg test "$old" = "$new" && 4597a3b38f7Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4607a3b38f7Smrg then 4617a3b38f7Smrg rm -f "$dsttmp" 4627a3b38f7Smrg else 4637a3b38f7Smrg # Rename the file to the real destination. 4647a3b38f7Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4657a3b38f7Smrg 4667a3b38f7Smrg # The rename failed, perhaps because mv can't rename something else 4677a3b38f7Smrg # to itself, or perhaps because mv is so ancient that it does not 4687a3b38f7Smrg # support -f. 4697a3b38f7Smrg { 470fc544a13Smrg # Now remove or move aside any old file at destination location. 471fc544a13Smrg # We try this two ways since rm can't unlink itself on some 472fc544a13Smrg # systems and the destination file might be busy for other 473fc544a13Smrg # reasons. In this case, the final cleanup might fail but the new 474fc544a13Smrg # file should still install successfully. 475fc544a13Smrg { 476fc544a13Smrg test ! -f "$dst" || 477fc544a13Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 478fc544a13Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479fc544a13Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480fc544a13Smrg } || 481fc544a13Smrg { echo "$0: cannot unlink or rename $dst" >&2 482fc544a13Smrg (exit 1); exit 1 483fc544a13Smrg } 484fc544a13Smrg } && 485fc544a13Smrg 486fc544a13Smrg # Now rename the file to the real destination. 487fc544a13Smrg $doit $mvcmd "$dsttmp" "$dst" 4887a3b38f7Smrg } 4897a3b38f7Smrg fi || exit 1 4907a3b38f7Smrg 4917a3b38f7Smrg trap '' 0 4927a3b38f7Smrg fi 493ff559fabSmrgdone 494ff559fabSmrg 495ff559fabSmrg# Local variables: 496ff559fabSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 497ff559fabSmrg# time-stamp-start: "scriptversion=" 498ff559fabSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 49944dda7b2Smrg# time-stamp-time-zone: "UTC" 50044dda7b2Smrg# time-stamp-end: "; # UTC" 501ff559fabSmrg# End: 502