install-sh revision b8df70be
111d341caSmrg#!/bin/sh 211d341caSmrg# install - install a program, script, or datafile 311d341caSmrg 4b8df70beSmrgscriptversion=2020-11-14.01; # UTC 511d341caSmrg 611d341caSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 711d341caSmrg# later released in X11R6 (xc/config/util/install.sh) with the 811d341caSmrg# following copyright and license. 911d341caSmrg# 1011d341caSmrg# Copyright (C) 1994 X Consortium 1111d341caSmrg# 1211d341caSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1311d341caSmrg# of this software and associated documentation files (the "Software"), to 1411d341caSmrg# deal in the Software without restriction, including without limitation the 1511d341caSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1611d341caSmrg# sell copies of the Software, and to permit persons to whom the Software is 1711d341caSmrg# furnished to do so, subject to the following conditions: 1811d341caSmrg# 1911d341caSmrg# The above copyright notice and this permission notice shall be included in 2011d341caSmrg# all copies or substantial portions of the Software. 2111d341caSmrg# 2211d341caSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2311d341caSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2411d341caSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2511d341caSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2611d341caSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2711d341caSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2811d341caSmrg# 2911d341caSmrg# Except as contained in this notice, the name of the X Consortium shall not 3011d341caSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 3111d341caSmrg# ings in this Software without prior written authorization from the X Consor- 3211d341caSmrg# tium. 3311d341caSmrg# 3411d341caSmrg# 3511d341caSmrg# FSF changes to this file are in the public domain. 3611d341caSmrg# 3711d341caSmrg# Calling this script install-sh is preferred over install.sh, to prevent 381c80d5b0Smrg# 'make' implicit rules from creating a file called install from it 3911d341caSmrg# when there is no Makefile. 4011d341caSmrg# 4111d341caSmrg# This script is compatible with the BSD install script, but was written 424c61c93dSmrg# from scratch. 434c61c93dSmrg 4441fe0c2aSmrgtab=' ' 454c61c93dSmrgnl=' 464c61c93dSmrg' 4741fe0c2aSmrgIFS=" $tab$nl" 4811d341caSmrg 4941fe0c2aSmrg# Set DOITPROG to "echo" to test this script. 5011d341caSmrg 514c61c93dSmrgdoit=${DOITPROG-} 5241fe0c2aSmrgdoit_exec=${doit:-exec} 5311d341caSmrg 544c61c93dSmrg# Put in absolute file names if you don't have them in your path; 554c61c93dSmrg# or use environment vars. 564c61c93dSmrg 574c61c93dSmrgchgrpprog=${CHGRPPROG-chgrp} 584c61c93dSmrgchmodprog=${CHMODPROG-chmod} 594c61c93dSmrgchownprog=${CHOWNPROG-chown} 604c61c93dSmrgcmpprog=${CMPPROG-cmp} 614c61c93dSmrgcpprog=${CPPROG-cp} 624c61c93dSmrgmkdirprog=${MKDIRPROG-mkdir} 634c61c93dSmrgmvprog=${MVPROG-mv} 644c61c93dSmrgrmprog=${RMPROG-rm} 654c61c93dSmrgstripprog=${STRIPPROG-strip} 664c61c93dSmrg 674c61c93dSmrgposix_mkdir= 684c61c93dSmrg 694c61c93dSmrg# Desired mode of installed file. 704c61c93dSmrgmode=0755 7111d341caSmrg 72b8df70beSmrg# Create dirs (including intermediate dirs) using mode 755. 73b8df70beSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74b8df70beSmrgmkdir_umask=22 75b8df70beSmrg 76b8df70beSmrgbackupsuffix= 7711d341caSmrgchgrpcmd= 784c61c93dSmrgchmodcmd=$chmodprog 794c61c93dSmrgchowncmd= 804c61c93dSmrgmvcmd=$mvprog 8111d341caSmrgrmcmd="$rmprog -f" 824c61c93dSmrgstripcmd= 834c61c93dSmrg 8411d341caSmrgsrc= 8511d341caSmrgdst= 8611d341caSmrgdir_arg= 874c61c93dSmrgdst_arg= 884c61c93dSmrg 894c61c93dSmrgcopy_on_change=false 9041fe0c2aSmrgis_target_a_directory=possibly 9111d341caSmrg 924c61c93dSmrgusage="\ 934c61c93dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 9411d341caSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 9511d341caSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9611d341caSmrg or: $0 [OPTION]... -d DIRECTORIES... 9711d341caSmrg 9811d341caSmrgIn the 1st form, copy SRCFILE to DSTFILE. 9911d341caSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 10011d341caSmrgIn the 4th, create DIRECTORIES. 10111d341caSmrg 10211d341caSmrgOptions: 1034c61c93dSmrg --help display this help and exit. 1044c61c93dSmrg --version display version info and exit. 1054c61c93dSmrg 1064c61c93dSmrg -c (ignored) 107b8df70beSmrg -C install only if different (preserve data modification time) 1084c61c93dSmrg -d create directories instead of installing files. 1094c61c93dSmrg -g GROUP $chgrpprog installed files to GROUP. 1104c61c93dSmrg -m MODE $chmodprog installed files to MODE. 1114c61c93dSmrg -o USER $chownprog installed files to USER. 112b8df70beSmrg -p pass -p to $cpprog. 1134c61c93dSmrg -s $stripprog installed files. 114b8df70beSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1154c61c93dSmrg -t DIRECTORY install into DIRECTORY. 1164c61c93dSmrg -T report an error if DSTFILE is a directory. 11711d341caSmrg 11811d341caSmrgEnvironment variables override the default commands: 1194c61c93dSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1204c61c93dSmrg RMPROG STRIPPROG 121b8df70beSmrg 122b8df70beSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123b8df70beSmrgit's up to you to specify -f if you want it. 124b8df70beSmrg 125b8df70beSmrgIf -S is not specified, no backups are attempted. 126b8df70beSmrg 127b8df70beSmrgEmail bug reports to bug-automake@gnu.org. 128b8df70beSmrgAutomake home page: https://www.gnu.org/software/automake/ 12911d341caSmrg" 13011d341caSmrg 1314c61c93dSmrgwhile test $# -ne 0; do 13211d341caSmrg case $1 in 1334c61c93dSmrg -c) ;; 1344c61c93dSmrg 1354c61c93dSmrg -C) copy_on_change=true;; 13611d341caSmrg 1374c61c93dSmrg -d) dir_arg=true;; 13811d341caSmrg 13911d341caSmrg -g) chgrpcmd="$chgrpprog $2" 14041fe0c2aSmrg shift;; 14111d341caSmrg 14211d341caSmrg --help) echo "$usage"; exit $?;; 14311d341caSmrg 1444c61c93dSmrg -m) mode=$2 14541fe0c2aSmrg case $mode in 14641fe0c2aSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14741fe0c2aSmrg echo "$0: invalid mode: $mode" >&2 14841fe0c2aSmrg exit 1;; 14941fe0c2aSmrg esac 15041fe0c2aSmrg shift;; 15111d341caSmrg 15211d341caSmrg -o) chowncmd="$chownprog $2" 15341fe0c2aSmrg shift;; 15411d341caSmrg 155b8df70beSmrg -p) cpprog="$cpprog -p";; 156b8df70beSmrg 1574c61c93dSmrg -s) stripcmd=$stripprog;; 15811d341caSmrg 159b8df70beSmrg -S) backupsuffix="$2" 160b8df70beSmrg shift;; 161b8df70beSmrg 16241fe0c2aSmrg -t) 16341fe0c2aSmrg is_target_a_directory=always 16441fe0c2aSmrg dst_arg=$2 16541fe0c2aSmrg # Protect names problematic for 'test' and other utilities. 16641fe0c2aSmrg case $dst_arg in 16741fe0c2aSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16841fe0c2aSmrg esac 16941fe0c2aSmrg shift;; 17011d341caSmrg 17141fe0c2aSmrg -T) is_target_a_directory=never;; 17211d341caSmrg 17311d341caSmrg --version) echo "$0 $scriptversion"; exit $?;; 17411d341caSmrg 17541fe0c2aSmrg --) shift 17641fe0c2aSmrg break;; 1774c61c93dSmrg 17841fe0c2aSmrg -*) echo "$0: invalid option: $1" >&2 17941fe0c2aSmrg exit 1;; 1804c61c93dSmrg 1814c61c93dSmrg *) break;; 18211d341caSmrg esac 1834c61c93dSmrg shift 18411d341caSmrgdone 18511d341caSmrg 18641fe0c2aSmrg# We allow the use of options -d and -T together, by making -d 18741fe0c2aSmrg# take the precedence; this is for compatibility with GNU install. 18841fe0c2aSmrg 18941fe0c2aSmrgif test -n "$dir_arg"; then 19041fe0c2aSmrg if test -n "$dst_arg"; then 19141fe0c2aSmrg echo "$0: target directory not allowed when installing a directory." >&2 19241fe0c2aSmrg exit 1 19341fe0c2aSmrg fi 19441fe0c2aSmrgfi 19541fe0c2aSmrg 1964c61c93dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1974c61c93dSmrg # When -d is used, all remaining arguments are directories to create. 1984c61c93dSmrg # When -t is used, the destination is already specified. 1994c61c93dSmrg # Otherwise, the last argument is the destination. Remove it from $@. 2004c61c93dSmrg for arg 2014c61c93dSmrg do 2024c61c93dSmrg if test -n "$dst_arg"; then 2034c61c93dSmrg # $@ is not empty: it contains at least $arg. 2044c61c93dSmrg set fnord "$@" "$dst_arg" 2054c61c93dSmrg shift # fnord 2064c61c93dSmrg fi 2074c61c93dSmrg shift # arg 2084c61c93dSmrg dst_arg=$arg 2091c80d5b0Smrg # Protect names problematic for 'test' and other utilities. 2101c80d5b0Smrg case $dst_arg in 2111c80d5b0Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 2121c80d5b0Smrg esac 2134c61c93dSmrg done 2144c61c93dSmrgfi 2154c61c93dSmrg 2164c61c93dSmrgif test $# -eq 0; then 21711d341caSmrg if test -z "$dir_arg"; then 21811d341caSmrg echo "$0: no input file specified." >&2 21911d341caSmrg exit 1 22011d341caSmrg fi 2211c80d5b0Smrg # It's OK to call 'install-sh -d' without argument. 22211d341caSmrg # This can happen when creating conditional directories. 22311d341caSmrg exit 0 22411d341caSmrgfi 22511d341caSmrg 22641fe0c2aSmrgif test -z "$dir_arg"; then 22741fe0c2aSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22841fe0c2aSmrg if test ! -d "$dst_arg"; then 22941fe0c2aSmrg echo "$0: $dst_arg: Is not a directory." >&2 23041fe0c2aSmrg exit 1 23141fe0c2aSmrg fi 23241fe0c2aSmrg fi 23341fe0c2aSmrgfi 23441fe0c2aSmrg 2354c61c93dSmrgif test -z "$dir_arg"; then 2361c80d5b0Smrg do_exit='(exit $ret); exit $ret' 2371c80d5b0Smrg trap "ret=129; $do_exit" 1 2381c80d5b0Smrg trap "ret=130; $do_exit" 2 2391c80d5b0Smrg trap "ret=141; $do_exit" 13 2401c80d5b0Smrg trap "ret=143; $do_exit" 15 2414c61c93dSmrg 2424c61c93dSmrg # Set umask so as not to create temps with too-generous modes. 2434c61c93dSmrg # However, 'strip' requires both read and write access to temps. 2444c61c93dSmrg case $mode in 2454c61c93dSmrg # Optimize common cases. 2464c61c93dSmrg *644) cp_umask=133;; 2474c61c93dSmrg *755) cp_umask=22;; 2484c61c93dSmrg 2494c61c93dSmrg *[0-7]) 2504c61c93dSmrg if test -z "$stripcmd"; then 25141fe0c2aSmrg u_plus_rw= 2524c61c93dSmrg else 25341fe0c2aSmrg u_plus_rw='% 200' 2544c61c93dSmrg fi 2554c61c93dSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2564c61c93dSmrg *) 2574c61c93dSmrg if test -z "$stripcmd"; then 25841fe0c2aSmrg u_plus_rw= 2594c61c93dSmrg else 26041fe0c2aSmrg u_plus_rw=,u+rw 2614c61c93dSmrg fi 2624c61c93dSmrg cp_umask=$mode$u_plus_rw;; 2634c61c93dSmrg esac 2644c61c93dSmrgfi 2654c61c93dSmrg 26611d341caSmrgfor src 26711d341caSmrgdo 2681c80d5b0Smrg # Protect names problematic for 'test' and other utilities. 26911d341caSmrg case $src in 2701c80d5b0Smrg -* | [=\(\)!]) src=./$src;; 27111d341caSmrg esac 27211d341caSmrg 27311d341caSmrg if test -n "$dir_arg"; then 27411d341caSmrg dst=$src 2754c61c93dSmrg dstdir=$dst 2764c61c93dSmrg test -d "$dstdir" 2774c61c93dSmrg dstdir_status=$? 278b8df70beSmrg # Don't chown directories that already exist. 279b8df70beSmrg if test $dstdir_status = 0; then 280b8df70beSmrg chowncmd="" 281b8df70beSmrg fi 28211d341caSmrg else 2834c61c93dSmrg 28411d341caSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 28511d341caSmrg # might cause directories to be created, which would be especially bad 28611d341caSmrg # if $src (and thus $dsttmp) contains '*'. 28711d341caSmrg if test ! -f "$src" && test ! -d "$src"; then 28811d341caSmrg echo "$0: $src does not exist." >&2 28911d341caSmrg exit 1 29011d341caSmrg fi 29111d341caSmrg 2924c61c93dSmrg if test -z "$dst_arg"; then 29311d341caSmrg echo "$0: no destination specified." >&2 29411d341caSmrg exit 1 29511d341caSmrg fi 2964c61c93dSmrg dst=$dst_arg 29711d341caSmrg 298b8df70beSmrg # If destination is a directory, append the input filename. 29911d341caSmrg if test -d "$dst"; then 30041fe0c2aSmrg if test "$is_target_a_directory" = never; then 30141fe0c2aSmrg echo "$0: $dst_arg: Is a directory" >&2 30241fe0c2aSmrg exit 1 30311d341caSmrg fi 3044c61c93dSmrg dstdir=$dst 305b8df70beSmrg dstbase=`basename "$src"` 306b8df70beSmrg case $dst in 307b8df70beSmrg */) dst=$dst$dstbase;; 308b8df70beSmrg *) dst=$dst/$dstbase;; 309b8df70beSmrg esac 3104c61c93dSmrg dstdir_status=0 3114c61c93dSmrg else 31241fe0c2aSmrg dstdir=`dirname "$dst"` 3134c61c93dSmrg test -d "$dstdir" 3144c61c93dSmrg dstdir_status=$? 31511d341caSmrg fi 31611d341caSmrg fi 31711d341caSmrg 318b8df70beSmrg case $dstdir in 319b8df70beSmrg */) dstdirslash=$dstdir;; 320b8df70beSmrg *) dstdirslash=$dstdir/;; 321b8df70beSmrg esac 322b8df70beSmrg 3234c61c93dSmrg obsolete_mkdir_used=false 3244c61c93dSmrg 3254c61c93dSmrg if test $dstdir_status != 0; then 3264c61c93dSmrg case $posix_mkdir in 3274c61c93dSmrg '') 32841fe0c2aSmrg # With -d, create the new directory with the user-specified mode. 32941fe0c2aSmrg # Otherwise, rely on $mkdir_umask. 33041fe0c2aSmrg if test -n "$dir_arg"; then 33141fe0c2aSmrg mkdir_mode=-m$mode 33241fe0c2aSmrg else 33341fe0c2aSmrg mkdir_mode= 33441fe0c2aSmrg fi 33541fe0c2aSmrg 33641fe0c2aSmrg posix_mkdir=false 337b8df70beSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 338b8df70beSmrg # here however when possible just to lower collision chance. 339b8df70beSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340b8df70beSmrg 341b8df70beSmrg trap ' 342b8df70beSmrg ret=$? 343b8df70beSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344b8df70beSmrg exit $ret 345b8df70beSmrg ' 0 346b8df70beSmrg 347b8df70beSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348b8df70beSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349b8df70beSmrg # directory is successfully created first before we actually test 350b8df70beSmrg # 'mkdir -p'. 351b8df70beSmrg if (umask $mkdir_umask && 352b8df70beSmrg $mkdirprog $mkdir_mode "$tmpdir" && 353b8df70beSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354b8df70beSmrg then 355b8df70beSmrg if test -z "$dir_arg" || { 356b8df70beSmrg # Check for POSIX incompatibilities with -m. 357b8df70beSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358b8df70beSmrg # other-writable bit of parent directory when it shouldn't. 359b8df70beSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360b8df70beSmrg test_tmpdir="$tmpdir/a" 361b8df70beSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362b8df70beSmrg case $ls_ld_tmpdir in 363b8df70beSmrg d????-?r-*) different_mode=700;; 364b8df70beSmrg d????-?--*) different_mode=755;; 365b8df70beSmrg *) false;; 366b8df70beSmrg esac && 367b8df70beSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368b8df70beSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369b8df70beSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370b8df70beSmrg } 371b8df70beSmrg } 372b8df70beSmrg then posix_mkdir=: 373b8df70beSmrg fi 374b8df70beSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375b8df70beSmrg else 376b8df70beSmrg # Remove any dirs left behind by ancient mkdir implementations. 377b8df70beSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378b8df70beSmrg fi 379b8df70beSmrg trap '' 0;; 3804c61c93dSmrg esac 38111d341caSmrg 3824c61c93dSmrg if 3834c61c93dSmrg $posix_mkdir && ( 38441fe0c2aSmrg umask $mkdir_umask && 38541fe0c2aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3864c61c93dSmrg ) 3874c61c93dSmrg then : 3884c61c93dSmrg else 38911d341caSmrg 390b8df70beSmrg # mkdir does not conform to POSIX, 3914c61c93dSmrg # or it failed possibly due to a race condition. Create the 3924c61c93dSmrg # directory the slow way, step by step, checking for races as we go. 39311d341caSmrg 3944c61c93dSmrg case $dstdir in 39541fe0c2aSmrg /*) prefix='/';; 39641fe0c2aSmrg [-=\(\)!]*) prefix='./';; 39741fe0c2aSmrg *) prefix='';; 3984c61c93dSmrg esac 39911d341caSmrg 4004c61c93dSmrg oIFS=$IFS 4014c61c93dSmrg IFS=/ 40241fe0c2aSmrg set -f 4034c61c93dSmrg set fnord $dstdir 40411d341caSmrg shift 40541fe0c2aSmrg set +f 4064c61c93dSmrg IFS=$oIFS 4074c61c93dSmrg 4084c61c93dSmrg prefixes= 4094c61c93dSmrg 4104c61c93dSmrg for d 4114c61c93dSmrg do 41241fe0c2aSmrg test X"$d" = X && continue 41341fe0c2aSmrg 41441fe0c2aSmrg prefix=$prefix$d 41541fe0c2aSmrg if test -d "$prefix"; then 41641fe0c2aSmrg prefixes= 41741fe0c2aSmrg else 41841fe0c2aSmrg if $posix_mkdir; then 419b8df70beSmrg (umask $mkdir_umask && 42041fe0c2aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42141fe0c2aSmrg # Don't fail if two instances are running concurrently. 42241fe0c2aSmrg test -d "$prefix" || exit 1 42341fe0c2aSmrg else 42441fe0c2aSmrg case $prefix in 42541fe0c2aSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42641fe0c2aSmrg *) qprefix=$prefix;; 42741fe0c2aSmrg esac 42841fe0c2aSmrg prefixes="$prefixes '$qprefix'" 42941fe0c2aSmrg fi 43041fe0c2aSmrg fi 43141fe0c2aSmrg prefix=$prefix/ 4324c61c93dSmrg done 4334c61c93dSmrg 4344c61c93dSmrg if test -n "$prefixes"; then 43541fe0c2aSmrg # Don't fail if two instances are running concurrently. 43641fe0c2aSmrg (umask $mkdir_umask && 43741fe0c2aSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 43841fe0c2aSmrg test -d "$dstdir" || exit 1 43941fe0c2aSmrg obsolete_mkdir_used=true 44011d341caSmrg fi 4414c61c93dSmrg fi 44211d341caSmrg fi 44311d341caSmrg 44411d341caSmrg if test -n "$dir_arg"; then 4454c61c93dSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4464c61c93dSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4474c61c93dSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4484c61c93dSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 44911d341caSmrg else 45011d341caSmrg 45111d341caSmrg # Make a couple of temp file names in the proper directory. 452b8df70beSmrg dsttmp=${dstdirslash}_inst.$$_ 453b8df70beSmrg rmtmp=${dstdirslash}_rm.$$_ 45411d341caSmrg 45511d341caSmrg # Trap to clean up those temp files at exit. 45611d341caSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 45711d341caSmrg 45811d341caSmrg # Copy the file name to the temp name. 459b8df70beSmrg (umask $cp_umask && 460b8df70beSmrg { test -z "$stripcmd" || { 461b8df70beSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462b8df70beSmrg # which would cause strip to fail. 463b8df70beSmrg if test -z "$doit"; then 464b8df70beSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 465b8df70beSmrg else 466b8df70beSmrg $doit touch "$dsttmp" 467b8df70beSmrg fi 468b8df70beSmrg } 469b8df70beSmrg } && 470b8df70beSmrg $doit_exec $cpprog "$src" "$dsttmp") && 47111d341caSmrg 47211d341caSmrg # and set any options; do chmod last to preserve setuid bits. 47311d341caSmrg # 47411d341caSmrg # If any of these fail, we abort the whole thing. If we want to 47511d341caSmrg # ignore errors from any of these, just make sure not to ignore 47611d341caSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 47711d341caSmrg # 4784c61c93dSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4794c61c93dSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4804c61c93dSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4814c61c93dSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4824c61c93dSmrg 4834c61c93dSmrg # If -C, don't bother to copy if it wouldn't change the file. 4844c61c93dSmrg if $copy_on_change && 48541fe0c2aSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48641fe0c2aSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48741fe0c2aSmrg set -f && 4884c61c93dSmrg set X $old && old=:$2:$4:$5:$6 && 4894c61c93dSmrg set X $new && new=:$2:$4:$5:$6 && 49041fe0c2aSmrg set +f && 4914c61c93dSmrg test "$old" = "$new" && 4924c61c93dSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4934c61c93dSmrg then 4944c61c93dSmrg rm -f "$dsttmp" 4954c61c93dSmrg else 496b8df70beSmrg # If $backupsuffix is set, and the file being installed 497b8df70beSmrg # already exists, attempt a backup. Don't worry if it fails, 498b8df70beSmrg # e.g., if mv doesn't support -f. 499b8df70beSmrg if test -n "$backupsuffix" && test -f "$dst"; then 500b8df70beSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501b8df70beSmrg fi 502b8df70beSmrg 5034c61c93dSmrg # Rename the file to the real destination. 5044c61c93dSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5054c61c93dSmrg 5064c61c93dSmrg # The rename failed, perhaps because mv can't rename something else 5074c61c93dSmrg # to itself, or perhaps because mv is so ancient that it does not 5084c61c93dSmrg # support -f. 5094c61c93dSmrg { 51041fe0c2aSmrg # Now remove or move aside any old file at destination location. 51141fe0c2aSmrg # We try this two ways since rm can't unlink itself on some 51241fe0c2aSmrg # systems and the destination file might be busy for other 51341fe0c2aSmrg # reasons. In this case, the final cleanup might fail but the new 51441fe0c2aSmrg # file should still install successfully. 51541fe0c2aSmrg { 51641fe0c2aSmrg test ! -f "$dst" || 517b8df70beSmrg $doit $rmcmd "$dst" 2>/dev/null || 51841fe0c2aSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519b8df70beSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52041fe0c2aSmrg } || 52141fe0c2aSmrg { echo "$0: cannot unlink or rename $dst" >&2 52241fe0c2aSmrg (exit 1); exit 1 52341fe0c2aSmrg } 52441fe0c2aSmrg } && 52541fe0c2aSmrg 52641fe0c2aSmrg # Now rename the file to the real destination. 52741fe0c2aSmrg $doit $mvcmd "$dsttmp" "$dst" 5284c61c93dSmrg } 5294c61c93dSmrg fi || exit 1 5304c61c93dSmrg 5314c61c93dSmrg trap '' 0 5324c61c93dSmrg fi 53311d341caSmrgdone 53411d341caSmrg 53511d341caSmrg# Local variables: 536b8df70beSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 53711d341caSmrg# time-stamp-start: "scriptversion=" 53811d341caSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539b8df70beSmrg# time-stamp-time-zone: "UTC0" 5404c61c93dSmrg# time-stamp-end: "; # UTC" 54111d341caSmrg# End: 542