install-sh revision ddb28773
14d9b34d9Smrg#!/bin/sh 24d9b34d9Smrg# install - install a program, script, or datafile 34d9b34d9Smrg 4ddb28773Smrgscriptversion=2020-11-14.01; # UTC 54d9b34d9Smrg 64d9b34d9Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 74d9b34d9Smrg# later released in X11R6 (xc/config/util/install.sh) with the 84d9b34d9Smrg# following copyright and license. 94d9b34d9Smrg# 104d9b34d9Smrg# Copyright (C) 1994 X Consortium 114d9b34d9Smrg# 124d9b34d9Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 134d9b34d9Smrg# of this software and associated documentation files (the "Software"), to 144d9b34d9Smrg# deal in the Software without restriction, including without limitation the 154d9b34d9Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 164d9b34d9Smrg# sell copies of the Software, and to permit persons to whom the Software is 174d9b34d9Smrg# furnished to do so, subject to the following conditions: 184d9b34d9Smrg# 194d9b34d9Smrg# The above copyright notice and this permission notice shall be included in 204d9b34d9Smrg# all copies or substantial portions of the Software. 214d9b34d9Smrg# 224d9b34d9Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 234d9b34d9Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 244d9b34d9Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 254d9b34d9Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 264d9b34d9Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 274d9b34d9Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 284d9b34d9Smrg# 294d9b34d9Smrg# Except as contained in this notice, the name of the X Consortium shall not 304d9b34d9Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 314d9b34d9Smrg# ings in this Software without prior written authorization from the X Consor- 324d9b34d9Smrg# tium. 334d9b34d9Smrg# 344d9b34d9Smrg# 354d9b34d9Smrg# FSF changes to this file are in the public domain. 364d9b34d9Smrg# 374d9b34d9Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3819d64aeeSmrg# 'make' implicit rules from creating a file called install from it 394d9b34d9Smrg# when there is no Makefile. 404d9b34d9Smrg# 414d9b34d9Smrg# This script is compatible with the BSD install script, but was written 424d9b34d9Smrg# from scratch. 434d9b34d9Smrg 4419d64aeeSmrgtab=' ' 454d9b34d9Smrgnl=' 464d9b34d9Smrg' 4719d64aeeSmrgIFS=" $tab$nl" 484d9b34d9Smrg 4919d64aeeSmrg# Set DOITPROG to "echo" to test this script. 504d9b34d9Smrg 518512f934Smrgdoit=${DOITPROG-} 5219d64aeeSmrgdoit_exec=${doit:-exec} 534d9b34d9Smrg 544d9b34d9Smrg# Put in absolute file names if you don't have them in your path; 554d9b34d9Smrg# or use environment vars. 564d9b34d9Smrg 578512f934Smrgchgrpprog=${CHGRPPROG-chgrp} 588512f934Smrgchmodprog=${CHMODPROG-chmod} 598512f934Smrgchownprog=${CHOWNPROG-chown} 608512f934Smrgcmpprog=${CMPPROG-cmp} 618512f934Smrgcpprog=${CPPROG-cp} 628512f934Smrgmkdirprog=${MKDIRPROG-mkdir} 638512f934Smrgmvprog=${MVPROG-mv} 648512f934Smrgrmprog=${RMPROG-rm} 658512f934Smrgstripprog=${STRIPPROG-strip} 668512f934Smrg 674d9b34d9Smrgposix_mkdir= 684d9b34d9Smrg 694d9b34d9Smrg# Desired mode of installed file. 704d9b34d9Smrgmode=0755 714d9b34d9Smrg 72ddb28773Smrg# Create dirs (including intermediate dirs) using mode 755. 73ddb28773Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74ddb28773Smrgmkdir_umask=22 75ddb28773Smrg 76ddb28773Smrgbackupsuffix= 778512f934Smrgchgrpcmd= 784d9b34d9Smrgchmodcmd=$chmodprog 794d9b34d9Smrgchowncmd= 808512f934Smrgmvcmd=$mvprog 814d9b34d9Smrgrmcmd="$rmprog -f" 828512f934Smrgstripcmd= 838512f934Smrg 844d9b34d9Smrgsrc= 854d9b34d9Smrgdst= 864d9b34d9Smrgdir_arg= 878512f934Smrgdst_arg= 888512f934Smrg 898512f934Smrgcopy_on_change=false 9019d64aeeSmrgis_target_a_directory=possibly 914d9b34d9Smrg 928512f934Smrgusage="\ 938512f934SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 944d9b34d9Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 954d9b34d9Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 964d9b34d9Smrg or: $0 [OPTION]... -d DIRECTORIES... 974d9b34d9Smrg 984d9b34d9SmrgIn the 1st form, copy SRCFILE to DSTFILE. 994d9b34d9SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1004d9b34d9SmrgIn the 4th, create DIRECTORIES. 1014d9b34d9Smrg 1024d9b34d9SmrgOptions: 1038512f934Smrg --help display this help and exit. 1048512f934Smrg --version display version info and exit. 1058512f934Smrg 1068512f934Smrg -c (ignored) 107ddb28773Smrg -C install only if different (preserve data modification time) 1088512f934Smrg -d create directories instead of installing files. 1098512f934Smrg -g GROUP $chgrpprog installed files to GROUP. 1108512f934Smrg -m MODE $chmodprog installed files to MODE. 1118512f934Smrg -o USER $chownprog installed files to USER. 112ddb28773Smrg -p pass -p to $cpprog. 1138512f934Smrg -s $stripprog installed files. 114ddb28773Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1158512f934Smrg -t DIRECTORY install into DIRECTORY. 1168512f934Smrg -T report an error if DSTFILE is a directory. 1174d9b34d9Smrg 1184d9b34d9SmrgEnvironment variables override the default commands: 1198512f934Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1208512f934Smrg RMPROG STRIPPROG 121ddb28773Smrg 122ddb28773SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123ddb28773Smrgit's up to you to specify -f if you want it. 124ddb28773Smrg 125ddb28773SmrgIf -S is not specified, no backups are attempted. 126ddb28773Smrg 127ddb28773SmrgEmail bug reports to bug-automake@gnu.org. 128ddb28773SmrgAutomake home page: https://www.gnu.org/software/automake/ 1294d9b34d9Smrg" 1304d9b34d9Smrg 1314d9b34d9Smrgwhile test $# -ne 0; do 1324d9b34d9Smrg case $1 in 1338512f934Smrg -c) ;; 1348512f934Smrg 1358512f934Smrg -C) copy_on_change=true;; 1364d9b34d9Smrg 1378512f934Smrg -d) dir_arg=true;; 1384d9b34d9Smrg 139498372abSmrg -g) chgrpcmd="$chgrpprog $2" 14019d64aeeSmrg shift;; 1414d9b34d9Smrg 142498372abSmrg --help) echo "$usage"; exit $?;; 1434d9b34d9Smrg 1444d9b34d9Smrg -m) mode=$2 14519d64aeeSmrg case $mode in 14619d64aeeSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14719d64aeeSmrg echo "$0: invalid mode: $mode" >&2 14819d64aeeSmrg exit 1;; 14919d64aeeSmrg esac 15019d64aeeSmrg shift;; 1514d9b34d9Smrg 152498372abSmrg -o) chowncmd="$chownprog $2" 15319d64aeeSmrg shift;; 1544d9b34d9Smrg 155ddb28773Smrg -p) cpprog="$cpprog -p";; 156ddb28773Smrg 1578512f934Smrg -s) stripcmd=$stripprog;; 1584d9b34d9Smrg 159ddb28773Smrg -S) backupsuffix="$2" 160ddb28773Smrg shift;; 161ddb28773Smrg 16219d64aeeSmrg -t) 16319d64aeeSmrg is_target_a_directory=always 16419d64aeeSmrg dst_arg=$2 16519d64aeeSmrg # Protect names problematic for 'test' and other utilities. 16619d64aeeSmrg case $dst_arg in 16719d64aeeSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16819d64aeeSmrg esac 16919d64aeeSmrg shift;; 1704d9b34d9Smrg 17119d64aeeSmrg -T) is_target_a_directory=never;; 1724d9b34d9Smrg 173498372abSmrg --version) echo "$0 $scriptversion"; exit $?;; 1744d9b34d9Smrg 17519d64aeeSmrg --) shift 17619d64aeeSmrg break;; 1774d9b34d9Smrg 17819d64aeeSmrg -*) echo "$0: invalid option: $1" >&2 17919d64aeeSmrg exit 1;; 1804d9b34d9Smrg 1814d9b34d9Smrg *) break;; 1824d9b34d9Smrg esac 1838512f934Smrg shift 1844d9b34d9Smrgdone 1854d9b34d9Smrg 18619d64aeeSmrg# We allow the use of options -d and -T together, by making -d 18719d64aeeSmrg# take the precedence; this is for compatibility with GNU install. 18819d64aeeSmrg 18919d64aeeSmrgif test -n "$dir_arg"; then 19019d64aeeSmrg if test -n "$dst_arg"; then 19119d64aeeSmrg echo "$0: target directory not allowed when installing a directory." >&2 19219d64aeeSmrg exit 1 19319d64aeeSmrg fi 19419d64aeeSmrgfi 19519d64aeeSmrg 196498372abSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1974d9b34d9Smrg # When -d is used, all remaining arguments are directories to create. 1984d9b34d9Smrg # When -t is used, the destination is already specified. 1994d9b34d9Smrg # Otherwise, the last argument is the destination. Remove it from $@. 2004d9b34d9Smrg for arg 2014d9b34d9Smrg do 2028512f934Smrg if test -n "$dst_arg"; then 203498372abSmrg # $@ is not empty: it contains at least $arg. 204498372abSmrg set fnord "$@" "$dst_arg" 2054d9b34d9Smrg shift # fnord 2064d9b34d9Smrg fi 2074d9b34d9Smrg shift # arg 2088512f934Smrg dst_arg=$arg 20919d64aeeSmrg # Protect names problematic for 'test' and other utilities. 210498372abSmrg case $dst_arg in 211498372abSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212498372abSmrg esac 2134d9b34d9Smrg done 2144d9b34d9Smrgfi 2154d9b34d9Smrg 2164d9b34d9Smrgif test $# -eq 0; then 2174d9b34d9Smrg if test -z "$dir_arg"; then 2184d9b34d9Smrg echo "$0: no input file specified." >&2 2194d9b34d9Smrg exit 1 2204d9b34d9Smrg fi 22119d64aeeSmrg # It's OK to call 'install-sh -d' without argument. 2224d9b34d9Smrg # This can happen when creating conditional directories. 2234d9b34d9Smrg exit 0 2244d9b34d9Smrgfi 2254d9b34d9Smrg 22619d64aeeSmrgif test -z "$dir_arg"; then 22719d64aeeSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22819d64aeeSmrg if test ! -d "$dst_arg"; then 22919d64aeeSmrg echo "$0: $dst_arg: Is not a directory." >&2 23019d64aeeSmrg exit 1 23119d64aeeSmrg fi 23219d64aeeSmrg fi 23319d64aeeSmrgfi 23419d64aeeSmrg 2354d9b34d9Smrgif test -z "$dir_arg"; then 236498372abSmrg do_exit='(exit $ret); exit $ret' 237498372abSmrg trap "ret=129; $do_exit" 1 238498372abSmrg trap "ret=130; $do_exit" 2 239498372abSmrg trap "ret=141; $do_exit" 13 240498372abSmrg trap "ret=143; $do_exit" 15 2414d9b34d9Smrg 2424d9b34d9Smrg # Set umask so as not to create temps with too-generous modes. 2434d9b34d9Smrg # However, 'strip' requires both read and write access to temps. 2444d9b34d9Smrg case $mode in 2454d9b34d9Smrg # Optimize common cases. 2464d9b34d9Smrg *644) cp_umask=133;; 2474d9b34d9Smrg *755) cp_umask=22;; 2484d9b34d9Smrg 2494d9b34d9Smrg *[0-7]) 2504d9b34d9Smrg if test -z "$stripcmd"; then 25119d64aeeSmrg u_plus_rw= 2524d9b34d9Smrg else 25319d64aeeSmrg u_plus_rw='% 200' 2544d9b34d9Smrg fi 255498372abSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2564d9b34d9Smrg *) 2574d9b34d9Smrg if test -z "$stripcmd"; then 25819d64aeeSmrg u_plus_rw= 2594d9b34d9Smrg else 26019d64aeeSmrg u_plus_rw=,u+rw 2614d9b34d9Smrg fi 262498372abSmrg cp_umask=$mode$u_plus_rw;; 2634d9b34d9Smrg esac 2644d9b34d9Smrgfi 2654d9b34d9Smrg 2664d9b34d9Smrgfor src 2674d9b34d9Smrgdo 26819d64aeeSmrg # Protect names problematic for 'test' and other utilities. 2694d9b34d9Smrg case $src in 270498372abSmrg -* | [=\(\)!]) src=./$src;; 2714d9b34d9Smrg esac 2724d9b34d9Smrg 2734d9b34d9Smrg if test -n "$dir_arg"; then 2744d9b34d9Smrg dst=$src 2754d9b34d9Smrg dstdir=$dst 2764d9b34d9Smrg test -d "$dstdir" 2774d9b34d9Smrg dstdir_status=$? 278ddb28773Smrg # Don't chown directories that already exist. 279ddb28773Smrg if test $dstdir_status = 0; then 280ddb28773Smrg chowncmd="" 281ddb28773Smrg fi 2824d9b34d9Smrg else 2834d9b34d9Smrg 284498372abSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2854d9b34d9Smrg # might cause directories to be created, which would be especially bad 286498372abSmrg # if $src (and thus $dsttmp) contains '*'. 287498372abSmrg if test ! -f "$src" && test ! -d "$src"; then 288498372abSmrg echo "$0: $src does not exist." >&2 2894d9b34d9Smrg exit 1 2904d9b34d9Smrg fi 2914d9b34d9Smrg 2928512f934Smrg if test -z "$dst_arg"; then 2934d9b34d9Smrg echo "$0: no destination specified." >&2 2944d9b34d9Smrg exit 1 2954d9b34d9Smrg fi 2968512f934Smrg dst=$dst_arg 2974d9b34d9Smrg 298ddb28773Smrg # If destination is a directory, append the input filename. 2994d9b34d9Smrg if test -d "$dst"; then 30019d64aeeSmrg if test "$is_target_a_directory" = never; then 30119d64aeeSmrg echo "$0: $dst_arg: Is a directory" >&2 30219d64aeeSmrg exit 1 3034d9b34d9Smrg fi 3044d9b34d9Smrg dstdir=$dst 305ddb28773Smrg dstbase=`basename "$src"` 306ddb28773Smrg case $dst in 307ddb28773Smrg */) dst=$dst$dstbase;; 308ddb28773Smrg *) dst=$dst/$dstbase;; 309ddb28773Smrg esac 3104d9b34d9Smrg dstdir_status=0 3114d9b34d9Smrg else 31219d64aeeSmrg dstdir=`dirname "$dst"` 3134d9b34d9Smrg test -d "$dstdir" 3144d9b34d9Smrg dstdir_status=$? 3154d9b34d9Smrg fi 3164d9b34d9Smrg fi 3174d9b34d9Smrg 318ddb28773Smrg case $dstdir in 319ddb28773Smrg */) dstdirslash=$dstdir;; 320ddb28773Smrg *) dstdirslash=$dstdir/;; 321ddb28773Smrg esac 322ddb28773Smrg 3234d9b34d9Smrg obsolete_mkdir_used=false 3244d9b34d9Smrg 3254d9b34d9Smrg if test $dstdir_status != 0; then 3264d9b34d9Smrg case $posix_mkdir in 3274d9b34d9Smrg '') 32819d64aeeSmrg # With -d, create the new directory with the user-specified mode. 32919d64aeeSmrg # Otherwise, rely on $mkdir_umask. 33019d64aeeSmrg if test -n "$dir_arg"; then 33119d64aeeSmrg mkdir_mode=-m$mode 33219d64aeeSmrg else 33319d64aeeSmrg mkdir_mode= 33419d64aeeSmrg fi 33519d64aeeSmrg 33619d64aeeSmrg posix_mkdir=false 337ddb28773Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 338ddb28773Smrg # here however when possible just to lower collision chance. 339ddb28773Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340ddb28773Smrg 341ddb28773Smrg trap ' 342ddb28773Smrg ret=$? 343ddb28773Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344ddb28773Smrg exit $ret 345ddb28773Smrg ' 0 346ddb28773Smrg 347ddb28773Smrg # Because "mkdir -p" follows existing symlinks and we likely work 348ddb28773Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349ddb28773Smrg # directory is successfully created first before we actually test 350ddb28773Smrg # 'mkdir -p'. 351ddb28773Smrg if (umask $mkdir_umask && 352ddb28773Smrg $mkdirprog $mkdir_mode "$tmpdir" && 353ddb28773Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354ddb28773Smrg then 355ddb28773Smrg if test -z "$dir_arg" || { 356ddb28773Smrg # Check for POSIX incompatibilities with -m. 357ddb28773Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358ddb28773Smrg # other-writable bit of parent directory when it shouldn't. 359ddb28773Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360ddb28773Smrg test_tmpdir="$tmpdir/a" 361ddb28773Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362ddb28773Smrg case $ls_ld_tmpdir in 363ddb28773Smrg d????-?r-*) different_mode=700;; 364ddb28773Smrg d????-?--*) different_mode=755;; 365ddb28773Smrg *) false;; 366ddb28773Smrg esac && 367ddb28773Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368ddb28773Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369ddb28773Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370ddb28773Smrg } 371ddb28773Smrg } 372ddb28773Smrg then posix_mkdir=: 373ddb28773Smrg fi 374ddb28773Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375ddb28773Smrg else 376ddb28773Smrg # Remove any dirs left behind by ancient mkdir implementations. 377ddb28773Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378ddb28773Smrg fi 379ddb28773Smrg trap '' 0;; 3804d9b34d9Smrg esac 3814d9b34d9Smrg 3824d9b34d9Smrg if 3834d9b34d9Smrg $posix_mkdir && ( 38419d64aeeSmrg umask $mkdir_umask && 38519d64aeeSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3864d9b34d9Smrg ) 3874d9b34d9Smrg then : 3884d9b34d9Smrg else 3894d9b34d9Smrg 390ddb28773Smrg # mkdir does not conform to POSIX, 3914d9b34d9Smrg # or it failed possibly due to a race condition. Create the 3924d9b34d9Smrg # directory the slow way, step by step, checking for races as we go. 3934d9b34d9Smrg 3944d9b34d9Smrg case $dstdir in 39519d64aeeSmrg /*) prefix='/';; 39619d64aeeSmrg [-=\(\)!]*) prefix='./';; 39719d64aeeSmrg *) prefix='';; 3984d9b34d9Smrg esac 3994d9b34d9Smrg 4004d9b34d9Smrg oIFS=$IFS 4014d9b34d9Smrg IFS=/ 40219d64aeeSmrg set -f 4034d9b34d9Smrg set fnord $dstdir 4044d9b34d9Smrg shift 40519d64aeeSmrg set +f 4064d9b34d9Smrg IFS=$oIFS 4074d9b34d9Smrg 4084d9b34d9Smrg prefixes= 4094d9b34d9Smrg 4104d9b34d9Smrg for d 4114d9b34d9Smrg do 41219d64aeeSmrg test X"$d" = X && continue 41319d64aeeSmrg 41419d64aeeSmrg prefix=$prefix$d 41519d64aeeSmrg if test -d "$prefix"; then 41619d64aeeSmrg prefixes= 41719d64aeeSmrg else 41819d64aeeSmrg if $posix_mkdir; then 419ddb28773Smrg (umask $mkdir_umask && 42019d64aeeSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42119d64aeeSmrg # Don't fail if two instances are running concurrently. 42219d64aeeSmrg test -d "$prefix" || exit 1 42319d64aeeSmrg else 42419d64aeeSmrg case $prefix in 42519d64aeeSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42619d64aeeSmrg *) qprefix=$prefix;; 42719d64aeeSmrg esac 42819d64aeeSmrg prefixes="$prefixes '$qprefix'" 42919d64aeeSmrg fi 43019d64aeeSmrg fi 43119d64aeeSmrg prefix=$prefix/ 4324d9b34d9Smrg done 4334d9b34d9Smrg 4344d9b34d9Smrg if test -n "$prefixes"; then 43519d64aeeSmrg # Don't fail if two instances are running concurrently. 43619d64aeeSmrg (umask $mkdir_umask && 43719d64aeeSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 43819d64aeeSmrg test -d "$dstdir" || exit 1 43919d64aeeSmrg obsolete_mkdir_used=true 4404d9b34d9Smrg fi 4414d9b34d9Smrg fi 4424d9b34d9Smrg fi 4434d9b34d9Smrg 4444d9b34d9Smrg if test -n "$dir_arg"; then 445498372abSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446498372abSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447498372abSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448498372abSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4494d9b34d9Smrg else 4504d9b34d9Smrg 4514d9b34d9Smrg # Make a couple of temp file names in the proper directory. 452ddb28773Smrg dsttmp=${dstdirslash}_inst.$$_ 453ddb28773Smrg rmtmp=${dstdirslash}_rm.$$_ 4544d9b34d9Smrg 4554d9b34d9Smrg # Trap to clean up those temp files at exit. 456498372abSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4574d9b34d9Smrg 4584d9b34d9Smrg # Copy the file name to the temp name. 459ddb28773Smrg (umask $cp_umask && 460ddb28773Smrg { test -z "$stripcmd" || { 461ddb28773Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462ddb28773Smrg # which would cause strip to fail. 463ddb28773Smrg if test -z "$doit"; then 464ddb28773Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 465ddb28773Smrg else 466ddb28773Smrg $doit touch "$dsttmp" 467ddb28773Smrg fi 468ddb28773Smrg } 469ddb28773Smrg } && 470ddb28773Smrg $doit_exec $cpprog "$src" "$dsttmp") && 4714d9b34d9Smrg 4724d9b34d9Smrg # and set any options; do chmod last to preserve setuid bits. 4734d9b34d9Smrg # 4744d9b34d9Smrg # If any of these fail, we abort the whole thing. If we want to 4754d9b34d9Smrg # ignore errors from any of these, just make sure not to ignore 476498372abSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4774d9b34d9Smrg # 478498372abSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479498372abSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480498372abSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481498372abSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4828512f934Smrg 4838512f934Smrg # If -C, don't bother to copy if it wouldn't change the file. 4848512f934Smrg if $copy_on_change && 48519d64aeeSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48619d64aeeSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48719d64aeeSmrg set -f && 488498372abSmrg set X $old && old=:$2:$4:$5:$6 && 489498372abSmrg set X $new && new=:$2:$4:$5:$6 && 49019d64aeeSmrg set +f && 491498372abSmrg test "$old" = "$new" && 492498372abSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4938512f934Smrg then 4948512f934Smrg rm -f "$dsttmp" 4958512f934Smrg else 496ddb28773Smrg # If $backupsuffix is set, and the file being installed 497ddb28773Smrg # already exists, attempt a backup. Don't worry if it fails, 498ddb28773Smrg # e.g., if mv doesn't support -f. 499ddb28773Smrg if test -n "$backupsuffix" && test -f "$dst"; then 500ddb28773Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501ddb28773Smrg fi 502ddb28773Smrg 5038512f934Smrg # Rename the file to the real destination. 504498372abSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5058512f934Smrg 5068512f934Smrg # The rename failed, perhaps because mv can't rename something else 5078512f934Smrg # to itself, or perhaps because mv is so ancient that it does not 5088512f934Smrg # support -f. 5098512f934Smrg { 51019d64aeeSmrg # Now remove or move aside any old file at destination location. 51119d64aeeSmrg # We try this two ways since rm can't unlink itself on some 51219d64aeeSmrg # systems and the destination file might be busy for other 51319d64aeeSmrg # reasons. In this case, the final cleanup might fail but the new 51419d64aeeSmrg # file should still install successfully. 51519d64aeeSmrg { 51619d64aeeSmrg test ! -f "$dst" || 517ddb28773Smrg $doit $rmcmd "$dst" 2>/dev/null || 51819d64aeeSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519ddb28773Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52019d64aeeSmrg } || 52119d64aeeSmrg { echo "$0: cannot unlink or rename $dst" >&2 52219d64aeeSmrg (exit 1); exit 1 52319d64aeeSmrg } 52419d64aeeSmrg } && 52519d64aeeSmrg 52619d64aeeSmrg # Now rename the file to the real destination. 52719d64aeeSmrg $doit $mvcmd "$dsttmp" "$dst" 5288512f934Smrg } 5298512f934Smrg fi || exit 1 5304d9b34d9Smrg 5314d9b34d9Smrg trap '' 0 5324d9b34d9Smrg fi 5334d9b34d9Smrgdone 5344d9b34d9Smrg 5354d9b34d9Smrg# Local variables: 536ddb28773Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 5374d9b34d9Smrg# time-stamp-start: "scriptversion=" 5384d9b34d9Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539ddb28773Smrg# time-stamp-time-zone: "UTC0" 5408512f934Smrg# time-stamp-end: "; # UTC" 5414d9b34d9Smrg# End: 542