1fc89c0fbSmrg#!/bin/sh 2fc89c0fbSmrg# install - install a program, script, or datafile 3fc89c0fbSmrg 4c8df0c59Smrgscriptversion=2024-06-19.01; # UTC 5fc89c0fbSmrg 6fc89c0fbSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7fc89c0fbSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8fc89c0fbSmrg# following copyright and license. 9fc89c0fbSmrg# 10fc89c0fbSmrg# Copyright (C) 1994 X Consortium 11fc89c0fbSmrg# 12fc89c0fbSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13fc89c0fbSmrg# of this software and associated documentation files (the "Software"), to 14fc89c0fbSmrg# deal in the Software without restriction, including without limitation the 15fc89c0fbSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16fc89c0fbSmrg# sell copies of the Software, and to permit persons to whom the Software is 17fc89c0fbSmrg# furnished to do so, subject to the following conditions: 18fc89c0fbSmrg# 19fc89c0fbSmrg# The above copyright notice and this permission notice shall be included in 20fc89c0fbSmrg# all copies or substantial portions of the Software. 21fc89c0fbSmrg# 22fc89c0fbSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23fc89c0fbSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24fc89c0fbSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25fc89c0fbSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26fc89c0fbSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27fc89c0fbSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28fc89c0fbSmrg# 29fc89c0fbSmrg# Except as contained in this notice, the name of the X Consortium shall not 30fc89c0fbSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31fc89c0fbSmrg# ings in this Software without prior written authorization from the X Consor- 32fc89c0fbSmrg# tium. 33fc89c0fbSmrg# 34fc89c0fbSmrg# 35fc89c0fbSmrg# FSF changes to this file are in the public domain. 36fc89c0fbSmrg# 37fc89c0fbSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38576bbdfcSmrg# 'make' implicit rules from creating a file called install from it 39fc89c0fbSmrg# when there is no Makefile. 40fc89c0fbSmrg# 41fc89c0fbSmrg# This script is compatible with the BSD install script, but was written 42fc89c0fbSmrg# from scratch. 43fc89c0fbSmrg 4481676fe2Smrgtab=' ' 45fc89c0fbSmrgnl=' 46fc89c0fbSmrg' 4781676fe2SmrgIFS=" $tab$nl" 48fc89c0fbSmrg 4981676fe2Smrg# Set DOITPROG to "echo" to test this script. 50fc89c0fbSmrg 5191ec45ceSmrgdoit=${DOITPROG-} 5281676fe2Smrgdoit_exec=${doit:-exec} 53fc89c0fbSmrg 54fc89c0fbSmrg# Put in absolute file names if you don't have them in your path; 55fc89c0fbSmrg# or use environment vars. 56fc89c0fbSmrg 5791ec45ceSmrgchgrpprog=${CHGRPPROG-chgrp} 5891ec45ceSmrgchmodprog=${CHMODPROG-chmod} 5991ec45ceSmrgchownprog=${CHOWNPROG-chown} 6091ec45ceSmrgcmpprog=${CMPPROG-cmp} 6191ec45ceSmrgcpprog=${CPPROG-cp} 6291ec45ceSmrgmkdirprog=${MKDIRPROG-mkdir} 6391ec45ceSmrgmvprog=${MVPROG-mv} 6491ec45ceSmrgrmprog=${RMPROG-rm} 6591ec45ceSmrgstripprog=${STRIPPROG-strip} 6691ec45ceSmrg 67fc89c0fbSmrgposix_mkdir= 68fc89c0fbSmrg 69fc89c0fbSmrg# Desired mode of installed file. 70fc89c0fbSmrgmode=0755 71fc89c0fbSmrg 7249bee38cSmrg# Create dirs (including intermediate dirs) using mode 755. 7349bee38cSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 7449bee38cSmrgmkdir_umask=22 7549bee38cSmrg 7649bee38cSmrgbackupsuffix= 7791ec45ceSmrgchgrpcmd= 78fc89c0fbSmrgchmodcmd=$chmodprog 79fc89c0fbSmrgchowncmd= 8091ec45ceSmrgmvcmd=$mvprog 81fc89c0fbSmrgrmcmd="$rmprog -f" 8291ec45ceSmrgstripcmd= 8391ec45ceSmrg 84fc89c0fbSmrgsrc= 85fc89c0fbSmrgdst= 86fc89c0fbSmrgdir_arg= 8791ec45ceSmrgdst_arg= 8891ec45ceSmrg 8991ec45ceSmrgcopy_on_change=false 9081676fe2Smrgis_target_a_directory=possibly 91fc89c0fbSmrg 9291ec45ceSmrgusage="\ 9391ec45ceSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94fc89c0fbSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95fc89c0fbSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96fc89c0fbSmrg or: $0 [OPTION]... -d DIRECTORIES... 97fc89c0fbSmrg 98fc89c0fbSmrgIn the 1st form, copy SRCFILE to DSTFILE. 99fc89c0fbSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100fc89c0fbSmrgIn the 4th, create DIRECTORIES. 101fc89c0fbSmrg 102fc89c0fbSmrgOptions: 10391ec45ceSmrg --help display this help and exit. 10491ec45ceSmrg --version display version info and exit. 10591ec45ceSmrg 10691ec45ceSmrg -c (ignored) 10749bee38cSmrg -C install only if different (preserve data modification time) 10891ec45ceSmrg -d create directories instead of installing files. 10991ec45ceSmrg -g GROUP $chgrpprog installed files to GROUP. 11091ec45ceSmrg -m MODE $chmodprog installed files to MODE. 11191ec45ceSmrg -o USER $chownprog installed files to USER. 11249bee38cSmrg -p pass -p to $cpprog. 11391ec45ceSmrg -s $stripprog installed files. 11449bee38cSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 11591ec45ceSmrg -t DIRECTORY install into DIRECTORY. 11691ec45ceSmrg -T report an error if DSTFILE is a directory. 117fc89c0fbSmrg 118fc89c0fbSmrgEnvironment variables override the default commands: 11991ec45ceSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 12091ec45ceSmrg RMPROG STRIPPROG 12149bee38cSmrg 12249bee38cSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 12349bee38cSmrgit's up to you to specify -f if you want it. 12449bee38cSmrg 12549bee38cSmrgIf -S is not specified, no backups are attempted. 12649bee38cSmrg 127c8df0c59SmrgReport bugs to <bug-automake@gnu.org>. 128c8df0c59SmrgGNU Automake home page: <https://www.gnu.org/software/automake/>. 129c8df0c59SmrgGeneral help using GNU software: <https://www.gnu.org/gethelp/>." 130fc89c0fbSmrg 131fc89c0fbSmrgwhile test $# -ne 0; do 132fc89c0fbSmrg case $1 in 13391ec45ceSmrg -c) ;; 13491ec45ceSmrg 13591ec45ceSmrg -C) copy_on_change=true;; 136fc89c0fbSmrg 13791ec45ceSmrg -d) dir_arg=true;; 138fc89c0fbSmrg 139fc89c0fbSmrg -g) chgrpcmd="$chgrpprog $2" 14081676fe2Smrg shift;; 141fc89c0fbSmrg 142fc89c0fbSmrg --help) echo "$usage"; exit $?;; 143fc89c0fbSmrg 144fc89c0fbSmrg -m) mode=$2 14581676fe2Smrg case $mode in 14681676fe2Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14781676fe2Smrg echo "$0: invalid mode: $mode" >&2 14881676fe2Smrg exit 1;; 14981676fe2Smrg esac 15081676fe2Smrg shift;; 151fc89c0fbSmrg 152fc89c0fbSmrg -o) chowncmd="$chownprog $2" 15381676fe2Smrg shift;; 154fc89c0fbSmrg 15549bee38cSmrg -p) cpprog="$cpprog -p";; 15649bee38cSmrg 15791ec45ceSmrg -s) stripcmd=$stripprog;; 158fc89c0fbSmrg 15949bee38cSmrg -S) backupsuffix="$2" 16049bee38cSmrg shift;; 16149bee38cSmrg 16281676fe2Smrg -t) 16381676fe2Smrg is_target_a_directory=always 16481676fe2Smrg dst_arg=$2 16581676fe2Smrg # Protect names problematic for 'test' and other utilities. 16681676fe2Smrg case $dst_arg in 16781676fe2Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16881676fe2Smrg esac 16981676fe2Smrg shift;; 170fc89c0fbSmrg 17181676fe2Smrg -T) is_target_a_directory=never;; 172fc89c0fbSmrg 173c8df0c59Smrg --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;; 174fc89c0fbSmrg 17581676fe2Smrg --) shift 17681676fe2Smrg break;; 177fc89c0fbSmrg 17881676fe2Smrg -*) echo "$0: invalid option: $1" >&2 17981676fe2Smrg exit 1;; 180fc89c0fbSmrg 181fc89c0fbSmrg *) break;; 182fc89c0fbSmrg esac 18391ec45ceSmrg shift 184fc89c0fbSmrgdone 185fc89c0fbSmrg 18681676fe2Smrg# We allow the use of options -d and -T together, by making -d 18781676fe2Smrg# take the precedence; this is for compatibility with GNU install. 18881676fe2Smrg 18981676fe2Smrgif test -n "$dir_arg"; then 19081676fe2Smrg if test -n "$dst_arg"; then 19181676fe2Smrg echo "$0: target directory not allowed when installing a directory." >&2 19281676fe2Smrg exit 1 19381676fe2Smrg fi 19481676fe2Smrgfi 19581676fe2Smrg 19691ec45ceSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197fc89c0fbSmrg # When -d is used, all remaining arguments are directories to create. 198fc89c0fbSmrg # When -t is used, the destination is already specified. 199fc89c0fbSmrg # Otherwise, the last argument is the destination. Remove it from $@. 200fc89c0fbSmrg for arg 201fc89c0fbSmrg do 20291ec45ceSmrg if test -n "$dst_arg"; then 203fc89c0fbSmrg # $@ is not empty: it contains at least $arg. 20491ec45ceSmrg set fnord "$@" "$dst_arg" 205fc89c0fbSmrg shift # fnord 206fc89c0fbSmrg fi 207fc89c0fbSmrg shift # arg 20891ec45ceSmrg dst_arg=$arg 209576bbdfcSmrg # Protect names problematic for 'test' and other utilities. 210576bbdfcSmrg case $dst_arg in 211576bbdfcSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212576bbdfcSmrg esac 213fc89c0fbSmrg done 214fc89c0fbSmrgfi 215fc89c0fbSmrg 216fc89c0fbSmrgif test $# -eq 0; then 217fc89c0fbSmrg if test -z "$dir_arg"; then 218fc89c0fbSmrg echo "$0: no input file specified." >&2 219fc89c0fbSmrg exit 1 220fc89c0fbSmrg fi 221576bbdfcSmrg # It's OK to call 'install-sh -d' without argument. 222fc89c0fbSmrg # This can happen when creating conditional directories. 223fc89c0fbSmrg exit 0 224fc89c0fbSmrgfi 225fc89c0fbSmrg 22681676fe2Smrgif test -z "$dir_arg"; then 22781676fe2Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22881676fe2Smrg if test ! -d "$dst_arg"; then 22981676fe2Smrg echo "$0: $dst_arg: Is not a directory." >&2 23081676fe2Smrg exit 1 23181676fe2Smrg fi 23281676fe2Smrg fi 23381676fe2Smrgfi 23481676fe2Smrg 235fc89c0fbSmrgif test -z "$dir_arg"; then 236576bbdfcSmrg do_exit='(exit $ret); exit $ret' 237576bbdfcSmrg trap "ret=129; $do_exit" 1 238576bbdfcSmrg trap "ret=130; $do_exit" 2 239576bbdfcSmrg trap "ret=141; $do_exit" 13 240576bbdfcSmrg trap "ret=143; $do_exit" 15 241fc89c0fbSmrg 242fc89c0fbSmrg # Set umask so as not to create temps with too-generous modes. 243fc89c0fbSmrg # However, 'strip' requires both read and write access to temps. 244fc89c0fbSmrg case $mode in 245fc89c0fbSmrg # Optimize common cases. 246fc89c0fbSmrg *644) cp_umask=133;; 247fc89c0fbSmrg *755) cp_umask=22;; 248fc89c0fbSmrg 249fc89c0fbSmrg *[0-7]) 250fc89c0fbSmrg if test -z "$stripcmd"; then 25181676fe2Smrg u_plus_rw= 252fc89c0fbSmrg else 25381676fe2Smrg u_plus_rw='% 200' 254fc89c0fbSmrg fi 255fc89c0fbSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256fc89c0fbSmrg *) 257fc89c0fbSmrg if test -z "$stripcmd"; then 25881676fe2Smrg u_plus_rw= 259fc89c0fbSmrg else 26081676fe2Smrg u_plus_rw=,u+rw 261fc89c0fbSmrg fi 262fc89c0fbSmrg cp_umask=$mode$u_plus_rw;; 263fc89c0fbSmrg esac 264fc89c0fbSmrgfi 265fc89c0fbSmrg 266fc89c0fbSmrgfor src 267fc89c0fbSmrgdo 268576bbdfcSmrg # Protect names problematic for 'test' and other utilities. 269fc89c0fbSmrg case $src in 270576bbdfcSmrg -* | [=\(\)!]) src=./$src;; 271fc89c0fbSmrg esac 272fc89c0fbSmrg 273fc89c0fbSmrg if test -n "$dir_arg"; then 274fc89c0fbSmrg dst=$src 275fc89c0fbSmrg dstdir=$dst 276fc89c0fbSmrg test -d "$dstdir" 277fc89c0fbSmrg dstdir_status=$? 27849bee38cSmrg # Don't chown directories that already exist. 27949bee38cSmrg if test $dstdir_status = 0; then 28049bee38cSmrg chowncmd="" 28149bee38cSmrg fi 282fc89c0fbSmrg else 283fc89c0fbSmrg 284fc89c0fbSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285fc89c0fbSmrg # might cause directories to be created, which would be especially bad 286fc89c0fbSmrg # if $src (and thus $dsttmp) contains '*'. 287fc89c0fbSmrg if test ! -f "$src" && test ! -d "$src"; then 288fc89c0fbSmrg echo "$0: $src does not exist." >&2 289fc89c0fbSmrg exit 1 290fc89c0fbSmrg fi 291fc89c0fbSmrg 29291ec45ceSmrg if test -z "$dst_arg"; then 293fc89c0fbSmrg echo "$0: no destination specified." >&2 294fc89c0fbSmrg exit 1 295fc89c0fbSmrg fi 29691ec45ceSmrg dst=$dst_arg 297fc89c0fbSmrg 298f9c28e31Smrg # If destination is a directory, append the input filename. 299fc89c0fbSmrg if test -d "$dst"; then 30081676fe2Smrg if test "$is_target_a_directory" = never; then 30181676fe2Smrg echo "$0: $dst_arg: Is a directory" >&2 30281676fe2Smrg exit 1 303fc89c0fbSmrg fi 304fc89c0fbSmrg dstdir=$dst 305f9c28e31Smrg dstbase=`basename "$src"` 306f9c28e31Smrg case $dst in 307f9c28e31Smrg */) dst=$dst$dstbase;; 308f9c28e31Smrg *) dst=$dst/$dstbase;; 309f9c28e31Smrg esac 310fc89c0fbSmrg dstdir_status=0 311fc89c0fbSmrg else 31281676fe2Smrg dstdir=`dirname "$dst"` 313fc89c0fbSmrg test -d "$dstdir" 314fc89c0fbSmrg dstdir_status=$? 315fc89c0fbSmrg fi 316fc89c0fbSmrg fi 317fc89c0fbSmrg 318f9c28e31Smrg case $dstdir in 319f9c28e31Smrg */) dstdirslash=$dstdir;; 320f9c28e31Smrg *) dstdirslash=$dstdir/;; 321f9c28e31Smrg esac 322f9c28e31Smrg 323fc89c0fbSmrg obsolete_mkdir_used=false 324fc89c0fbSmrg 325fc89c0fbSmrg if test $dstdir_status != 0; then 326fc89c0fbSmrg case $posix_mkdir in 327fc89c0fbSmrg '') 32881676fe2Smrg # With -d, create the new directory with the user-specified mode. 32981676fe2Smrg # Otherwise, rely on $mkdir_umask. 33081676fe2Smrg if test -n "$dir_arg"; then 33181676fe2Smrg mkdir_mode=-m$mode 33281676fe2Smrg else 33381676fe2Smrg mkdir_mode= 33481676fe2Smrg fi 33581676fe2Smrg 33681676fe2Smrg posix_mkdir=false 33749bee38cSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 33849bee38cSmrg # here however when possible just to lower collision chance. 33949bee38cSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34049bee38cSmrg 34149bee38cSmrg trap ' 34249bee38cSmrg ret=$? 34349bee38cSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 34449bee38cSmrg exit $ret 34549bee38cSmrg ' 0 34649bee38cSmrg 34749bee38cSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348c8df0c59Smrg # directly in world-writable /tmp, make sure that the '$tmpdir' 34949bee38cSmrg # directory is successfully created first before we actually test 35049bee38cSmrg # 'mkdir -p'. 35149bee38cSmrg if (umask $mkdir_umask && 35249bee38cSmrg $mkdirprog $mkdir_mode "$tmpdir" && 35349bee38cSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 35449bee38cSmrg then 35549bee38cSmrg if test -z "$dir_arg" || { 356c8df0c59Smrg # Check for POSIX incompatibility with -m. 35749bee38cSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35849bee38cSmrg # other-writable bit of parent directory when it shouldn't. 35949bee38cSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 36049bee38cSmrg test_tmpdir="$tmpdir/a" 36149bee38cSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 36249bee38cSmrg case $ls_ld_tmpdir in 36349bee38cSmrg d????-?r-*) different_mode=700;; 36449bee38cSmrg d????-?--*) different_mode=755;; 36549bee38cSmrg *) false;; 36649bee38cSmrg esac && 36749bee38cSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 36849bee38cSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36949bee38cSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 37049bee38cSmrg } 37149bee38cSmrg } 37249bee38cSmrg then posix_mkdir=: 37349bee38cSmrg fi 37449bee38cSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 37549bee38cSmrg else 37649bee38cSmrg # Remove any dirs left behind by ancient mkdir implementations. 37749bee38cSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 37849bee38cSmrg fi 37949bee38cSmrg trap '' 0;; 380fc89c0fbSmrg esac 381fc89c0fbSmrg 382fc89c0fbSmrg if 383fc89c0fbSmrg $posix_mkdir && ( 38481676fe2Smrg umask $mkdir_umask && 38581676fe2Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386fc89c0fbSmrg ) 387fc89c0fbSmrg then : 388fc89c0fbSmrg else 389fc89c0fbSmrg 39049bee38cSmrg # mkdir does not conform to POSIX, 391fc89c0fbSmrg # or it failed possibly due to a race condition. Create the 392fc89c0fbSmrg # directory the slow way, step by step, checking for races as we go. 393fc89c0fbSmrg 394fc89c0fbSmrg case $dstdir in 39581676fe2Smrg /*) prefix='/';; 39681676fe2Smrg [-=\(\)!]*) prefix='./';; 39781676fe2Smrg *) prefix='';; 398fc89c0fbSmrg esac 399fc89c0fbSmrg 400fc89c0fbSmrg oIFS=$IFS 401fc89c0fbSmrg IFS=/ 40281676fe2Smrg set -f 403fc89c0fbSmrg set fnord $dstdir 404fc89c0fbSmrg shift 40581676fe2Smrg set +f 406fc89c0fbSmrg IFS=$oIFS 407fc89c0fbSmrg 408fc89c0fbSmrg prefixes= 409fc89c0fbSmrg 410fc89c0fbSmrg for d 411fc89c0fbSmrg do 41281676fe2Smrg test X"$d" = X && continue 41381676fe2Smrg 41481676fe2Smrg prefix=$prefix$d 41581676fe2Smrg if test -d "$prefix"; then 41681676fe2Smrg prefixes= 41781676fe2Smrg else 41881676fe2Smrg if $posix_mkdir; then 41949bee38cSmrg (umask $mkdir_umask && 42081676fe2Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42181676fe2Smrg # Don't fail if two instances are running concurrently. 42281676fe2Smrg test -d "$prefix" || exit 1 42381676fe2Smrg else 42481676fe2Smrg case $prefix in 42581676fe2Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42681676fe2Smrg *) qprefix=$prefix;; 42781676fe2Smrg esac 42881676fe2Smrg prefixes="$prefixes '$qprefix'" 42981676fe2Smrg fi 43081676fe2Smrg fi 43181676fe2Smrg prefix=$prefix/ 432fc89c0fbSmrg done 433fc89c0fbSmrg 434fc89c0fbSmrg if test -n "$prefixes"; then 43581676fe2Smrg # Don't fail if two instances are running concurrently. 43681676fe2Smrg (umask $mkdir_umask && 43781676fe2Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 43881676fe2Smrg test -d "$dstdir" || exit 1 43981676fe2Smrg obsolete_mkdir_used=true 440fc89c0fbSmrg fi 441fc89c0fbSmrg fi 442fc89c0fbSmrg fi 443fc89c0fbSmrg 444fc89c0fbSmrg if test -n "$dir_arg"; then 445fc89c0fbSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446fc89c0fbSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447fc89c0fbSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448fc89c0fbSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449fc89c0fbSmrg else 450fc89c0fbSmrg 451fc89c0fbSmrg # Make a couple of temp file names in the proper directory. 452f9c28e31Smrg dsttmp=${dstdirslash}_inst.$$_ 453f9c28e31Smrg rmtmp=${dstdirslash}_rm.$$_ 454fc89c0fbSmrg 455fc89c0fbSmrg # Trap to clean up those temp files at exit. 456fc89c0fbSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457fc89c0fbSmrg 458fc89c0fbSmrg # Copy the file name to the temp name. 459f9c28e31Smrg (umask $cp_umask && 460f9c28e31Smrg { test -z "$stripcmd" || { 461f9c28e31Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462f9c28e31Smrg # which would cause strip to fail. 463f9c28e31Smrg if test -z "$doit"; then 464f9c28e31Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 465f9c28e31Smrg else 466f9c28e31Smrg $doit touch "$dsttmp" 467f9c28e31Smrg fi 468f9c28e31Smrg } 469f9c28e31Smrg } && 470f9c28e31Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471fc89c0fbSmrg 472fc89c0fbSmrg # and set any options; do chmod last to preserve setuid bits. 473fc89c0fbSmrg # 474fc89c0fbSmrg # If any of these fail, we abort the whole thing. If we want to 475fc89c0fbSmrg # ignore errors from any of these, just make sure not to ignore 476fc89c0fbSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477fc89c0fbSmrg # 47891ec45ceSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 47991ec45ceSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 48091ec45ceSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 48191ec45ceSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 48291ec45ceSmrg 48391ec45ceSmrg # If -C, don't bother to copy if it wouldn't change the file. 48491ec45ceSmrg if $copy_on_change && 48581676fe2Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48681676fe2Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48781676fe2Smrg set -f && 48891ec45ceSmrg set X $old && old=:$2:$4:$5:$6 && 48991ec45ceSmrg set X $new && new=:$2:$4:$5:$6 && 49081676fe2Smrg set +f && 49191ec45ceSmrg test "$old" = "$new" && 49291ec45ceSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 49391ec45ceSmrg then 49491ec45ceSmrg rm -f "$dsttmp" 49591ec45ceSmrg else 49649bee38cSmrg # If $backupsuffix is set, and the file being installed 49749bee38cSmrg # already exists, attempt a backup. Don't worry if it fails, 49849bee38cSmrg # e.g., if mv doesn't support -f. 49949bee38cSmrg if test -n "$backupsuffix" && test -f "$dst"; then 50049bee38cSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 50149bee38cSmrg fi 50249bee38cSmrg 50391ec45ceSmrg # Rename the file to the real destination. 50491ec45ceSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 50591ec45ceSmrg 50691ec45ceSmrg # The rename failed, perhaps because mv can't rename something else 50791ec45ceSmrg # to itself, or perhaps because mv is so ancient that it does not 50891ec45ceSmrg # support -f. 50991ec45ceSmrg { 51081676fe2Smrg # Now remove or move aside any old file at destination location. 51181676fe2Smrg # We try this two ways since rm can't unlink itself on some 51281676fe2Smrg # systems and the destination file might be busy for other 51381676fe2Smrg # reasons. In this case, the final cleanup might fail but the new 51481676fe2Smrg # file should still install successfully. 51581676fe2Smrg { 51681676fe2Smrg test ! -f "$dst" || 51749bee38cSmrg $doit $rmcmd "$dst" 2>/dev/null || 51881676fe2Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 51949bee38cSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52081676fe2Smrg } || 52181676fe2Smrg { echo "$0: cannot unlink or rename $dst" >&2 52281676fe2Smrg (exit 1); exit 1 52381676fe2Smrg } 52481676fe2Smrg } && 52581676fe2Smrg 52681676fe2Smrg # Now rename the file to the real destination. 52781676fe2Smrg $doit $mvcmd "$dsttmp" "$dst" 52891ec45ceSmrg } 52991ec45ceSmrg fi || exit 1 530fc89c0fbSmrg 531fc89c0fbSmrg trap '' 0 532fc89c0fbSmrg fi 533fc89c0fbSmrgdone 534fc89c0fbSmrg 535fc89c0fbSmrg# Local variables: 536f9c28e31Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537fc89c0fbSmrg# time-stamp-start: "scriptversion=" 538fc89c0fbSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539f9c28e31Smrg# time-stamp-time-zone: "UTC0" 54091ec45ceSmrg# time-stamp-end: "; # UTC" 541fc89c0fbSmrg# End: 542