install-sh revision 084f91cc
19bd41f2cSmrg#!/bin/sh 29bd41f2cSmrg# install - install a program, script, or datafile 39bd41f2cSmrg 4084f91ccSmrgscriptversion=2020-11-14.01; # UTC 59bd41f2cSmrg 69bd41f2cSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 79bd41f2cSmrg# later released in X11R6 (xc/config/util/install.sh) with the 89bd41f2cSmrg# following copyright and license. 99bd41f2cSmrg# 109bd41f2cSmrg# Copyright (C) 1994 X Consortium 119bd41f2cSmrg# 129bd41f2cSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 139bd41f2cSmrg# of this software and associated documentation files (the "Software"), to 149bd41f2cSmrg# deal in the Software without restriction, including without limitation the 159bd41f2cSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 169bd41f2cSmrg# sell copies of the Software, and to permit persons to whom the Software is 179bd41f2cSmrg# furnished to do so, subject to the following conditions: 189bd41f2cSmrg# 199bd41f2cSmrg# The above copyright notice and this permission notice shall be included in 209bd41f2cSmrg# all copies or substantial portions of the Software. 219bd41f2cSmrg# 229bd41f2cSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 239bd41f2cSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 249bd41f2cSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 259bd41f2cSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 269bd41f2cSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 279bd41f2cSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 289bd41f2cSmrg# 299bd41f2cSmrg# Except as contained in this notice, the name of the X Consortium shall not 309bd41f2cSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 319bd41f2cSmrg# ings in this Software without prior written authorization from the X Consor- 329bd41f2cSmrg# tium. 339bd41f2cSmrg# 349bd41f2cSmrg# 359bd41f2cSmrg# FSF changes to this file are in the public domain. 369bd41f2cSmrg# 379bd41f2cSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38084f91ccSmrg# 'make' implicit rules from creating a file called install from it 399bd41f2cSmrg# when there is no Makefile. 409bd41f2cSmrg# 419bd41f2cSmrg# This script is compatible with the BSD install script, but was written 429418810dSmrg# from scratch. 439418810dSmrg 44084f91ccSmrgtab=' ' 459418810dSmrgnl=' 469418810dSmrg' 47084f91ccSmrgIFS=" $tab$nl" 489bd41f2cSmrg 49084f91ccSmrg# Set DOITPROG to "echo" to test this script. 509bd41f2cSmrg 519418810dSmrgdoit=${DOITPROG-} 52084f91ccSmrgdoit_exec=${doit:-exec} 539bd41f2cSmrg 549418810dSmrg# Put in absolute file names if you don't have them in your path; 559418810dSmrg# or use environment vars. 569418810dSmrg 579418810dSmrgchgrpprog=${CHGRPPROG-chgrp} 589418810dSmrgchmodprog=${CHMODPROG-chmod} 599418810dSmrgchownprog=${CHOWNPROG-chown} 609418810dSmrgcmpprog=${CMPPROG-cmp} 619418810dSmrgcpprog=${CPPROG-cp} 629418810dSmrgmkdirprog=${MKDIRPROG-mkdir} 639418810dSmrgmvprog=${MVPROG-mv} 649418810dSmrgrmprog=${RMPROG-rm} 659418810dSmrgstripprog=${STRIPPROG-strip} 669418810dSmrg 679418810dSmrgposix_mkdir= 689418810dSmrg 699418810dSmrg# Desired mode of installed file. 709418810dSmrgmode=0755 719bd41f2cSmrg 72084f91ccSmrg# Create dirs (including intermediate dirs) using mode 755. 73084f91ccSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74084f91ccSmrgmkdir_umask=22 75084f91ccSmrg 76084f91ccSmrgbackupsuffix= 779bd41f2cSmrgchgrpcmd= 789418810dSmrgchmodcmd=$chmodprog 799418810dSmrgchowncmd= 809418810dSmrgmvcmd=$mvprog 819bd41f2cSmrgrmcmd="$rmprog -f" 829418810dSmrgstripcmd= 839418810dSmrg 849bd41f2cSmrgsrc= 859bd41f2cSmrgdst= 869bd41f2cSmrgdir_arg= 879418810dSmrgdst_arg= 889418810dSmrg 899418810dSmrgcopy_on_change=false 90084f91ccSmrgis_target_a_directory=possibly 919bd41f2cSmrg 929418810dSmrgusage="\ 939418810dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 949bd41f2cSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 959bd41f2cSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 969bd41f2cSmrg or: $0 [OPTION]... -d DIRECTORIES... 979bd41f2cSmrg 989bd41f2cSmrgIn the 1st form, copy SRCFILE to DSTFILE. 999bd41f2cSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1009bd41f2cSmrgIn the 4th, create DIRECTORIES. 1019bd41f2cSmrg 1029bd41f2cSmrgOptions: 1039418810dSmrg --help display this help and exit. 1049418810dSmrg --version display version info and exit. 1059418810dSmrg 1069418810dSmrg -c (ignored) 107084f91ccSmrg -C install only if different (preserve data modification time) 1089418810dSmrg -d create directories instead of installing files. 1099418810dSmrg -g GROUP $chgrpprog installed files to GROUP. 1109418810dSmrg -m MODE $chmodprog installed files to MODE. 1119418810dSmrg -o USER $chownprog installed files to USER. 112084f91ccSmrg -p pass -p to $cpprog. 1139418810dSmrg -s $stripprog installed files. 114084f91ccSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1159418810dSmrg -t DIRECTORY install into DIRECTORY. 1169418810dSmrg -T report an error if DSTFILE is a directory. 1179bd41f2cSmrg 1189bd41f2cSmrgEnvironment variables override the default commands: 1199418810dSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1209418810dSmrg RMPROG STRIPPROG 121084f91ccSmrg 122084f91ccSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123084f91ccSmrgit's up to you to specify -f if you want it. 124084f91ccSmrg 125084f91ccSmrgIf -S is not specified, no backups are attempted. 126084f91ccSmrg 127084f91ccSmrgEmail bug reports to bug-automake@gnu.org. 128084f91ccSmrgAutomake home page: https://www.gnu.org/software/automake/ 1299bd41f2cSmrg" 1309bd41f2cSmrg 1319418810dSmrgwhile test $# -ne 0; do 1329bd41f2cSmrg case $1 in 1339418810dSmrg -c) ;; 1349418810dSmrg 1359418810dSmrg -C) copy_on_change=true;; 1369bd41f2cSmrg 1379418810dSmrg -d) dir_arg=true;; 1389bd41f2cSmrg 1399bd41f2cSmrg -g) chgrpcmd="$chgrpprog $2" 140084f91ccSmrg shift;; 1419bd41f2cSmrg 1429bd41f2cSmrg --help) echo "$usage"; exit $?;; 1439bd41f2cSmrg 1449418810dSmrg -m) mode=$2 145084f91ccSmrg case $mode in 146084f91ccSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147084f91ccSmrg echo "$0: invalid mode: $mode" >&2 148084f91ccSmrg exit 1;; 149084f91ccSmrg esac 150084f91ccSmrg shift;; 1519bd41f2cSmrg 1529bd41f2cSmrg -o) chowncmd="$chownprog $2" 153084f91ccSmrg shift;; 154084f91ccSmrg 155084f91ccSmrg -p) cpprog="$cpprog -p";; 1569bd41f2cSmrg 1579418810dSmrg -s) stripcmd=$stripprog;; 1589bd41f2cSmrg 159084f91ccSmrg -S) backupsuffix="$2" 160084f91ccSmrg shift;; 1619bd41f2cSmrg 162084f91ccSmrg -t) 163084f91ccSmrg is_target_a_directory=always 164084f91ccSmrg dst_arg=$2 165084f91ccSmrg # Protect names problematic for 'test' and other utilities. 166084f91ccSmrg case $dst_arg in 167084f91ccSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168084f91ccSmrg esac 169084f91ccSmrg shift;; 170084f91ccSmrg 171084f91ccSmrg -T) is_target_a_directory=never;; 1729bd41f2cSmrg 1739bd41f2cSmrg --version) echo "$0 $scriptversion"; exit $?;; 1749bd41f2cSmrg 175084f91ccSmrg --) shift 176084f91ccSmrg break;; 1779418810dSmrg 178084f91ccSmrg -*) echo "$0: invalid option: $1" >&2 179084f91ccSmrg exit 1;; 1809418810dSmrg 1819418810dSmrg *) break;; 1829bd41f2cSmrg esac 1839418810dSmrg shift 1849bd41f2cSmrgdone 1859bd41f2cSmrg 186084f91ccSmrg# We allow the use of options -d and -T together, by making -d 187084f91ccSmrg# take the precedence; this is for compatibility with GNU install. 188084f91ccSmrg 189084f91ccSmrgif test -n "$dir_arg"; then 190084f91ccSmrg if test -n "$dst_arg"; then 191084f91ccSmrg echo "$0: target directory not allowed when installing a directory." >&2 192084f91ccSmrg exit 1 193084f91ccSmrg fi 194084f91ccSmrgfi 195084f91ccSmrg 1969418810dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1979418810dSmrg # When -d is used, all remaining arguments are directories to create. 1989418810dSmrg # When -t is used, the destination is already specified. 1999418810dSmrg # Otherwise, the last argument is the destination. Remove it from $@. 2009418810dSmrg for arg 2019418810dSmrg do 2029418810dSmrg if test -n "$dst_arg"; then 2039418810dSmrg # $@ is not empty: it contains at least $arg. 2049418810dSmrg set fnord "$@" "$dst_arg" 2059418810dSmrg shift # fnord 2069418810dSmrg fi 2079418810dSmrg shift # arg 2089418810dSmrg dst_arg=$arg 209084f91ccSmrg # Protect names problematic for 'test' and other utilities. 2100da4cdccSmrg case $dst_arg in 2110da4cdccSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 2120da4cdccSmrg esac 2139418810dSmrg done 2149418810dSmrgfi 2159418810dSmrg 2169418810dSmrgif test $# -eq 0; then 2179bd41f2cSmrg if test -z "$dir_arg"; then 2189bd41f2cSmrg echo "$0: no input file specified." >&2 2199bd41f2cSmrg exit 1 2209bd41f2cSmrg fi 221084f91ccSmrg # It's OK to call 'install-sh -d' without argument. 2229bd41f2cSmrg # This can happen when creating conditional directories. 2239bd41f2cSmrg exit 0 2249bd41f2cSmrgfi 2259bd41f2cSmrg 226084f91ccSmrgif test -z "$dir_arg"; then 227084f91ccSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228084f91ccSmrg if test ! -d "$dst_arg"; then 229084f91ccSmrg echo "$0: $dst_arg: Is not a directory." >&2 230084f91ccSmrg exit 1 231084f91ccSmrg fi 232084f91ccSmrg fi 233084f91ccSmrgfi 234084f91ccSmrg 2359418810dSmrgif test -z "$dir_arg"; then 2360da4cdccSmrg do_exit='(exit $ret); exit $ret' 2370da4cdccSmrg trap "ret=129; $do_exit" 1 2380da4cdccSmrg trap "ret=130; $do_exit" 2 2390da4cdccSmrg trap "ret=141; $do_exit" 13 2400da4cdccSmrg trap "ret=143; $do_exit" 15 2419418810dSmrg 2429418810dSmrg # Set umask so as not to create temps with too-generous modes. 2439418810dSmrg # However, 'strip' requires both read and write access to temps. 2449418810dSmrg case $mode in 2459418810dSmrg # Optimize common cases. 2469418810dSmrg *644) cp_umask=133;; 2479418810dSmrg *755) cp_umask=22;; 2489418810dSmrg 2499418810dSmrg *[0-7]) 2509418810dSmrg if test -z "$stripcmd"; then 251084f91ccSmrg u_plus_rw= 2529418810dSmrg else 253084f91ccSmrg u_plus_rw='% 200' 2549418810dSmrg fi 2559418810dSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2569418810dSmrg *) 2579418810dSmrg if test -z "$stripcmd"; then 258084f91ccSmrg u_plus_rw= 2599418810dSmrg else 260084f91ccSmrg u_plus_rw=,u+rw 2619418810dSmrg fi 2629418810dSmrg cp_umask=$mode$u_plus_rw;; 2639418810dSmrg esac 2649418810dSmrgfi 2659418810dSmrg 2669bd41f2cSmrgfor src 2679bd41f2cSmrgdo 268084f91ccSmrg # Protect names problematic for 'test' and other utilities. 2699bd41f2cSmrg case $src in 2700da4cdccSmrg -* | [=\(\)!]) src=./$src;; 2719bd41f2cSmrg esac 2729bd41f2cSmrg 2739bd41f2cSmrg if test -n "$dir_arg"; then 2749bd41f2cSmrg dst=$src 2759418810dSmrg dstdir=$dst 2769418810dSmrg test -d "$dstdir" 2779418810dSmrg dstdir_status=$? 278084f91ccSmrg # Don't chown directories that already exist. 279084f91ccSmrg if test $dstdir_status = 0; then 280084f91ccSmrg chowncmd="" 281084f91ccSmrg fi 282d075918cSmrg else 2839418810dSmrg 2849bd41f2cSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2859bd41f2cSmrg # might cause directories to be created, which would be especially bad 2869bd41f2cSmrg # if $src (and thus $dsttmp) contains '*'. 2879bd41f2cSmrg if test ! -f "$src" && test ! -d "$src"; then 2889bd41f2cSmrg echo "$0: $src does not exist." >&2 2899bd41f2cSmrg exit 1 2909bd41f2cSmrg fi 2919bd41f2cSmrg 2929418810dSmrg if test -z "$dst_arg"; then 2939bd41f2cSmrg echo "$0: no destination specified." >&2 2949bd41f2cSmrg exit 1 2959bd41f2cSmrg fi 2969418810dSmrg dst=$dst_arg 2979bd41f2cSmrg 298084f91ccSmrg # If destination is a directory, append the input filename. 2999bd41f2cSmrg if test -d "$dst"; then 300084f91ccSmrg if test "$is_target_a_directory" = never; then 301084f91ccSmrg echo "$0: $dst_arg: Is a directory" >&2 302084f91ccSmrg exit 1 3039bd41f2cSmrg fi 3049418810dSmrg dstdir=$dst 305084f91ccSmrg dstbase=`basename "$src"` 306084f91ccSmrg case $dst in 307084f91ccSmrg */) dst=$dst$dstbase;; 308084f91ccSmrg *) dst=$dst/$dstbase;; 309084f91ccSmrg esac 3109418810dSmrg dstdir_status=0 3119418810dSmrg else 312084f91ccSmrg dstdir=`dirname "$dst"` 3139418810dSmrg test -d "$dstdir" 3149418810dSmrg dstdir_status=$? 3159bd41f2cSmrg fi 3169bd41f2cSmrg fi 3179bd41f2cSmrg 318084f91ccSmrg case $dstdir in 319084f91ccSmrg */) dstdirslash=$dstdir;; 320084f91ccSmrg *) dstdirslash=$dstdir/;; 321084f91ccSmrg esac 322084f91ccSmrg 3239418810dSmrg obsolete_mkdir_used=false 3249418810dSmrg 3259418810dSmrg if test $dstdir_status != 0; then 3269418810dSmrg case $posix_mkdir in 3279418810dSmrg '') 328084f91ccSmrg # With -d, create the new directory with the user-specified mode. 329084f91ccSmrg # Otherwise, rely on $mkdir_umask. 330084f91ccSmrg if test -n "$dir_arg"; then 331084f91ccSmrg mkdir_mode=-m$mode 332084f91ccSmrg else 333084f91ccSmrg mkdir_mode= 334084f91ccSmrg fi 335084f91ccSmrg 336084f91ccSmrg posix_mkdir=false 337084f91ccSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 338084f91ccSmrg # here however when possible just to lower collision chance. 339084f91ccSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340084f91ccSmrg 341084f91ccSmrg trap ' 342084f91ccSmrg ret=$? 343084f91ccSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344084f91ccSmrg exit $ret 345084f91ccSmrg ' 0 346084f91ccSmrg 347084f91ccSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348084f91ccSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349084f91ccSmrg # directory is successfully created first before we actually test 350084f91ccSmrg # 'mkdir -p'. 351084f91ccSmrg if (umask $mkdir_umask && 352084f91ccSmrg $mkdirprog $mkdir_mode "$tmpdir" && 353084f91ccSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354084f91ccSmrg then 355084f91ccSmrg if test -z "$dir_arg" || { 356084f91ccSmrg # Check for POSIX incompatibilities with -m. 357084f91ccSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358084f91ccSmrg # other-writable bit of parent directory when it shouldn't. 359084f91ccSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360084f91ccSmrg test_tmpdir="$tmpdir/a" 361084f91ccSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362084f91ccSmrg case $ls_ld_tmpdir in 363084f91ccSmrg d????-?r-*) different_mode=700;; 364084f91ccSmrg d????-?--*) different_mode=755;; 365084f91ccSmrg *) false;; 366084f91ccSmrg esac && 367084f91ccSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368084f91ccSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369084f91ccSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370084f91ccSmrg } 371084f91ccSmrg } 372084f91ccSmrg then posix_mkdir=: 373084f91ccSmrg fi 374084f91ccSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3759418810dSmrg else 376084f91ccSmrg # Remove any dirs left behind by ancient mkdir implementations. 377084f91ccSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3789418810dSmrg fi 379084f91ccSmrg trap '' 0;; 3809418810dSmrg esac 3819bd41f2cSmrg 3829418810dSmrg if 3839418810dSmrg $posix_mkdir && ( 384084f91ccSmrg umask $mkdir_umask && 385084f91ccSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3869418810dSmrg ) 3879418810dSmrg then : 3889418810dSmrg else 389d075918cSmrg 390084f91ccSmrg # mkdir does not conform to POSIX, 3919418810dSmrg # or it failed possibly due to a race condition. Create the 3929418810dSmrg # directory the slow way, step by step, checking for races as we go. 3939bd41f2cSmrg 3949418810dSmrg case $dstdir in 395084f91ccSmrg /*) prefix='/';; 396084f91ccSmrg [-=\(\)!]*) prefix='./';; 397084f91ccSmrg *) prefix='';; 3989418810dSmrg esac 399d075918cSmrg 4009418810dSmrg oIFS=$IFS 4019418810dSmrg IFS=/ 402084f91ccSmrg set -f 4039418810dSmrg set fnord $dstdir 4049bd41f2cSmrg shift 405084f91ccSmrg set +f 4069418810dSmrg IFS=$oIFS 4079418810dSmrg 4089418810dSmrg prefixes= 4099418810dSmrg 4109418810dSmrg for d 4119418810dSmrg do 412084f91ccSmrg test X"$d" = X && continue 413084f91ccSmrg 414084f91ccSmrg prefix=$prefix$d 415084f91ccSmrg if test -d "$prefix"; then 416084f91ccSmrg prefixes= 417084f91ccSmrg else 418084f91ccSmrg if $posix_mkdir; then 419084f91ccSmrg (umask $mkdir_umask && 420084f91ccSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421084f91ccSmrg # Don't fail if two instances are running concurrently. 422084f91ccSmrg test -d "$prefix" || exit 1 423084f91ccSmrg else 424084f91ccSmrg case $prefix in 425084f91ccSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426084f91ccSmrg *) qprefix=$prefix;; 427084f91ccSmrg esac 428084f91ccSmrg prefixes="$prefixes '$qprefix'" 429084f91ccSmrg fi 430084f91ccSmrg fi 431084f91ccSmrg prefix=$prefix/ 4329418810dSmrg done 4339418810dSmrg 4349418810dSmrg if test -n "$prefixes"; then 435084f91ccSmrg # Don't fail if two instances are running concurrently. 436084f91ccSmrg (umask $mkdir_umask && 437084f91ccSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 438084f91ccSmrg test -d "$dstdir" || exit 1 439084f91ccSmrg obsolete_mkdir_used=true 4409bd41f2cSmrg fi 4419418810dSmrg fi 4429bd41f2cSmrg fi 4439bd41f2cSmrg 4449bd41f2cSmrg if test -n "$dir_arg"; then 4459418810dSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4469418810dSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4479418810dSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4489418810dSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4499bd41f2cSmrg else 4509bd41f2cSmrg 4519bd41f2cSmrg # Make a couple of temp file names in the proper directory. 452084f91ccSmrg dsttmp=${dstdirslash}_inst.$$_ 453084f91ccSmrg rmtmp=${dstdirslash}_rm.$$_ 4549bd41f2cSmrg 4559bd41f2cSmrg # Trap to clean up those temp files at exit. 4569bd41f2cSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4579bd41f2cSmrg 4589bd41f2cSmrg # Copy the file name to the temp name. 459084f91ccSmrg (umask $cp_umask && 460084f91ccSmrg { test -z "$stripcmd" || { 461084f91ccSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462084f91ccSmrg # which would cause strip to fail. 463084f91ccSmrg if test -z "$doit"; then 464084f91ccSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 465084f91ccSmrg else 466084f91ccSmrg $doit touch "$dsttmp" 467084f91ccSmrg fi 468084f91ccSmrg } 469084f91ccSmrg } && 470084f91ccSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4719bd41f2cSmrg 4729bd41f2cSmrg # and set any options; do chmod last to preserve setuid bits. 4739bd41f2cSmrg # 4749bd41f2cSmrg # If any of these fail, we abort the whole thing. If we want to 4759bd41f2cSmrg # ignore errors from any of these, just make sure not to ignore 4769bd41f2cSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4779bd41f2cSmrg # 4789418810dSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4799418810dSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4809418810dSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4819418810dSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4829418810dSmrg 4839418810dSmrg # If -C, don't bother to copy if it wouldn't change the file. 4849418810dSmrg if $copy_on_change && 485084f91ccSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486084f91ccSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487084f91ccSmrg set -f && 4889418810dSmrg set X $old && old=:$2:$4:$5:$6 && 4899418810dSmrg set X $new && new=:$2:$4:$5:$6 && 490084f91ccSmrg set +f && 4919418810dSmrg test "$old" = "$new" && 4929418810dSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4939418810dSmrg then 4949418810dSmrg rm -f "$dsttmp" 4959418810dSmrg else 496084f91ccSmrg # If $backupsuffix is set, and the file being installed 497084f91ccSmrg # already exists, attempt a backup. Don't worry if it fails, 498084f91ccSmrg # e.g., if mv doesn't support -f. 499084f91ccSmrg if test -n "$backupsuffix" && test -f "$dst"; then 500084f91ccSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501084f91ccSmrg fi 502084f91ccSmrg 5039418810dSmrg # Rename the file to the real destination. 5049418810dSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5059418810dSmrg 5069418810dSmrg # The rename failed, perhaps because mv can't rename something else 5079418810dSmrg # to itself, or perhaps because mv is so ancient that it does not 5089418810dSmrg # support -f. 5099418810dSmrg { 510084f91ccSmrg # Now remove or move aside any old file at destination location. 511084f91ccSmrg # We try this two ways since rm can't unlink itself on some 512084f91ccSmrg # systems and the destination file might be busy for other 513084f91ccSmrg # reasons. In this case, the final cleanup might fail but the new 514084f91ccSmrg # file should still install successfully. 515084f91ccSmrg { 516084f91ccSmrg test ! -f "$dst" || 517084f91ccSmrg $doit $rmcmd "$dst" 2>/dev/null || 518084f91ccSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519084f91ccSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520084f91ccSmrg } || 521084f91ccSmrg { echo "$0: cannot unlink or rename $dst" >&2 522084f91ccSmrg (exit 1); exit 1 523084f91ccSmrg } 524084f91ccSmrg } && 525084f91ccSmrg 526084f91ccSmrg # Now rename the file to the real destination. 527084f91ccSmrg $doit $mvcmd "$dsttmp" "$dst" 5289418810dSmrg } 5299418810dSmrg fi || exit 1 5309418810dSmrg 5319418810dSmrg trap '' 0 5329418810dSmrg fi 5339bd41f2cSmrgdone 5349bd41f2cSmrg 5359bd41f2cSmrg# Local variables: 536084f91ccSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5379bd41f2cSmrg# time-stamp-start: "scriptversion=" 5389bd41f2cSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539084f91ccSmrg# time-stamp-time-zone: "UTC0" 5400da4cdccSmrg# time-stamp-end: "; # UTC" 5419bd41f2cSmrg# End: 542