install-sh revision 6d8e82c3
13e747e6dSmrg#!/bin/sh 23e747e6dSmrg# install - install a program, script, or datafile 33e747e6dSmrg 46d8e82c3Smrgscriptversion=2020-11-14.01; # UTC 53e747e6dSmrg 63e747e6dSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 73e747e6dSmrg# later released in X11R6 (xc/config/util/install.sh) with the 83e747e6dSmrg# following copyright and license. 93e747e6dSmrg# 103e747e6dSmrg# Copyright (C) 1994 X Consortium 113e747e6dSmrg# 123e747e6dSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 133e747e6dSmrg# of this software and associated documentation files (the "Software"), to 143e747e6dSmrg# deal in the Software without restriction, including without limitation the 153e747e6dSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 163e747e6dSmrg# sell copies of the Software, and to permit persons to whom the Software is 173e747e6dSmrg# furnished to do so, subject to the following conditions: 183e747e6dSmrg# 193e747e6dSmrg# The above copyright notice and this permission notice shall be included in 203e747e6dSmrg# all copies or substantial portions of the Software. 213e747e6dSmrg# 223e747e6dSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 233e747e6dSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 243e747e6dSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 253e747e6dSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 263e747e6dSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 273e747e6dSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 283e747e6dSmrg# 293e747e6dSmrg# Except as contained in this notice, the name of the X Consortium shall not 303e747e6dSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 313e747e6dSmrg# ings in this Software without prior written authorization from the X Consor- 323e747e6dSmrg# tium. 333e747e6dSmrg# 343e747e6dSmrg# 353e747e6dSmrg# FSF changes to this file are in the public domain. 363e747e6dSmrg# 373e747e6dSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38c2535118Smrg# 'make' implicit rules from creating a file called install from it 393e747e6dSmrg# when there is no Makefile. 403e747e6dSmrg# 413e747e6dSmrg# This script is compatible with the BSD install script, but was written 423e747e6dSmrg# from scratch. 433e747e6dSmrg 449cd34f4bSmrgtab=' ' 453e747e6dSmrgnl=' 463e747e6dSmrg' 479cd34f4bSmrgIFS=" $tab$nl" 483e747e6dSmrg 499cd34f4bSmrg# Set DOITPROG to "echo" to test this script. 503e747e6dSmrg 513e747e6dSmrgdoit=${DOITPROG-} 529cd34f4bSmrgdoit_exec=${doit:-exec} 533e747e6dSmrg 543e747e6dSmrg# Put in absolute file names if you don't have them in your path; 553e747e6dSmrg# or use environment vars. 563e747e6dSmrg 573e747e6dSmrgchgrpprog=${CHGRPPROG-chgrp} 583e747e6dSmrgchmodprog=${CHMODPROG-chmod} 593e747e6dSmrgchownprog=${CHOWNPROG-chown} 603e747e6dSmrgcmpprog=${CMPPROG-cmp} 613e747e6dSmrgcpprog=${CPPROG-cp} 623e747e6dSmrgmkdirprog=${MKDIRPROG-mkdir} 633e747e6dSmrgmvprog=${MVPROG-mv} 643e747e6dSmrgrmprog=${RMPROG-rm} 653e747e6dSmrgstripprog=${STRIPPROG-strip} 663e747e6dSmrg 673e747e6dSmrgposix_mkdir= 683e747e6dSmrg 693e747e6dSmrg# Desired mode of installed file. 703e747e6dSmrgmode=0755 713e747e6dSmrg 726d8e82c3Smrg# Create dirs (including intermediate dirs) using mode 755. 736d8e82c3Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 746d8e82c3Smrgmkdir_umask=22 756d8e82c3Smrg 766d8e82c3Smrgbackupsuffix= 773e747e6dSmrgchgrpcmd= 783e747e6dSmrgchmodcmd=$chmodprog 793e747e6dSmrgchowncmd= 803e747e6dSmrgmvcmd=$mvprog 813e747e6dSmrgrmcmd="$rmprog -f" 823e747e6dSmrgstripcmd= 833e747e6dSmrg 843e747e6dSmrgsrc= 853e747e6dSmrgdst= 863e747e6dSmrgdir_arg= 873e747e6dSmrgdst_arg= 883e747e6dSmrg 893e747e6dSmrgcopy_on_change=false 909cd34f4bSmrgis_target_a_directory=possibly 913e747e6dSmrg 923e747e6dSmrgusage="\ 933e747e6dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 943e747e6dSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 953e747e6dSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 963e747e6dSmrg or: $0 [OPTION]... -d DIRECTORIES... 973e747e6dSmrg 983e747e6dSmrgIn the 1st form, copy SRCFILE to DSTFILE. 993e747e6dSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1003e747e6dSmrgIn the 4th, create DIRECTORIES. 1013e747e6dSmrg 1023e747e6dSmrgOptions: 1033e747e6dSmrg --help display this help and exit. 1043e747e6dSmrg --version display version info and exit. 1053e747e6dSmrg 1063e747e6dSmrg -c (ignored) 1076d8e82c3Smrg -C install only if different (preserve data modification time) 1083e747e6dSmrg -d create directories instead of installing files. 1093e747e6dSmrg -g GROUP $chgrpprog installed files to GROUP. 1103e747e6dSmrg -m MODE $chmodprog installed files to MODE. 1113e747e6dSmrg -o USER $chownprog installed files to USER. 1126d8e82c3Smrg -p pass -p to $cpprog. 1133e747e6dSmrg -s $stripprog installed files. 1146d8e82c3Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1153e747e6dSmrg -t DIRECTORY install into DIRECTORY. 1163e747e6dSmrg -T report an error if DSTFILE is a directory. 1173e747e6dSmrg 1183e747e6dSmrgEnvironment variables override the default commands: 1193e747e6dSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1203e747e6dSmrg RMPROG STRIPPROG 1216d8e82c3Smrg 1226d8e82c3SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 1236d8e82c3Smrgit's up to you to specify -f if you want it. 1246d8e82c3Smrg 1256d8e82c3SmrgIf -S is not specified, no backups are attempted. 1266d8e82c3Smrg 1276d8e82c3SmrgEmail bug reports to bug-automake@gnu.org. 1286d8e82c3SmrgAutomake home page: https://www.gnu.org/software/automake/ 1293e747e6dSmrg" 1303e747e6dSmrg 1313e747e6dSmrgwhile test $# -ne 0; do 1323e747e6dSmrg case $1 in 1333e747e6dSmrg -c) ;; 1343e747e6dSmrg 1353e747e6dSmrg -C) copy_on_change=true;; 1363e747e6dSmrg 1373e747e6dSmrg -d) dir_arg=true;; 1383e747e6dSmrg 1393e747e6dSmrg -g) chgrpcmd="$chgrpprog $2" 1409cd34f4bSmrg shift;; 1413e747e6dSmrg 1423e747e6dSmrg --help) echo "$usage"; exit $?;; 1433e747e6dSmrg 1443e747e6dSmrg -m) mode=$2 1459cd34f4bSmrg case $mode in 1469cd34f4bSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1479cd34f4bSmrg echo "$0: invalid mode: $mode" >&2 1489cd34f4bSmrg exit 1;; 1499cd34f4bSmrg esac 1509cd34f4bSmrg shift;; 1513e747e6dSmrg 1523e747e6dSmrg -o) chowncmd="$chownprog $2" 1539cd34f4bSmrg shift;; 1543e747e6dSmrg 1556d8e82c3Smrg -p) cpprog="$cpprog -p";; 1566d8e82c3Smrg 1573e747e6dSmrg -s) stripcmd=$stripprog;; 1583e747e6dSmrg 1596d8e82c3Smrg -S) backupsuffix="$2" 1606d8e82c3Smrg shift;; 1616d8e82c3Smrg 1629cd34f4bSmrg -t) 1639cd34f4bSmrg is_target_a_directory=always 1649cd34f4bSmrg dst_arg=$2 1659cd34f4bSmrg # Protect names problematic for 'test' and other utilities. 1669cd34f4bSmrg case $dst_arg in 1679cd34f4bSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1689cd34f4bSmrg esac 1699cd34f4bSmrg shift;; 1703e747e6dSmrg 1719cd34f4bSmrg -T) is_target_a_directory=never;; 1723e747e6dSmrg 1733e747e6dSmrg --version) echo "$0 $scriptversion"; exit $?;; 1743e747e6dSmrg 1759cd34f4bSmrg --) shift 1769cd34f4bSmrg break;; 1773e747e6dSmrg 1789cd34f4bSmrg -*) echo "$0: invalid option: $1" >&2 1799cd34f4bSmrg exit 1;; 1803e747e6dSmrg 1813e747e6dSmrg *) break;; 1823e747e6dSmrg esac 1833e747e6dSmrg shift 1843e747e6dSmrgdone 1853e747e6dSmrg 1869cd34f4bSmrg# We allow the use of options -d and -T together, by making -d 1879cd34f4bSmrg# take the precedence; this is for compatibility with GNU install. 1889cd34f4bSmrg 1899cd34f4bSmrgif test -n "$dir_arg"; then 1909cd34f4bSmrg if test -n "$dst_arg"; then 1919cd34f4bSmrg echo "$0: target directory not allowed when installing a directory." >&2 1929cd34f4bSmrg exit 1 1939cd34f4bSmrg fi 1949cd34f4bSmrgfi 1959cd34f4bSmrg 1963e747e6dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1973e747e6dSmrg # When -d is used, all remaining arguments are directories to create. 1983e747e6dSmrg # When -t is used, the destination is already specified. 1993e747e6dSmrg # Otherwise, the last argument is the destination. Remove it from $@. 2003e747e6dSmrg for arg 2013e747e6dSmrg do 2023e747e6dSmrg if test -n "$dst_arg"; then 2033e747e6dSmrg # $@ is not empty: it contains at least $arg. 2043e747e6dSmrg set fnord "$@" "$dst_arg" 2053e747e6dSmrg shift # fnord 2063e747e6dSmrg fi 2073e747e6dSmrg shift # arg 2083e747e6dSmrg dst_arg=$arg 209c2535118Smrg # Protect names problematic for 'test' and other utilities. 210c2535118Smrg case $dst_arg in 211c2535118Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212c2535118Smrg esac 2133e747e6dSmrg done 2143e747e6dSmrgfi 2153e747e6dSmrg 2163e747e6dSmrgif test $# -eq 0; then 2173e747e6dSmrg if test -z "$dir_arg"; then 2183e747e6dSmrg echo "$0: no input file specified." >&2 2193e747e6dSmrg exit 1 2203e747e6dSmrg fi 221c2535118Smrg # It's OK to call 'install-sh -d' without argument. 2223e747e6dSmrg # This can happen when creating conditional directories. 2233e747e6dSmrg exit 0 2243e747e6dSmrgfi 2253e747e6dSmrg 2269cd34f4bSmrgif test -z "$dir_arg"; then 2279cd34f4bSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2289cd34f4bSmrg if test ! -d "$dst_arg"; then 2299cd34f4bSmrg echo "$0: $dst_arg: Is not a directory." >&2 2309cd34f4bSmrg exit 1 2319cd34f4bSmrg fi 2329cd34f4bSmrg fi 2339cd34f4bSmrgfi 2349cd34f4bSmrg 2353e747e6dSmrgif test -z "$dir_arg"; then 236c2535118Smrg do_exit='(exit $ret); exit $ret' 237c2535118Smrg trap "ret=129; $do_exit" 1 238c2535118Smrg trap "ret=130; $do_exit" 2 239c2535118Smrg trap "ret=141; $do_exit" 13 240c2535118Smrg trap "ret=143; $do_exit" 15 2413e747e6dSmrg 2423e747e6dSmrg # Set umask so as not to create temps with too-generous modes. 2433e747e6dSmrg # However, 'strip' requires both read and write access to temps. 2443e747e6dSmrg case $mode in 2453e747e6dSmrg # Optimize common cases. 2463e747e6dSmrg *644) cp_umask=133;; 2473e747e6dSmrg *755) cp_umask=22;; 2483e747e6dSmrg 2493e747e6dSmrg *[0-7]) 2503e747e6dSmrg if test -z "$stripcmd"; then 2519cd34f4bSmrg u_plus_rw= 2523e747e6dSmrg else 2539cd34f4bSmrg u_plus_rw='% 200' 2543e747e6dSmrg fi 2553e747e6dSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2563e747e6dSmrg *) 2573e747e6dSmrg if test -z "$stripcmd"; then 2589cd34f4bSmrg u_plus_rw= 2593e747e6dSmrg else 2609cd34f4bSmrg u_plus_rw=,u+rw 2613e747e6dSmrg fi 2623e747e6dSmrg cp_umask=$mode$u_plus_rw;; 2633e747e6dSmrg esac 2643e747e6dSmrgfi 2653e747e6dSmrg 2663e747e6dSmrgfor src 2673e747e6dSmrgdo 268c2535118Smrg # Protect names problematic for 'test' and other utilities. 2693e747e6dSmrg case $src in 270c2535118Smrg -* | [=\(\)!]) src=./$src;; 2713e747e6dSmrg esac 2723e747e6dSmrg 2733e747e6dSmrg if test -n "$dir_arg"; then 2743e747e6dSmrg dst=$src 2753e747e6dSmrg dstdir=$dst 2763e747e6dSmrg test -d "$dstdir" 2773e747e6dSmrg dstdir_status=$? 2786d8e82c3Smrg # Don't chown directories that already exist. 2796d8e82c3Smrg if test $dstdir_status = 0; then 2806d8e82c3Smrg chowncmd="" 2816d8e82c3Smrg fi 2823e747e6dSmrg else 2833e747e6dSmrg 2843e747e6dSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2853e747e6dSmrg # might cause directories to be created, which would be especially bad 2863e747e6dSmrg # if $src (and thus $dsttmp) contains '*'. 2873e747e6dSmrg if test ! -f "$src" && test ! -d "$src"; then 2883e747e6dSmrg echo "$0: $src does not exist." >&2 2893e747e6dSmrg exit 1 2903e747e6dSmrg fi 2913e747e6dSmrg 2923e747e6dSmrg if test -z "$dst_arg"; then 2933e747e6dSmrg echo "$0: no destination specified." >&2 2943e747e6dSmrg exit 1 2953e747e6dSmrg fi 2963e747e6dSmrg dst=$dst_arg 2973e747e6dSmrg 2986d8e82c3Smrg # If destination is a directory, append the input filename. 2993e747e6dSmrg if test -d "$dst"; then 3009cd34f4bSmrg if test "$is_target_a_directory" = never; then 3019cd34f4bSmrg echo "$0: $dst_arg: Is a directory" >&2 3029cd34f4bSmrg exit 1 3033e747e6dSmrg fi 3043e747e6dSmrg dstdir=$dst 3056d8e82c3Smrg dstbase=`basename "$src"` 3066d8e82c3Smrg case $dst in 3076d8e82c3Smrg */) dst=$dst$dstbase;; 3086d8e82c3Smrg *) dst=$dst/$dstbase;; 3096d8e82c3Smrg esac 3103e747e6dSmrg dstdir_status=0 3113e747e6dSmrg else 3129cd34f4bSmrg dstdir=`dirname "$dst"` 3133e747e6dSmrg test -d "$dstdir" 3143e747e6dSmrg dstdir_status=$? 3153e747e6dSmrg fi 3163e747e6dSmrg fi 3173e747e6dSmrg 3186d8e82c3Smrg case $dstdir in 3196d8e82c3Smrg */) dstdirslash=$dstdir;; 3206d8e82c3Smrg *) dstdirslash=$dstdir/;; 3216d8e82c3Smrg esac 3226d8e82c3Smrg 3233e747e6dSmrg obsolete_mkdir_used=false 3243e747e6dSmrg 3253e747e6dSmrg if test $dstdir_status != 0; then 3263e747e6dSmrg case $posix_mkdir in 3273e747e6dSmrg '') 3289cd34f4bSmrg # With -d, create the new directory with the user-specified mode. 3299cd34f4bSmrg # Otherwise, rely on $mkdir_umask. 3309cd34f4bSmrg if test -n "$dir_arg"; then 3319cd34f4bSmrg mkdir_mode=-m$mode 3329cd34f4bSmrg else 3339cd34f4bSmrg mkdir_mode= 3349cd34f4bSmrg fi 3359cd34f4bSmrg 3369cd34f4bSmrg posix_mkdir=false 3376d8e82c3Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 3386d8e82c3Smrg # here however when possible just to lower collision chance. 3396d8e82c3Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3406d8e82c3Smrg 3416d8e82c3Smrg trap ' 3426d8e82c3Smrg ret=$? 3436d8e82c3Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 3446d8e82c3Smrg exit $ret 3456d8e82c3Smrg ' 0 3466d8e82c3Smrg 3476d8e82c3Smrg # Because "mkdir -p" follows existing symlinks and we likely work 3486d8e82c3Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 3496d8e82c3Smrg # directory is successfully created first before we actually test 3506d8e82c3Smrg # 'mkdir -p'. 3516d8e82c3Smrg if (umask $mkdir_umask && 3526d8e82c3Smrg $mkdirprog $mkdir_mode "$tmpdir" && 3536d8e82c3Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 3546d8e82c3Smrg then 3556d8e82c3Smrg if test -z "$dir_arg" || { 3566d8e82c3Smrg # Check for POSIX incompatibilities with -m. 3576d8e82c3Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3586d8e82c3Smrg # other-writable bit of parent directory when it shouldn't. 3596d8e82c3Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3606d8e82c3Smrg test_tmpdir="$tmpdir/a" 3616d8e82c3Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 3626d8e82c3Smrg case $ls_ld_tmpdir in 3636d8e82c3Smrg d????-?r-*) different_mode=700;; 3646d8e82c3Smrg d????-?--*) different_mode=755;; 3656d8e82c3Smrg *) false;; 3666d8e82c3Smrg esac && 3676d8e82c3Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 3686d8e82c3Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 3696d8e82c3Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3706d8e82c3Smrg } 3716d8e82c3Smrg } 3726d8e82c3Smrg then posix_mkdir=: 3736d8e82c3Smrg fi 3746d8e82c3Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3756d8e82c3Smrg else 3766d8e82c3Smrg # Remove any dirs left behind by ancient mkdir implementations. 3776d8e82c3Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3786d8e82c3Smrg fi 3796d8e82c3Smrg trap '' 0;; 3803e747e6dSmrg esac 3813e747e6dSmrg 3823e747e6dSmrg if 3833e747e6dSmrg $posix_mkdir && ( 3849cd34f4bSmrg umask $mkdir_umask && 3859cd34f4bSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3863e747e6dSmrg ) 3873e747e6dSmrg then : 3883e747e6dSmrg else 3893e747e6dSmrg 3906d8e82c3Smrg # mkdir does not conform to POSIX, 3913e747e6dSmrg # or it failed possibly due to a race condition. Create the 3923e747e6dSmrg # directory the slow way, step by step, checking for races as we go. 3933e747e6dSmrg 3943e747e6dSmrg case $dstdir in 3959cd34f4bSmrg /*) prefix='/';; 3969cd34f4bSmrg [-=\(\)!]*) prefix='./';; 3979cd34f4bSmrg *) prefix='';; 3983e747e6dSmrg esac 3993e747e6dSmrg 4003e747e6dSmrg oIFS=$IFS 4013e747e6dSmrg IFS=/ 4029cd34f4bSmrg set -f 4033e747e6dSmrg set fnord $dstdir 4043e747e6dSmrg shift 4059cd34f4bSmrg set +f 4063e747e6dSmrg IFS=$oIFS 4073e747e6dSmrg 4083e747e6dSmrg prefixes= 4093e747e6dSmrg 4103e747e6dSmrg for d 4113e747e6dSmrg do 4129cd34f4bSmrg test X"$d" = X && continue 4139cd34f4bSmrg 4149cd34f4bSmrg prefix=$prefix$d 4159cd34f4bSmrg if test -d "$prefix"; then 4169cd34f4bSmrg prefixes= 4179cd34f4bSmrg else 4189cd34f4bSmrg if $posix_mkdir; then 4196d8e82c3Smrg (umask $mkdir_umask && 4209cd34f4bSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4219cd34f4bSmrg # Don't fail if two instances are running concurrently. 4229cd34f4bSmrg test -d "$prefix" || exit 1 4239cd34f4bSmrg else 4249cd34f4bSmrg case $prefix in 4259cd34f4bSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4269cd34f4bSmrg *) qprefix=$prefix;; 4279cd34f4bSmrg esac 4289cd34f4bSmrg prefixes="$prefixes '$qprefix'" 4299cd34f4bSmrg fi 4309cd34f4bSmrg fi 4319cd34f4bSmrg prefix=$prefix/ 4323e747e6dSmrg done 4333e747e6dSmrg 4343e747e6dSmrg if test -n "$prefixes"; then 4359cd34f4bSmrg # Don't fail if two instances are running concurrently. 4369cd34f4bSmrg (umask $mkdir_umask && 4379cd34f4bSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 4389cd34f4bSmrg test -d "$dstdir" || exit 1 4399cd34f4bSmrg obsolete_mkdir_used=true 4403e747e6dSmrg fi 4413e747e6dSmrg fi 4423e747e6dSmrg fi 4433e747e6dSmrg 4443e747e6dSmrg if test -n "$dir_arg"; then 4453e747e6dSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4463e747e6dSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4473e747e6dSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4483e747e6dSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4493e747e6dSmrg else 4503e747e6dSmrg 4513e747e6dSmrg # Make a couple of temp file names in the proper directory. 4526d8e82c3Smrg dsttmp=${dstdirslash}_inst.$$_ 4536d8e82c3Smrg rmtmp=${dstdirslash}_rm.$$_ 4543e747e6dSmrg 4553e747e6dSmrg # Trap to clean up those temp files at exit. 4563e747e6dSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4573e747e6dSmrg 4583e747e6dSmrg # Copy the file name to the temp name. 4596d8e82c3Smrg (umask $cp_umask && 4606d8e82c3Smrg { test -z "$stripcmd" || { 4616d8e82c3Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 4626d8e82c3Smrg # which would cause strip to fail. 4636d8e82c3Smrg if test -z "$doit"; then 4646d8e82c3Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 4656d8e82c3Smrg else 4666d8e82c3Smrg $doit touch "$dsttmp" 4676d8e82c3Smrg fi 4686d8e82c3Smrg } 4696d8e82c3Smrg } && 4706d8e82c3Smrg $doit_exec $cpprog "$src" "$dsttmp") && 4713e747e6dSmrg 4723e747e6dSmrg # and set any options; do chmod last to preserve setuid bits. 4733e747e6dSmrg # 4743e747e6dSmrg # If any of these fail, we abort the whole thing. If we want to 4753e747e6dSmrg # ignore errors from any of these, just make sure not to ignore 4763e747e6dSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4773e747e6dSmrg # 4783e747e6dSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4793e747e6dSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4803e747e6dSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4813e747e6dSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4823e747e6dSmrg 4833e747e6dSmrg # If -C, don't bother to copy if it wouldn't change the file. 4843e747e6dSmrg if $copy_on_change && 4859cd34f4bSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4869cd34f4bSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4879cd34f4bSmrg set -f && 4883e747e6dSmrg set X $old && old=:$2:$4:$5:$6 && 4893e747e6dSmrg set X $new && new=:$2:$4:$5:$6 && 4909cd34f4bSmrg set +f && 4913e747e6dSmrg test "$old" = "$new" && 4923e747e6dSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4933e747e6dSmrg then 4943e747e6dSmrg rm -f "$dsttmp" 4953e747e6dSmrg else 4966d8e82c3Smrg # If $backupsuffix is set, and the file being installed 4976d8e82c3Smrg # already exists, attempt a backup. Don't worry if it fails, 4986d8e82c3Smrg # e.g., if mv doesn't support -f. 4996d8e82c3Smrg if test -n "$backupsuffix" && test -f "$dst"; then 5006d8e82c3Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 5016d8e82c3Smrg fi 5026d8e82c3Smrg 5033e747e6dSmrg # Rename the file to the real destination. 5043e747e6dSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5053e747e6dSmrg 5063e747e6dSmrg # The rename failed, perhaps because mv can't rename something else 5073e747e6dSmrg # to itself, or perhaps because mv is so ancient that it does not 5083e747e6dSmrg # support -f. 5093e747e6dSmrg { 5109cd34f4bSmrg # Now remove or move aside any old file at destination location. 5119cd34f4bSmrg # We try this two ways since rm can't unlink itself on some 5129cd34f4bSmrg # systems and the destination file might be busy for other 5139cd34f4bSmrg # reasons. In this case, the final cleanup might fail but the new 5149cd34f4bSmrg # file should still install successfully. 5159cd34f4bSmrg { 5169cd34f4bSmrg test ! -f "$dst" || 5176d8e82c3Smrg $doit $rmcmd "$dst" 2>/dev/null || 5189cd34f4bSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5196d8e82c3Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 5209cd34f4bSmrg } || 5219cd34f4bSmrg { echo "$0: cannot unlink or rename $dst" >&2 5229cd34f4bSmrg (exit 1); exit 1 5239cd34f4bSmrg } 5249cd34f4bSmrg } && 5259cd34f4bSmrg 5269cd34f4bSmrg # Now rename the file to the real destination. 5279cd34f4bSmrg $doit $mvcmd "$dsttmp" "$dst" 5283e747e6dSmrg } 5293e747e6dSmrg fi || exit 1 5303e747e6dSmrg 5313e747e6dSmrg trap '' 0 5323e747e6dSmrg fi 5333e747e6dSmrgdone 5343e747e6dSmrg 5353e747e6dSmrg# Local variables: 5366d8e82c3Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 5373e747e6dSmrg# time-stamp-start: "scriptversion=" 5383e747e6dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5396d8e82c3Smrg# time-stamp-time-zone: "UTC0" 5407a2631fcSmrg# time-stamp-end: "; # UTC" 5413e747e6dSmrg# End: 542