11cc8c64fSmrg#!/bin/sh 21cc8c64fSmrg# install - install a program, script, or datafile 3b9bb67cbSmrg 418eba588Smrgscriptversion=2020-11-14.01; # UTC 5b9bb67cbSmrg 61cc8c64fSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 71cc8c64fSmrg# later released in X11R6 (xc/config/util/install.sh) with the 81cc8c64fSmrg# following copyright and license. 91cc8c64fSmrg# 101cc8c64fSmrg# Copyright (C) 1994 X Consortium 111cc8c64fSmrg# 121cc8c64fSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 131cc8c64fSmrg# of this software and associated documentation files (the "Software"), to 141cc8c64fSmrg# deal in the Software without restriction, including without limitation the 151cc8c64fSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 161cc8c64fSmrg# sell copies of the Software, and to permit persons to whom the Software is 171cc8c64fSmrg# furnished to do so, subject to the following conditions: 181cc8c64fSmrg# 191cc8c64fSmrg# The above copyright notice and this permission notice shall be included in 201cc8c64fSmrg# all copies or substantial portions of the Software. 211cc8c64fSmrg# 221cc8c64fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 231cc8c64fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 241cc8c64fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 251cc8c64fSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 261cc8c64fSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 271cc8c64fSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 281cc8c64fSmrg# 291cc8c64fSmrg# Except as contained in this notice, the name of the X Consortium shall not 301cc8c64fSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 311cc8c64fSmrg# ings in this Software without prior written authorization from the X Consor- 321cc8c64fSmrg# tium. 331cc8c64fSmrg# 341cc8c64fSmrg# 351cc8c64fSmrg# FSF changes to this file are in the public domain. 361cc8c64fSmrg# 371cc8c64fSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3818eba588Smrg# 'make' implicit rules from creating a file called install from it 391cc8c64fSmrg# when there is no Makefile. 401cc8c64fSmrg# 411cc8c64fSmrg# This script is compatible with the BSD install script, but was written 42b9bb67cbSmrg# from scratch. 431cc8c64fSmrg 4418eba588Smrgtab=' ' 45b9bb67cbSmrgnl=' 46b9bb67cbSmrg' 4718eba588SmrgIFS=" $tab$nl" 481cc8c64fSmrg 4918eba588Smrg# Set DOITPROG to "echo" to test this script. 501cc8c64fSmrg 51b9bb67cbSmrgdoit=${DOITPROG-} 5218eba588Smrgdoit_exec=${doit:-exec} 531cc8c64fSmrg 54b9bb67cbSmrg# Put in absolute file names if you don't have them in your path; 55b9bb67cbSmrg# or use environment vars. 56b9bb67cbSmrg 57b9bb67cbSmrgchgrpprog=${CHGRPPROG-chgrp} 58b9bb67cbSmrgchmodprog=${CHMODPROG-chmod} 59b9bb67cbSmrgchownprog=${CHOWNPROG-chown} 60b9bb67cbSmrgcmpprog=${CMPPROG-cmp} 61b9bb67cbSmrgcpprog=${CPPROG-cp} 62b9bb67cbSmrgmkdirprog=${MKDIRPROG-mkdir} 63b9bb67cbSmrgmvprog=${MVPROG-mv} 64b9bb67cbSmrgrmprog=${RMPROG-rm} 65b9bb67cbSmrgstripprog=${STRIPPROG-strip} 66b9bb67cbSmrg 67b9bb67cbSmrgposix_mkdir= 68b9bb67cbSmrg 69b9bb67cbSmrg# Desired mode of installed file. 70b9bb67cbSmrgmode=0755 71b9bb67cbSmrg 7218eba588Smrg# Create dirs (including intermediate dirs) using mode 755. 7318eba588Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 7418eba588Smrgmkdir_umask=22 7518eba588Smrg 7618eba588Smrgbackupsuffix= 77b9bb67cbSmrgchgrpcmd= 78b9bb67cbSmrgchmodcmd=$chmodprog 79b9bb67cbSmrgchowncmd= 80b9bb67cbSmrgmvcmd=$mvprog 81b9bb67cbSmrgrmcmd="$rmprog -f" 82b9bb67cbSmrgstripcmd= 831cc8c64fSmrg 84b9bb67cbSmrgsrc= 85b9bb67cbSmrgdst= 86b9bb67cbSmrgdir_arg= 87b9bb67cbSmrgdst_arg= 881cc8c64fSmrg 89b9bb67cbSmrgcopy_on_change=false 9018eba588Smrgis_target_a_directory=possibly 911cc8c64fSmrg 92b9bb67cbSmrgusage="\ 93b9bb67cbSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94b9bb67cbSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95b9bb67cbSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96b9bb67cbSmrg or: $0 [OPTION]... -d DIRECTORIES... 971cc8c64fSmrg 98b9bb67cbSmrgIn the 1st form, copy SRCFILE to DSTFILE. 99b9bb67cbSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100b9bb67cbSmrgIn the 4th, create DIRECTORIES. 1011cc8c64fSmrg 102b9bb67cbSmrgOptions: 103b9bb67cbSmrg --help display this help and exit. 104b9bb67cbSmrg --version display version info and exit. 1051cc8c64fSmrg 106b9bb67cbSmrg -c (ignored) 10718eba588Smrg -C install only if different (preserve data modification time) 108b9bb67cbSmrg -d create directories instead of installing files. 109b9bb67cbSmrg -g GROUP $chgrpprog installed files to GROUP. 110b9bb67cbSmrg -m MODE $chmodprog installed files to MODE. 111b9bb67cbSmrg -o USER $chownprog installed files to USER. 11218eba588Smrg -p pass -p to $cpprog. 113b9bb67cbSmrg -s $stripprog installed files. 11418eba588Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115b9bb67cbSmrg -t DIRECTORY install into DIRECTORY. 116b9bb67cbSmrg -T report an error if DSTFILE is a directory. 1171cc8c64fSmrg 118b9bb67cbSmrgEnvironment variables override the default commands: 119b9bb67cbSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120b9bb67cbSmrg RMPROG STRIPPROG 12118eba588Smrg 12218eba588SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 12318eba588Smrgit's up to you to specify -f if you want it. 12418eba588Smrg 12518eba588SmrgIf -S is not specified, no backups are attempted. 12618eba588Smrg 12718eba588SmrgEmail bug reports to bug-automake@gnu.org. 12818eba588SmrgAutomake home page: https://www.gnu.org/software/automake/ 129b9bb67cbSmrg" 1301cc8c64fSmrg 131b9bb67cbSmrgwhile test $# -ne 0; do 132b9bb67cbSmrg case $1 in 133b9bb67cbSmrg -c) ;; 1341cc8c64fSmrg 135b9bb67cbSmrg -C) copy_on_change=true;; 1361cc8c64fSmrg 137b9bb67cbSmrg -d) dir_arg=true;; 1381cc8c64fSmrg 139b9bb67cbSmrg -g) chgrpcmd="$chgrpprog $2" 14018eba588Smrg shift;; 1411cc8c64fSmrg 142b9bb67cbSmrg --help) echo "$usage"; exit $?;; 1431cc8c64fSmrg 144b9bb67cbSmrg -m) mode=$2 14518eba588Smrg case $mode in 14618eba588Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14718eba588Smrg echo "$0: invalid mode: $mode" >&2 14818eba588Smrg exit 1;; 14918eba588Smrg esac 15018eba588Smrg shift;; 1511cc8c64fSmrg 152b9bb67cbSmrg -o) chowncmd="$chownprog $2" 15318eba588Smrg shift;; 15418eba588Smrg 15518eba588Smrg -p) cpprog="$cpprog -p";; 1561cc8c64fSmrg 157b9bb67cbSmrg -s) stripcmd=$stripprog;; 1581cc8c64fSmrg 15918eba588Smrg -S) backupsuffix="$2" 16018eba588Smrg shift;; 16118eba588Smrg 16218eba588Smrg -t) 16318eba588Smrg is_target_a_directory=always 16418eba588Smrg dst_arg=$2 16518eba588Smrg # Protect names problematic for 'test' and other utilities. 16618eba588Smrg case $dst_arg in 16718eba588Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16818eba588Smrg esac 16918eba588Smrg shift;; 1701cc8c64fSmrg 17118eba588Smrg -T) is_target_a_directory=never;; 1721cc8c64fSmrg 173b9bb67cbSmrg --version) echo "$0 $scriptversion"; exit $?;; 1741cc8c64fSmrg 17518eba588Smrg --) shift 17618eba588Smrg break;; 1771cc8c64fSmrg 17818eba588Smrg -*) echo "$0: invalid option: $1" >&2 17918eba588Smrg exit 1;; 1801cc8c64fSmrg 181b9bb67cbSmrg *) break;; 182b9bb67cbSmrg esac 183b9bb67cbSmrg shift 184b9bb67cbSmrgdone 1851cc8c64fSmrg 18618eba588Smrg# We allow the use of options -d and -T together, by making -d 18718eba588Smrg# take the precedence; this is for compatibility with GNU install. 18818eba588Smrg 18918eba588Smrgif test -n "$dir_arg"; then 19018eba588Smrg if test -n "$dst_arg"; then 19118eba588Smrg echo "$0: target directory not allowed when installing a directory." >&2 19218eba588Smrg exit 1 19318eba588Smrg fi 19418eba588Smrgfi 19518eba588Smrg 196b9bb67cbSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197b9bb67cbSmrg # When -d is used, all remaining arguments are directories to create. 198b9bb67cbSmrg # When -t is used, the destination is already specified. 199b9bb67cbSmrg # Otherwise, the last argument is the destination. Remove it from $@. 200b9bb67cbSmrg for arg 201b9bb67cbSmrg do 202b9bb67cbSmrg if test -n "$dst_arg"; then 203b9bb67cbSmrg # $@ is not empty: it contains at least $arg. 204b9bb67cbSmrg set fnord "$@" "$dst_arg" 205b9bb67cbSmrg shift # fnord 206b9bb67cbSmrg fi 207b9bb67cbSmrg shift # arg 208b9bb67cbSmrg dst_arg=$arg 20918eba588Smrg # Protect names problematic for 'test' and other utilities. 21018eba588Smrg case $dst_arg in 21118eba588Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21218eba588Smrg esac 213b9bb67cbSmrg done 214b9bb67cbSmrgfi 2151cc8c64fSmrg 216b9bb67cbSmrgif test $# -eq 0; then 217b9bb67cbSmrg if test -z "$dir_arg"; then 218b9bb67cbSmrg echo "$0: no input file specified." >&2 219b9bb67cbSmrg exit 1 220b9bb67cbSmrg fi 22118eba588Smrg # It's OK to call 'install-sh -d' without argument. 222b9bb67cbSmrg # This can happen when creating conditional directories. 223b9bb67cbSmrg exit 0 224b9bb67cbSmrgfi 2251cc8c64fSmrg 226b9bb67cbSmrgif test -z "$dir_arg"; then 22718eba588Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22818eba588Smrg if test ! -d "$dst_arg"; then 22918eba588Smrg echo "$0: $dst_arg: Is not a directory." >&2 23018eba588Smrg exit 1 23118eba588Smrg fi 23218eba588Smrg fi 23318eba588Smrgfi 23418eba588Smrg 23518eba588Smrgif test -z "$dir_arg"; then 23618eba588Smrg do_exit='(exit $ret); exit $ret' 23718eba588Smrg trap "ret=129; $do_exit" 1 23818eba588Smrg trap "ret=130; $do_exit" 2 23918eba588Smrg trap "ret=141; $do_exit" 13 24018eba588Smrg trap "ret=143; $do_exit" 15 241b9bb67cbSmrg 242b9bb67cbSmrg # Set umask so as not to create temps with too-generous modes. 243b9bb67cbSmrg # However, 'strip' requires both read and write access to temps. 244b9bb67cbSmrg case $mode in 245b9bb67cbSmrg # Optimize common cases. 246b9bb67cbSmrg *644) cp_umask=133;; 247b9bb67cbSmrg *755) cp_umask=22;; 248b9bb67cbSmrg 249b9bb67cbSmrg *[0-7]) 250b9bb67cbSmrg if test -z "$stripcmd"; then 25118eba588Smrg u_plus_rw= 252b9bb67cbSmrg else 25318eba588Smrg u_plus_rw='% 200' 254b9bb67cbSmrg fi 255b9bb67cbSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256b9bb67cbSmrg *) 257b9bb67cbSmrg if test -z "$stripcmd"; then 25818eba588Smrg u_plus_rw= 259b9bb67cbSmrg else 26018eba588Smrg u_plus_rw=,u+rw 261b9bb67cbSmrg fi 262b9bb67cbSmrg cp_umask=$mode$u_plus_rw;; 263b9bb67cbSmrg esac 264b9bb67cbSmrgfi 2651cc8c64fSmrg 266b9bb67cbSmrgfor src 267b9bb67cbSmrgdo 26818eba588Smrg # Protect names problematic for 'test' and other utilities. 269b9bb67cbSmrg case $src in 27018eba588Smrg -* | [=\(\)!]) src=./$src;; 271b9bb67cbSmrg esac 272b9bb67cbSmrg 273b9bb67cbSmrg if test -n "$dir_arg"; then 274b9bb67cbSmrg dst=$src 275b9bb67cbSmrg dstdir=$dst 276b9bb67cbSmrg test -d "$dstdir" 277b9bb67cbSmrg dstdir_status=$? 27818eba588Smrg # Don't chown directories that already exist. 27918eba588Smrg if test $dstdir_status = 0; then 28018eba588Smrg chowncmd="" 28118eba588Smrg fi 282b9bb67cbSmrg else 283b9bb67cbSmrg 284b9bb67cbSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285b9bb67cbSmrg # might cause directories to be created, which would be especially bad 286b9bb67cbSmrg # if $src (and thus $dsttmp) contains '*'. 287b9bb67cbSmrg if test ! -f "$src" && test ! -d "$src"; then 288b9bb67cbSmrg echo "$0: $src does not exist." >&2 289b9bb67cbSmrg exit 1 290b9bb67cbSmrg fi 291b9bb67cbSmrg 292b9bb67cbSmrg if test -z "$dst_arg"; then 293b9bb67cbSmrg echo "$0: no destination specified." >&2 294b9bb67cbSmrg exit 1 295b9bb67cbSmrg fi 296b9bb67cbSmrg dst=$dst_arg 2971cc8c64fSmrg 29818eba588Smrg # If destination is a directory, append the input filename. 299b9bb67cbSmrg if test -d "$dst"; then 30018eba588Smrg if test "$is_target_a_directory" = never; then 30118eba588Smrg echo "$0: $dst_arg: Is a directory" >&2 30218eba588Smrg exit 1 303b9bb67cbSmrg fi 304b9bb67cbSmrg dstdir=$dst 30518eba588Smrg dstbase=`basename "$src"` 30618eba588Smrg case $dst in 30718eba588Smrg */) dst=$dst$dstbase;; 30818eba588Smrg *) dst=$dst/$dstbase;; 30918eba588Smrg esac 310b9bb67cbSmrg dstdir_status=0 311b9bb67cbSmrg else 31218eba588Smrg dstdir=`dirname "$dst"` 313b9bb67cbSmrg test -d "$dstdir" 314b9bb67cbSmrg dstdir_status=$? 315b9bb67cbSmrg fi 316b9bb67cbSmrg fi 317b9bb67cbSmrg 31818eba588Smrg case $dstdir in 31918eba588Smrg */) dstdirslash=$dstdir;; 32018eba588Smrg *) dstdirslash=$dstdir/;; 32118eba588Smrg esac 32218eba588Smrg 323b9bb67cbSmrg obsolete_mkdir_used=false 324b9bb67cbSmrg 325b9bb67cbSmrg if test $dstdir_status != 0; then 326b9bb67cbSmrg case $posix_mkdir in 327b9bb67cbSmrg '') 32818eba588Smrg # With -d, create the new directory with the user-specified mode. 32918eba588Smrg # Otherwise, rely on $mkdir_umask. 33018eba588Smrg if test -n "$dir_arg"; then 33118eba588Smrg mkdir_mode=-m$mode 33218eba588Smrg else 33318eba588Smrg mkdir_mode= 33418eba588Smrg fi 33518eba588Smrg 33618eba588Smrg posix_mkdir=false 33718eba588Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 33818eba588Smrg # here however when possible just to lower collision chance. 33918eba588Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34018eba588Smrg 34118eba588Smrg trap ' 34218eba588Smrg ret=$? 34318eba588Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 34418eba588Smrg exit $ret 34518eba588Smrg ' 0 34618eba588Smrg 34718eba588Smrg # Because "mkdir -p" follows existing symlinks and we likely work 34818eba588Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 34918eba588Smrg # directory is successfully created first before we actually test 35018eba588Smrg # 'mkdir -p'. 35118eba588Smrg if (umask $mkdir_umask && 35218eba588Smrg $mkdirprog $mkdir_mode "$tmpdir" && 35318eba588Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 35418eba588Smrg then 35518eba588Smrg if test -z "$dir_arg" || { 35618eba588Smrg # Check for POSIX incompatibilities with -m. 35718eba588Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35818eba588Smrg # other-writable bit of parent directory when it shouldn't. 35918eba588Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 36018eba588Smrg test_tmpdir="$tmpdir/a" 36118eba588Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 36218eba588Smrg case $ls_ld_tmpdir in 36318eba588Smrg d????-?r-*) different_mode=700;; 36418eba588Smrg d????-?--*) different_mode=755;; 36518eba588Smrg *) false;; 36618eba588Smrg esac && 36718eba588Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 36818eba588Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36918eba588Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 37018eba588Smrg } 37118eba588Smrg } 37218eba588Smrg then posix_mkdir=: 37318eba588Smrg fi 37418eba588Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3751cc8c64fSmrg else 37618eba588Smrg # Remove any dirs left behind by ancient mkdir implementations. 37718eba588Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3781cc8c64fSmrg fi 37918eba588Smrg trap '' 0;; 380b9bb67cbSmrg esac 3811cc8c64fSmrg 382b9bb67cbSmrg if 383b9bb67cbSmrg $posix_mkdir && ( 38418eba588Smrg umask $mkdir_umask && 38518eba588Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386b9bb67cbSmrg ) 387b9bb67cbSmrg then : 388b9bb67cbSmrg else 389b9bb67cbSmrg 39018eba588Smrg # mkdir does not conform to POSIX, 391b9bb67cbSmrg # or it failed possibly due to a race condition. Create the 392b9bb67cbSmrg # directory the slow way, step by step, checking for races as we go. 393b9bb67cbSmrg 394b9bb67cbSmrg case $dstdir in 39518eba588Smrg /*) prefix='/';; 39618eba588Smrg [-=\(\)!]*) prefix='./';; 39718eba588Smrg *) prefix='';; 398b9bb67cbSmrg esac 399b9bb67cbSmrg 400b9bb67cbSmrg oIFS=$IFS 401b9bb67cbSmrg IFS=/ 40218eba588Smrg set -f 403b9bb67cbSmrg set fnord $dstdir 404b9bb67cbSmrg shift 40518eba588Smrg set +f 406b9bb67cbSmrg IFS=$oIFS 407b9bb67cbSmrg 408b9bb67cbSmrg prefixes= 409b9bb67cbSmrg 410b9bb67cbSmrg for d 411b9bb67cbSmrg do 41218eba588Smrg test X"$d" = X && continue 41318eba588Smrg 41418eba588Smrg prefix=$prefix$d 41518eba588Smrg if test -d "$prefix"; then 41618eba588Smrg prefixes= 41718eba588Smrg else 41818eba588Smrg if $posix_mkdir; then 41918eba588Smrg (umask $mkdir_umask && 42018eba588Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42118eba588Smrg # Don't fail if two instances are running concurrently. 42218eba588Smrg test -d "$prefix" || exit 1 42318eba588Smrg else 42418eba588Smrg case $prefix in 42518eba588Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42618eba588Smrg *) qprefix=$prefix;; 42718eba588Smrg esac 42818eba588Smrg prefixes="$prefixes '$qprefix'" 42918eba588Smrg fi 43018eba588Smrg fi 43118eba588Smrg prefix=$prefix/ 432b9bb67cbSmrg done 433b9bb67cbSmrg 434b9bb67cbSmrg if test -n "$prefixes"; then 43518eba588Smrg # Don't fail if two instances are running concurrently. 43618eba588Smrg (umask $mkdir_umask && 43718eba588Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 43818eba588Smrg test -d "$dstdir" || exit 1 43918eba588Smrg obsolete_mkdir_used=true 440b9bb67cbSmrg fi 441b9bb67cbSmrg fi 442b9bb67cbSmrg fi 443b9bb67cbSmrg 444b9bb67cbSmrg if test -n "$dir_arg"; then 445b9bb67cbSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446b9bb67cbSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447b9bb67cbSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448b9bb67cbSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449b9bb67cbSmrg else 450b9bb67cbSmrg 451b9bb67cbSmrg # Make a couple of temp file names in the proper directory. 45218eba588Smrg dsttmp=${dstdirslash}_inst.$$_ 45318eba588Smrg rmtmp=${dstdirslash}_rm.$$_ 454b9bb67cbSmrg 455b9bb67cbSmrg # Trap to clean up those temp files at exit. 456b9bb67cbSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457b9bb67cbSmrg 458b9bb67cbSmrg # Copy the file name to the temp name. 45918eba588Smrg (umask $cp_umask && 46018eba588Smrg { test -z "$stripcmd" || { 46118eba588Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 46218eba588Smrg # which would cause strip to fail. 46318eba588Smrg if test -z "$doit"; then 46418eba588Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 46518eba588Smrg else 46618eba588Smrg $doit touch "$dsttmp" 46718eba588Smrg fi 46818eba588Smrg } 46918eba588Smrg } && 47018eba588Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471b9bb67cbSmrg 472b9bb67cbSmrg # and set any options; do chmod last to preserve setuid bits. 473b9bb67cbSmrg # 474b9bb67cbSmrg # If any of these fail, we abort the whole thing. If we want to 475b9bb67cbSmrg # ignore errors from any of these, just make sure not to ignore 476b9bb67cbSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477b9bb67cbSmrg # 478b9bb67cbSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479b9bb67cbSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480b9bb67cbSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481b9bb67cbSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482b9bb67cbSmrg 483b9bb67cbSmrg # If -C, don't bother to copy if it wouldn't change the file. 484b9bb67cbSmrg if $copy_on_change && 48518eba588Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48618eba588Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48718eba588Smrg set -f && 488b9bb67cbSmrg set X $old && old=:$2:$4:$5:$6 && 489b9bb67cbSmrg set X $new && new=:$2:$4:$5:$6 && 49018eba588Smrg set +f && 491b9bb67cbSmrg test "$old" = "$new" && 492b9bb67cbSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493b9bb67cbSmrg then 494b9bb67cbSmrg rm -f "$dsttmp" 495b9bb67cbSmrg else 49618eba588Smrg # If $backupsuffix is set, and the file being installed 49718eba588Smrg # already exists, attempt a backup. Don't worry if it fails, 49818eba588Smrg # e.g., if mv doesn't support -f. 49918eba588Smrg if test -n "$backupsuffix" && test -f "$dst"; then 50018eba588Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 50118eba588Smrg fi 50218eba588Smrg 503b9bb67cbSmrg # Rename the file to the real destination. 504b9bb67cbSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505b9bb67cbSmrg 506b9bb67cbSmrg # The rename failed, perhaps because mv can't rename something else 507b9bb67cbSmrg # to itself, or perhaps because mv is so ancient that it does not 508b9bb67cbSmrg # support -f. 509b9bb67cbSmrg { 51018eba588Smrg # Now remove or move aside any old file at destination location. 51118eba588Smrg # We try this two ways since rm can't unlink itself on some 51218eba588Smrg # systems and the destination file might be busy for other 51318eba588Smrg # reasons. In this case, the final cleanup might fail but the new 51418eba588Smrg # file should still install successfully. 51518eba588Smrg { 51618eba588Smrg test ! -f "$dst" || 51718eba588Smrg $doit $rmcmd "$dst" 2>/dev/null || 51818eba588Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 51918eba588Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52018eba588Smrg } || 52118eba588Smrg { echo "$0: cannot unlink or rename $dst" >&2 52218eba588Smrg (exit 1); exit 1 52318eba588Smrg } 52418eba588Smrg } && 52518eba588Smrg 52618eba588Smrg # Now rename the file to the real destination. 52718eba588Smrg $doit $mvcmd "$dsttmp" "$dst" 528b9bb67cbSmrg } 529b9bb67cbSmrg fi || exit 1 530b9bb67cbSmrg 531b9bb67cbSmrg trap '' 0 532b9bb67cbSmrg fi 533b9bb67cbSmrgdone 5341cc8c64fSmrg 535b9bb67cbSmrg# Local variables: 53618eba588Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537b9bb67cbSmrg# time-stamp-start: "scriptversion=" 538b9bb67cbSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 53918eba588Smrg# time-stamp-time-zone: "UTC0" 540b9bb67cbSmrg# time-stamp-end: "; # UTC" 541b9bb67cbSmrg# End: 542