install-sh revision e39ce84c
19aa228fdSmrg#!/bin/sh 29aa228fdSmrg# install - install a program, script, or datafile 39aa228fdSmrg 4e39ce84cSmrgscriptversion=2020-11-14.01; # UTC 59aa228fdSmrg 69aa228fdSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 79aa228fdSmrg# later released in X11R6 (xc/config/util/install.sh) with the 89aa228fdSmrg# following copyright and license. 99aa228fdSmrg# 109aa228fdSmrg# Copyright (C) 1994 X Consortium 119aa228fdSmrg# 129aa228fdSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 139aa228fdSmrg# of this software and associated documentation files (the "Software"), to 149aa228fdSmrg# deal in the Software without restriction, including without limitation the 159aa228fdSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 169aa228fdSmrg# sell copies of the Software, and to permit persons to whom the Software is 179aa228fdSmrg# furnished to do so, subject to the following conditions: 189aa228fdSmrg# 199aa228fdSmrg# The above copyright notice and this permission notice shall be included in 209aa228fdSmrg# all copies or substantial portions of the Software. 219aa228fdSmrg# 229aa228fdSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 239aa228fdSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 249aa228fdSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 259aa228fdSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 269aa228fdSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 279aa228fdSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 289aa228fdSmrg# 299aa228fdSmrg# Except as contained in this notice, the name of the X Consortium shall not 309aa228fdSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 319aa228fdSmrg# ings in this Software without prior written authorization from the X Consor- 329aa228fdSmrg# tium. 339aa228fdSmrg# 349aa228fdSmrg# 359aa228fdSmrg# FSF changes to this file are in the public domain. 369aa228fdSmrg# 379aa228fdSmrg# Calling this script install-sh is preferred over install.sh, to prevent 380c7e83b2Smrg# 'make' implicit rules from creating a file called install from it 399aa228fdSmrg# when there is no Makefile. 409aa228fdSmrg# 419aa228fdSmrg# This script is compatible with the BSD install script, but was written 429aa228fdSmrg# from scratch. 439aa228fdSmrg 440c7e83b2Smrgtab=' ' 459aa228fdSmrgnl=' 469aa228fdSmrg' 470c7e83b2SmrgIFS=" $tab$nl" 489aa228fdSmrg 490c7e83b2Smrg# Set DOITPROG to "echo" to test this script. 509aa228fdSmrg 518f65982aSmrgdoit=${DOITPROG-} 520c7e83b2Smrgdoit_exec=${doit:-exec} 539aa228fdSmrg 549aa228fdSmrg# Put in absolute file names if you don't have them in your path; 559aa228fdSmrg# or use environment vars. 569aa228fdSmrg 578f65982aSmrgchgrpprog=${CHGRPPROG-chgrp} 588f65982aSmrgchmodprog=${CHMODPROG-chmod} 598f65982aSmrgchownprog=${CHOWNPROG-chown} 608f65982aSmrgcmpprog=${CMPPROG-cmp} 618f65982aSmrgcpprog=${CPPROG-cp} 628f65982aSmrgmkdirprog=${MKDIRPROG-mkdir} 638f65982aSmrgmvprog=${MVPROG-mv} 648f65982aSmrgrmprog=${RMPROG-rm} 658f65982aSmrgstripprog=${STRIPPROG-strip} 668f65982aSmrg 679aa228fdSmrgposix_mkdir= 689aa228fdSmrg 699aa228fdSmrg# Desired mode of installed file. 709aa228fdSmrgmode=0755 719aa228fdSmrg 72e39ce84cSmrg# Create dirs (including intermediate dirs) using mode 755. 73e39ce84cSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74e39ce84cSmrgmkdir_umask=22 75e39ce84cSmrg 76e39ce84cSmrgbackupsuffix= 778f65982aSmrgchgrpcmd= 789aa228fdSmrgchmodcmd=$chmodprog 799aa228fdSmrgchowncmd= 808f65982aSmrgmvcmd=$mvprog 819aa228fdSmrgrmcmd="$rmprog -f" 828f65982aSmrgstripcmd= 838f65982aSmrg 849aa228fdSmrgsrc= 859aa228fdSmrgdst= 869aa228fdSmrgdir_arg= 878f65982aSmrgdst_arg= 888f65982aSmrg 898f65982aSmrgcopy_on_change=false 900c7e83b2Smrgis_target_a_directory=possibly 919aa228fdSmrg 928f65982aSmrgusage="\ 938f65982aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 949aa228fdSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 959aa228fdSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 969aa228fdSmrg or: $0 [OPTION]... -d DIRECTORIES... 979aa228fdSmrg 989aa228fdSmrgIn the 1st form, copy SRCFILE to DSTFILE. 999aa228fdSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1009aa228fdSmrgIn the 4th, create DIRECTORIES. 1019aa228fdSmrg 1029aa228fdSmrgOptions: 1038f65982aSmrg --help display this help and exit. 1048f65982aSmrg --version display version info and exit. 1058f65982aSmrg 1068f65982aSmrg -c (ignored) 107e39ce84cSmrg -C install only if different (preserve data modification time) 1088f65982aSmrg -d create directories instead of installing files. 1098f65982aSmrg -g GROUP $chgrpprog installed files to GROUP. 1108f65982aSmrg -m MODE $chmodprog installed files to MODE. 1118f65982aSmrg -o USER $chownprog installed files to USER. 112e39ce84cSmrg -p pass -p to $cpprog. 1138f65982aSmrg -s $stripprog installed files. 114e39ce84cSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1158f65982aSmrg -t DIRECTORY install into DIRECTORY. 1168f65982aSmrg -T report an error if DSTFILE is a directory. 1179aa228fdSmrg 1189aa228fdSmrgEnvironment variables override the default commands: 1198f65982aSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1208f65982aSmrg RMPROG STRIPPROG 121e39ce84cSmrg 122e39ce84cSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123e39ce84cSmrgit's up to you to specify -f if you want it. 124e39ce84cSmrg 125e39ce84cSmrgIf -S is not specified, no backups are attempted. 126e39ce84cSmrg 127e39ce84cSmrgEmail bug reports to bug-automake@gnu.org. 128e39ce84cSmrgAutomake home page: https://www.gnu.org/software/automake/ 1299aa228fdSmrg" 1309aa228fdSmrg 1319aa228fdSmrgwhile test $# -ne 0; do 1329aa228fdSmrg case $1 in 1338f65982aSmrg -c) ;; 1348f65982aSmrg 1358f65982aSmrg -C) copy_on_change=true;; 1369aa228fdSmrg 1378f65982aSmrg -d) dir_arg=true;; 1389aa228fdSmrg 1399aa228fdSmrg -g) chgrpcmd="$chgrpprog $2" 1400c7e83b2Smrg shift;; 1419aa228fdSmrg 1429aa228fdSmrg --help) echo "$usage"; exit $?;; 1439aa228fdSmrg 1449aa228fdSmrg -m) mode=$2 1450c7e83b2Smrg case $mode in 1460c7e83b2Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1470c7e83b2Smrg echo "$0: invalid mode: $mode" >&2 1480c7e83b2Smrg exit 1;; 1490c7e83b2Smrg esac 1500c7e83b2Smrg shift;; 1519aa228fdSmrg 1529aa228fdSmrg -o) chowncmd="$chownprog $2" 1530c7e83b2Smrg shift;; 1549aa228fdSmrg 155e39ce84cSmrg -p) cpprog="$cpprog -p";; 156e39ce84cSmrg 1578f65982aSmrg -s) stripcmd=$stripprog;; 1589aa228fdSmrg 159e39ce84cSmrg -S) backupsuffix="$2" 160e39ce84cSmrg shift;; 161e39ce84cSmrg 1620c7e83b2Smrg -t) 1630c7e83b2Smrg is_target_a_directory=always 1640c7e83b2Smrg dst_arg=$2 1650c7e83b2Smrg # Protect names problematic for 'test' and other utilities. 1660c7e83b2Smrg case $dst_arg in 1670c7e83b2Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1680c7e83b2Smrg esac 1690c7e83b2Smrg shift;; 1709aa228fdSmrg 1710c7e83b2Smrg -T) is_target_a_directory=never;; 1729aa228fdSmrg 1739aa228fdSmrg --version) echo "$0 $scriptversion"; exit $?;; 1749aa228fdSmrg 1750c7e83b2Smrg --) shift 1760c7e83b2Smrg break;; 1779aa228fdSmrg 1780c7e83b2Smrg -*) echo "$0: invalid option: $1" >&2 1790c7e83b2Smrg exit 1;; 1809aa228fdSmrg 1819aa228fdSmrg *) break;; 1829aa228fdSmrg esac 1838f65982aSmrg shift 1849aa228fdSmrgdone 1859aa228fdSmrg 1860c7e83b2Smrg# We allow the use of options -d and -T together, by making -d 1870c7e83b2Smrg# take the precedence; this is for compatibility with GNU install. 1880c7e83b2Smrg 1890c7e83b2Smrgif test -n "$dir_arg"; then 1900c7e83b2Smrg if test -n "$dst_arg"; then 1910c7e83b2Smrg echo "$0: target directory not allowed when installing a directory." >&2 1920c7e83b2Smrg exit 1 1930c7e83b2Smrg fi 1940c7e83b2Smrgfi 1950c7e83b2Smrg 1968f65982aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1979aa228fdSmrg # When -d is used, all remaining arguments are directories to create. 1989aa228fdSmrg # When -t is used, the destination is already specified. 1999aa228fdSmrg # Otherwise, the last argument is the destination. Remove it from $@. 2009aa228fdSmrg for arg 2019aa228fdSmrg do 2028f65982aSmrg if test -n "$dst_arg"; then 2039aa228fdSmrg # $@ is not empty: it contains at least $arg. 2048f65982aSmrg set fnord "$@" "$dst_arg" 2059aa228fdSmrg shift # fnord 2069aa228fdSmrg fi 2079aa228fdSmrg shift # arg 2088f65982aSmrg dst_arg=$arg 2090c7e83b2Smrg # Protect names problematic for 'test' and other utilities. 21080b026c6Smrg case $dst_arg in 21180b026c6Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21280b026c6Smrg esac 2139aa228fdSmrg done 2149aa228fdSmrgfi 2159aa228fdSmrg 2169aa228fdSmrgif test $# -eq 0; then 2179aa228fdSmrg if test -z "$dir_arg"; then 2189aa228fdSmrg echo "$0: no input file specified." >&2 2199aa228fdSmrg exit 1 2209aa228fdSmrg fi 2210c7e83b2Smrg # It's OK to call 'install-sh -d' without argument. 2229aa228fdSmrg # This can happen when creating conditional directories. 2239aa228fdSmrg exit 0 2249aa228fdSmrgfi 2259aa228fdSmrg 2260c7e83b2Smrgif test -z "$dir_arg"; then 2270c7e83b2Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2280c7e83b2Smrg if test ! -d "$dst_arg"; then 2290c7e83b2Smrg echo "$0: $dst_arg: Is not a directory." >&2 2300c7e83b2Smrg exit 1 2310c7e83b2Smrg fi 2320c7e83b2Smrg fi 2330c7e83b2Smrgfi 2340c7e83b2Smrg 2359aa228fdSmrgif test -z "$dir_arg"; then 23680b026c6Smrg do_exit='(exit $ret); exit $ret' 23780b026c6Smrg trap "ret=129; $do_exit" 1 23880b026c6Smrg trap "ret=130; $do_exit" 2 23980b026c6Smrg trap "ret=141; $do_exit" 13 24080b026c6Smrg trap "ret=143; $do_exit" 15 2419aa228fdSmrg 2429aa228fdSmrg # Set umask so as not to create temps with too-generous modes. 2439aa228fdSmrg # However, 'strip' requires both read and write access to temps. 2449aa228fdSmrg case $mode in 2459aa228fdSmrg # Optimize common cases. 2469aa228fdSmrg *644) cp_umask=133;; 2479aa228fdSmrg *755) cp_umask=22;; 2489aa228fdSmrg 2499aa228fdSmrg *[0-7]) 2509aa228fdSmrg if test -z "$stripcmd"; then 2510c7e83b2Smrg u_plus_rw= 2529aa228fdSmrg else 2530c7e83b2Smrg u_plus_rw='% 200' 2549aa228fdSmrg fi 2559aa228fdSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2569aa228fdSmrg *) 2579aa228fdSmrg if test -z "$stripcmd"; then 2580c7e83b2Smrg u_plus_rw= 2599aa228fdSmrg else 2600c7e83b2Smrg u_plus_rw=,u+rw 2619aa228fdSmrg fi 2629aa228fdSmrg cp_umask=$mode$u_plus_rw;; 2639aa228fdSmrg esac 2649aa228fdSmrgfi 2659aa228fdSmrg 2669aa228fdSmrgfor src 2679aa228fdSmrgdo 2680c7e83b2Smrg # Protect names problematic for 'test' and other utilities. 2699aa228fdSmrg case $src in 27080b026c6Smrg -* | [=\(\)!]) src=./$src;; 2719aa228fdSmrg esac 2729aa228fdSmrg 2739aa228fdSmrg if test -n "$dir_arg"; then 2749aa228fdSmrg dst=$src 2759aa228fdSmrg dstdir=$dst 2769aa228fdSmrg test -d "$dstdir" 2779aa228fdSmrg dstdir_status=$? 278e39ce84cSmrg # Don't chown directories that already exist. 279e39ce84cSmrg if test $dstdir_status = 0; then 280e39ce84cSmrg chowncmd="" 281e39ce84cSmrg fi 2829aa228fdSmrg else 2839aa228fdSmrg 2849aa228fdSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2859aa228fdSmrg # might cause directories to be created, which would be especially bad 2869aa228fdSmrg # if $src (and thus $dsttmp) contains '*'. 2879aa228fdSmrg if test ! -f "$src" && test ! -d "$src"; then 2889aa228fdSmrg echo "$0: $src does not exist." >&2 2899aa228fdSmrg exit 1 2909aa228fdSmrg fi 2919aa228fdSmrg 2928f65982aSmrg if test -z "$dst_arg"; then 2939aa228fdSmrg echo "$0: no destination specified." >&2 2949aa228fdSmrg exit 1 2959aa228fdSmrg fi 2968f65982aSmrg dst=$dst_arg 2979aa228fdSmrg 298e39ce84cSmrg # If destination is a directory, append the input filename. 2999aa228fdSmrg if test -d "$dst"; then 3000c7e83b2Smrg if test "$is_target_a_directory" = never; then 3010c7e83b2Smrg echo "$0: $dst_arg: Is a directory" >&2 3020c7e83b2Smrg exit 1 3039aa228fdSmrg fi 3049aa228fdSmrg dstdir=$dst 305e39ce84cSmrg dstbase=`basename "$src"` 306e39ce84cSmrg case $dst in 307e39ce84cSmrg */) dst=$dst$dstbase;; 308e39ce84cSmrg *) dst=$dst/$dstbase;; 309e39ce84cSmrg esac 3109aa228fdSmrg dstdir_status=0 3119aa228fdSmrg else 3120c7e83b2Smrg dstdir=`dirname "$dst"` 3139aa228fdSmrg test -d "$dstdir" 3149aa228fdSmrg dstdir_status=$? 3159aa228fdSmrg fi 3169aa228fdSmrg fi 3179aa228fdSmrg 318e39ce84cSmrg case $dstdir in 319e39ce84cSmrg */) dstdirslash=$dstdir;; 320e39ce84cSmrg *) dstdirslash=$dstdir/;; 321e39ce84cSmrg esac 322e39ce84cSmrg 3239aa228fdSmrg obsolete_mkdir_used=false 3249aa228fdSmrg 3259aa228fdSmrg if test $dstdir_status != 0; then 3269aa228fdSmrg case $posix_mkdir in 3279aa228fdSmrg '') 3280c7e83b2Smrg # With -d, create the new directory with the user-specified mode. 3290c7e83b2Smrg # Otherwise, rely on $mkdir_umask. 3300c7e83b2Smrg if test -n "$dir_arg"; then 3310c7e83b2Smrg mkdir_mode=-m$mode 3320c7e83b2Smrg else 3330c7e83b2Smrg mkdir_mode= 3340c7e83b2Smrg fi 3350c7e83b2Smrg 3360c7e83b2Smrg posix_mkdir=false 337e39ce84cSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 338e39ce84cSmrg # here however when possible just to lower collision chance. 339e39ce84cSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340e39ce84cSmrg 341e39ce84cSmrg trap ' 342e39ce84cSmrg ret=$? 343e39ce84cSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344e39ce84cSmrg exit $ret 345e39ce84cSmrg ' 0 346e39ce84cSmrg 347e39ce84cSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348e39ce84cSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349e39ce84cSmrg # directory is successfully created first before we actually test 350e39ce84cSmrg # 'mkdir -p'. 351e39ce84cSmrg if (umask $mkdir_umask && 352e39ce84cSmrg $mkdirprog $mkdir_mode "$tmpdir" && 353e39ce84cSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354e39ce84cSmrg then 355e39ce84cSmrg if test -z "$dir_arg" || { 356e39ce84cSmrg # Check for POSIX incompatibilities with -m. 357e39ce84cSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358e39ce84cSmrg # other-writable bit of parent directory when it shouldn't. 359e39ce84cSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360e39ce84cSmrg test_tmpdir="$tmpdir/a" 361e39ce84cSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362e39ce84cSmrg case $ls_ld_tmpdir in 363e39ce84cSmrg d????-?r-*) different_mode=700;; 364e39ce84cSmrg d????-?--*) different_mode=755;; 365e39ce84cSmrg *) false;; 366e39ce84cSmrg esac && 367e39ce84cSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368e39ce84cSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369e39ce84cSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370e39ce84cSmrg } 371e39ce84cSmrg } 372e39ce84cSmrg then posix_mkdir=: 373e39ce84cSmrg fi 374e39ce84cSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375e39ce84cSmrg else 376e39ce84cSmrg # Remove any dirs left behind by ancient mkdir implementations. 377e39ce84cSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378e39ce84cSmrg fi 379e39ce84cSmrg trap '' 0;; 3809aa228fdSmrg esac 3819aa228fdSmrg 3829aa228fdSmrg if 3839aa228fdSmrg $posix_mkdir && ( 3840c7e83b2Smrg umask $mkdir_umask && 3850c7e83b2Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3869aa228fdSmrg ) 3879aa228fdSmrg then : 3889aa228fdSmrg else 3899aa228fdSmrg 390e39ce84cSmrg # mkdir does not conform to POSIX, 3919aa228fdSmrg # or it failed possibly due to a race condition. Create the 3929aa228fdSmrg # directory the slow way, step by step, checking for races as we go. 3939aa228fdSmrg 3949aa228fdSmrg case $dstdir in 3950c7e83b2Smrg /*) prefix='/';; 3960c7e83b2Smrg [-=\(\)!]*) prefix='./';; 3970c7e83b2Smrg *) prefix='';; 3989aa228fdSmrg esac 3999aa228fdSmrg 4009aa228fdSmrg oIFS=$IFS 4019aa228fdSmrg IFS=/ 4020c7e83b2Smrg set -f 4039aa228fdSmrg set fnord $dstdir 4049aa228fdSmrg shift 4050c7e83b2Smrg set +f 4069aa228fdSmrg IFS=$oIFS 4079aa228fdSmrg 4089aa228fdSmrg prefixes= 4099aa228fdSmrg 4109aa228fdSmrg for d 4119aa228fdSmrg do 4120c7e83b2Smrg test X"$d" = X && continue 4130c7e83b2Smrg 4140c7e83b2Smrg prefix=$prefix$d 4150c7e83b2Smrg if test -d "$prefix"; then 4160c7e83b2Smrg prefixes= 4170c7e83b2Smrg else 4180c7e83b2Smrg if $posix_mkdir; then 419e39ce84cSmrg (umask $mkdir_umask && 4200c7e83b2Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4210c7e83b2Smrg # Don't fail if two instances are running concurrently. 4220c7e83b2Smrg test -d "$prefix" || exit 1 4230c7e83b2Smrg else 4240c7e83b2Smrg case $prefix in 4250c7e83b2Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4260c7e83b2Smrg *) qprefix=$prefix;; 4270c7e83b2Smrg esac 4280c7e83b2Smrg prefixes="$prefixes '$qprefix'" 4290c7e83b2Smrg fi 4300c7e83b2Smrg fi 4310c7e83b2Smrg prefix=$prefix/ 4329aa228fdSmrg done 4339aa228fdSmrg 4349aa228fdSmrg if test -n "$prefixes"; then 4350c7e83b2Smrg # Don't fail if two instances are running concurrently. 4360c7e83b2Smrg (umask $mkdir_umask && 4370c7e83b2Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4380c7e83b2Smrg test -d "$dstdir" || exit 1 4390c7e83b2Smrg obsolete_mkdir_used=true 4409aa228fdSmrg fi 4419aa228fdSmrg fi 4429aa228fdSmrg fi 4439aa228fdSmrg 4449aa228fdSmrg if test -n "$dir_arg"; then 4459aa228fdSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4469aa228fdSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4479aa228fdSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4489aa228fdSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4499aa228fdSmrg else 4509aa228fdSmrg 4519aa228fdSmrg # Make a couple of temp file names in the proper directory. 452e39ce84cSmrg dsttmp=${dstdirslash}_inst.$$_ 453e39ce84cSmrg rmtmp=${dstdirslash}_rm.$$_ 4549aa228fdSmrg 4559aa228fdSmrg # Trap to clean up those temp files at exit. 4569aa228fdSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4579aa228fdSmrg 4589aa228fdSmrg # Copy the file name to the temp name. 459e39ce84cSmrg (umask $cp_umask && 460e39ce84cSmrg { test -z "$stripcmd" || { 461e39ce84cSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462e39ce84cSmrg # which would cause strip to fail. 463e39ce84cSmrg if test -z "$doit"; then 464e39ce84cSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 465e39ce84cSmrg else 466e39ce84cSmrg $doit touch "$dsttmp" 467e39ce84cSmrg fi 468e39ce84cSmrg } 469e39ce84cSmrg } && 470e39ce84cSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4719aa228fdSmrg 4729aa228fdSmrg # and set any options; do chmod last to preserve setuid bits. 4739aa228fdSmrg # 4749aa228fdSmrg # If any of these fail, we abort the whole thing. If we want to 4759aa228fdSmrg # ignore errors from any of these, just make sure not to ignore 4769aa228fdSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4779aa228fdSmrg # 4788f65982aSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4798f65982aSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4808f65982aSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4818f65982aSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4828f65982aSmrg 4838f65982aSmrg # If -C, don't bother to copy if it wouldn't change the file. 4848f65982aSmrg if $copy_on_change && 4850c7e83b2Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4860c7e83b2Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4870c7e83b2Smrg set -f && 4888f65982aSmrg set X $old && old=:$2:$4:$5:$6 && 4898f65982aSmrg set X $new && new=:$2:$4:$5:$6 && 4900c7e83b2Smrg set +f && 4918f65982aSmrg test "$old" = "$new" && 4928f65982aSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4938f65982aSmrg then 4948f65982aSmrg rm -f "$dsttmp" 4958f65982aSmrg else 496e39ce84cSmrg # If $backupsuffix is set, and the file being installed 497e39ce84cSmrg # already exists, attempt a backup. Don't worry if it fails, 498e39ce84cSmrg # e.g., if mv doesn't support -f. 499e39ce84cSmrg if test -n "$backupsuffix" && test -f "$dst"; then 500e39ce84cSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501e39ce84cSmrg fi 502e39ce84cSmrg 5038f65982aSmrg # Rename the file to the real destination. 5048f65982aSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5058f65982aSmrg 5068f65982aSmrg # The rename failed, perhaps because mv can't rename something else 5078f65982aSmrg # to itself, or perhaps because mv is so ancient that it does not 5088f65982aSmrg # support -f. 5098f65982aSmrg { 5100c7e83b2Smrg # Now remove or move aside any old file at destination location. 5110c7e83b2Smrg # We try this two ways since rm can't unlink itself on some 5120c7e83b2Smrg # systems and the destination file might be busy for other 5130c7e83b2Smrg # reasons. In this case, the final cleanup might fail but the new 5140c7e83b2Smrg # file should still install successfully. 5150c7e83b2Smrg { 5160c7e83b2Smrg test ! -f "$dst" || 517e39ce84cSmrg $doit $rmcmd "$dst" 2>/dev/null || 5180c7e83b2Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519e39ce84cSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 5200c7e83b2Smrg } || 5210c7e83b2Smrg { echo "$0: cannot unlink or rename $dst" >&2 5220c7e83b2Smrg (exit 1); exit 1 5230c7e83b2Smrg } 5240c7e83b2Smrg } && 5250c7e83b2Smrg 5260c7e83b2Smrg # Now rename the file to the real destination. 5270c7e83b2Smrg $doit $mvcmd "$dsttmp" "$dst" 5288f65982aSmrg } 5298f65982aSmrg fi || exit 1 5309aa228fdSmrg 5319aa228fdSmrg trap '' 0 5329aa228fdSmrg fi 5339aa228fdSmrgdone 5349aa228fdSmrg 5359aa228fdSmrg# Local variables: 536e39ce84cSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5379aa228fdSmrg# time-stamp-start: "scriptversion=" 5389aa228fdSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539e39ce84cSmrg# time-stamp-time-zone: "UTC0" 5408f65982aSmrg# time-stamp-end: "; # UTC" 5419aa228fdSmrg# End: 542