install-sh revision 25dbecb6
16df26cacSmrg#!/bin/sh 26df26cacSmrg# install - install a program, script, or datafile 36df26cacSmrg 425dbecb6Smrgscriptversion=2020-11-14.01; # UTC 56df26cacSmrg 66df26cacSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 76df26cacSmrg# later released in X11R6 (xc/config/util/install.sh) with the 86df26cacSmrg# following copyright and license. 96df26cacSmrg# 106df26cacSmrg# Copyright (C) 1994 X Consortium 116df26cacSmrg# 126df26cacSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 136df26cacSmrg# of this software and associated documentation files (the "Software"), to 146df26cacSmrg# deal in the Software without restriction, including without limitation the 156df26cacSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 166df26cacSmrg# sell copies of the Software, and to permit persons to whom the Software is 176df26cacSmrg# furnished to do so, subject to the following conditions: 186df26cacSmrg# 196df26cacSmrg# The above copyright notice and this permission notice shall be included in 206df26cacSmrg# all copies or substantial portions of the Software. 216df26cacSmrg# 226df26cacSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 236df26cacSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 246df26cacSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 256df26cacSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 266df26cacSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 276df26cacSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 286df26cacSmrg# 296df26cacSmrg# Except as contained in this notice, the name of the X Consortium shall not 306df26cacSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 316df26cacSmrg# ings in this Software without prior written authorization from the X Consor- 326df26cacSmrg# tium. 336df26cacSmrg# 346df26cacSmrg# 356df26cacSmrg# FSF changes to this file are in the public domain. 366df26cacSmrg# 376df26cacSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3825dbecb6Smrg# 'make' implicit rules from creating a file called install from it 396df26cacSmrg# when there is no Makefile. 406df26cacSmrg# 416df26cacSmrg# This script is compatible with the BSD install script, but was written 42b68e1f86Smrg# from scratch. 43b68e1f86Smrg 4425dbecb6Smrgtab=' ' 45b68e1f86Smrgnl=' 46b68e1f86Smrg' 4725dbecb6SmrgIFS=" $tab$nl" 486df26cacSmrg 4925dbecb6Smrg# Set DOITPROG to "echo" to test this script. 506df26cacSmrg 51b68e1f86Smrgdoit=${DOITPROG-} 5225dbecb6Smrgdoit_exec=${doit:-exec} 536df26cacSmrg 54b68e1f86Smrg# Put in absolute file names if you don't have them in your path; 55b68e1f86Smrg# or use environment vars. 56b68e1f86Smrg 57b68e1f86Smrgchgrpprog=${CHGRPPROG-chgrp} 58b68e1f86Smrgchmodprog=${CHMODPROG-chmod} 59b68e1f86Smrgchownprog=${CHOWNPROG-chown} 60b68e1f86Smrgcmpprog=${CMPPROG-cmp} 61b68e1f86Smrgcpprog=${CPPROG-cp} 62b68e1f86Smrgmkdirprog=${MKDIRPROG-mkdir} 63b68e1f86Smrgmvprog=${MVPROG-mv} 64b68e1f86Smrgrmprog=${RMPROG-rm} 65b68e1f86Smrgstripprog=${STRIPPROG-strip} 66b68e1f86Smrg 67b68e1f86Smrgposix_mkdir= 68b68e1f86Smrg 69b68e1f86Smrg# Desired mode of installed file. 70b68e1f86Smrgmode=0755 716df26cacSmrg 7225dbecb6Smrg# Create dirs (including intermediate dirs) using mode 755. 7325dbecb6Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 7425dbecb6Smrgmkdir_umask=22 7525dbecb6Smrg 7625dbecb6Smrgbackupsuffix= 776df26cacSmrgchgrpcmd= 78b68e1f86Smrgchmodcmd=$chmodprog 79b68e1f86Smrgchowncmd= 80b68e1f86Smrgmvcmd=$mvprog 816df26cacSmrgrmcmd="$rmprog -f" 82b68e1f86Smrgstripcmd= 83b68e1f86Smrg 846df26cacSmrgsrc= 856df26cacSmrgdst= 866df26cacSmrgdir_arg= 87b68e1f86Smrgdst_arg= 88b68e1f86Smrg 89b68e1f86Smrgcopy_on_change=false 9025dbecb6Smrgis_target_a_directory=possibly 916df26cacSmrg 92b68e1f86Smrgusage="\ 93b68e1f86SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 946df26cacSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 956df26cacSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 966df26cacSmrg or: $0 [OPTION]... -d DIRECTORIES... 976df26cacSmrg 986df26cacSmrgIn the 1st form, copy SRCFILE to DSTFILE. 996df26cacSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1006df26cacSmrgIn the 4th, create DIRECTORIES. 1016df26cacSmrg 1026df26cacSmrgOptions: 103b68e1f86Smrg --help display this help and exit. 104b68e1f86Smrg --version display version info and exit. 105b68e1f86Smrg 106b68e1f86Smrg -c (ignored) 10725dbecb6Smrg -C install only if different (preserve data modification time) 108b68e1f86Smrg -d create directories instead of installing files. 109b68e1f86Smrg -g GROUP $chgrpprog installed files to GROUP. 110b68e1f86Smrg -m MODE $chmodprog installed files to MODE. 111b68e1f86Smrg -o USER $chownprog installed files to USER. 11225dbecb6Smrg -p pass -p to $cpprog. 113b68e1f86Smrg -s $stripprog installed files. 11425dbecb6Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115b68e1f86Smrg -t DIRECTORY install into DIRECTORY. 116b68e1f86Smrg -T report an error if DSTFILE is a directory. 1176df26cacSmrg 1186df26cacSmrgEnvironment variables override the default commands: 119b68e1f86Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120b68e1f86Smrg RMPROG STRIPPROG 12125dbecb6Smrg 12225dbecb6SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 12325dbecb6Smrgit's up to you to specify -f if you want it. 12425dbecb6Smrg 12525dbecb6SmrgIf -S is not specified, no backups are attempted. 12625dbecb6Smrg 12725dbecb6SmrgEmail bug reports to bug-automake@gnu.org. 12825dbecb6SmrgAutomake home page: https://www.gnu.org/software/automake/ 1296df26cacSmrg" 1306df26cacSmrg 131b68e1f86Smrgwhile test $# -ne 0; do 1326df26cacSmrg case $1 in 133b68e1f86Smrg -c) ;; 134b68e1f86Smrg 135b68e1f86Smrg -C) copy_on_change=true;; 1366df26cacSmrg 137b68e1f86Smrg -d) dir_arg=true;; 1386df26cacSmrg 1396df26cacSmrg -g) chgrpcmd="$chgrpprog $2" 14025dbecb6Smrg shift;; 1416df26cacSmrg 1426df26cacSmrg --help) echo "$usage"; exit $?;; 1436df26cacSmrg 144b68e1f86Smrg -m) mode=$2 14525dbecb6Smrg case $mode in 14625dbecb6Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14725dbecb6Smrg echo "$0: invalid mode: $mode" >&2 14825dbecb6Smrg exit 1;; 14925dbecb6Smrg esac 15025dbecb6Smrg shift;; 1516df26cacSmrg 1526df26cacSmrg -o) chowncmd="$chownprog $2" 15325dbecb6Smrg shift;; 15425dbecb6Smrg 15525dbecb6Smrg -p) cpprog="$cpprog -p";; 1566df26cacSmrg 157b68e1f86Smrg -s) stripcmd=$stripprog;; 1586df26cacSmrg 15925dbecb6Smrg -S) backupsuffix="$2" 16025dbecb6Smrg shift;; 16125dbecb6Smrg 16225dbecb6Smrg -t) 16325dbecb6Smrg is_target_a_directory=always 16425dbecb6Smrg dst_arg=$2 16525dbecb6Smrg # Protect names problematic for 'test' and other utilities. 16625dbecb6Smrg case $dst_arg in 16725dbecb6Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16825dbecb6Smrg esac 16925dbecb6Smrg shift;; 1706df26cacSmrg 17125dbecb6Smrg -T) is_target_a_directory=never;; 1726df26cacSmrg 1736df26cacSmrg --version) echo "$0 $scriptversion"; exit $?;; 1746df26cacSmrg 17525dbecb6Smrg --) shift 17625dbecb6Smrg break;; 177b68e1f86Smrg 17825dbecb6Smrg -*) echo "$0: invalid option: $1" >&2 17925dbecb6Smrg exit 1;; 180b68e1f86Smrg 181b68e1f86Smrg *) break;; 1826df26cacSmrg esac 183b68e1f86Smrg shift 1846df26cacSmrgdone 1856df26cacSmrg 18625dbecb6Smrg# We allow the use of options -d and -T together, by making -d 18725dbecb6Smrg# take the precedence; this is for compatibility with GNU install. 18825dbecb6Smrg 18925dbecb6Smrgif test -n "$dir_arg"; then 19025dbecb6Smrg if test -n "$dst_arg"; then 19125dbecb6Smrg echo "$0: target directory not allowed when installing a directory." >&2 19225dbecb6Smrg exit 1 19325dbecb6Smrg fi 19425dbecb6Smrgfi 19525dbecb6Smrg 196b68e1f86Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197b68e1f86Smrg # When -d is used, all remaining arguments are directories to create. 198b68e1f86Smrg # When -t is used, the destination is already specified. 199b68e1f86Smrg # Otherwise, the last argument is the destination. Remove it from $@. 200b68e1f86Smrg for arg 201b68e1f86Smrg do 202b68e1f86Smrg if test -n "$dst_arg"; then 203b68e1f86Smrg # $@ is not empty: it contains at least $arg. 204b68e1f86Smrg set fnord "$@" "$dst_arg" 205b68e1f86Smrg shift # fnord 206b68e1f86Smrg fi 207b68e1f86Smrg shift # arg 208b68e1f86Smrg dst_arg=$arg 20925dbecb6Smrg # Protect names problematic for 'test' and other utilities. 21025dbecb6Smrg case $dst_arg in 21125dbecb6Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21225dbecb6Smrg esac 213b68e1f86Smrg done 214b68e1f86Smrgfi 215b68e1f86Smrg 216b68e1f86Smrgif test $# -eq 0; then 2176df26cacSmrg if test -z "$dir_arg"; then 2186df26cacSmrg echo "$0: no input file specified." >&2 2196df26cacSmrg exit 1 2206df26cacSmrg fi 22125dbecb6Smrg # It's OK to call 'install-sh -d' without argument. 2226df26cacSmrg # This can happen when creating conditional directories. 2236df26cacSmrg exit 0 2246df26cacSmrgfi 2256df26cacSmrg 226b68e1f86Smrgif test -z "$dir_arg"; then 22725dbecb6Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22825dbecb6Smrg if test ! -d "$dst_arg"; then 22925dbecb6Smrg echo "$0: $dst_arg: Is not a directory." >&2 23025dbecb6Smrg exit 1 23125dbecb6Smrg fi 23225dbecb6Smrg fi 23325dbecb6Smrgfi 23425dbecb6Smrg 23525dbecb6Smrgif test -z "$dir_arg"; then 23625dbecb6Smrg do_exit='(exit $ret); exit $ret' 23725dbecb6Smrg trap "ret=129; $do_exit" 1 23825dbecb6Smrg trap "ret=130; $do_exit" 2 23925dbecb6Smrg trap "ret=141; $do_exit" 13 24025dbecb6Smrg trap "ret=143; $do_exit" 15 241b68e1f86Smrg 242b68e1f86Smrg # Set umask so as not to create temps with too-generous modes. 243b68e1f86Smrg # However, 'strip' requires both read and write access to temps. 244b68e1f86Smrg case $mode in 245b68e1f86Smrg # Optimize common cases. 246b68e1f86Smrg *644) cp_umask=133;; 247b68e1f86Smrg *755) cp_umask=22;; 248b68e1f86Smrg 249b68e1f86Smrg *[0-7]) 250b68e1f86Smrg if test -z "$stripcmd"; then 25125dbecb6Smrg u_plus_rw= 252b68e1f86Smrg else 25325dbecb6Smrg u_plus_rw='% 200' 254b68e1f86Smrg fi 255b68e1f86Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256b68e1f86Smrg *) 257b68e1f86Smrg if test -z "$stripcmd"; then 25825dbecb6Smrg u_plus_rw= 259b68e1f86Smrg else 26025dbecb6Smrg u_plus_rw=,u+rw 261b68e1f86Smrg fi 262b68e1f86Smrg cp_umask=$mode$u_plus_rw;; 263b68e1f86Smrg esac 264b68e1f86Smrgfi 265b68e1f86Smrg 2666df26cacSmrgfor src 2676df26cacSmrgdo 26825dbecb6Smrg # Protect names problematic for 'test' and other utilities. 2696df26cacSmrg case $src in 27025dbecb6Smrg -* | [=\(\)!]) src=./$src;; 2716df26cacSmrg esac 2726df26cacSmrg 2736df26cacSmrg if test -n "$dir_arg"; then 2746df26cacSmrg dst=$src 275b68e1f86Smrg dstdir=$dst 276b68e1f86Smrg test -d "$dstdir" 277b68e1f86Smrg dstdir_status=$? 27825dbecb6Smrg # Don't chown directories that already exist. 27925dbecb6Smrg if test $dstdir_status = 0; then 28025dbecb6Smrg chowncmd="" 28125dbecb6Smrg fi 28216fd1166Smrg else 283b68e1f86Smrg 2846df26cacSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2856df26cacSmrg # might cause directories to be created, which would be especially bad 2866df26cacSmrg # if $src (and thus $dsttmp) contains '*'. 2876df26cacSmrg if test ! -f "$src" && test ! -d "$src"; then 2886df26cacSmrg echo "$0: $src does not exist." >&2 2896df26cacSmrg exit 1 2906df26cacSmrg fi 2916df26cacSmrg 292b68e1f86Smrg if test -z "$dst_arg"; then 2936df26cacSmrg echo "$0: no destination specified." >&2 2946df26cacSmrg exit 1 2956df26cacSmrg fi 296b68e1f86Smrg dst=$dst_arg 2976df26cacSmrg 29825dbecb6Smrg # If destination is a directory, append the input filename. 2996df26cacSmrg if test -d "$dst"; then 30025dbecb6Smrg if test "$is_target_a_directory" = never; then 30125dbecb6Smrg echo "$0: $dst_arg: Is a directory" >&2 30225dbecb6Smrg exit 1 3036df26cacSmrg fi 304b68e1f86Smrg dstdir=$dst 30525dbecb6Smrg dstbase=`basename "$src"` 30625dbecb6Smrg case $dst in 30725dbecb6Smrg */) dst=$dst$dstbase;; 30825dbecb6Smrg *) dst=$dst/$dstbase;; 30925dbecb6Smrg esac 310b68e1f86Smrg dstdir_status=0 311b68e1f86Smrg else 31225dbecb6Smrg dstdir=`dirname "$dst"` 313b68e1f86Smrg test -d "$dstdir" 314b68e1f86Smrg dstdir_status=$? 3156df26cacSmrg fi 3166df26cacSmrg fi 3176df26cacSmrg 31825dbecb6Smrg case $dstdir in 31925dbecb6Smrg */) dstdirslash=$dstdir;; 32025dbecb6Smrg *) dstdirslash=$dstdir/;; 32125dbecb6Smrg esac 32225dbecb6Smrg 323b68e1f86Smrg obsolete_mkdir_used=false 324b68e1f86Smrg 325b68e1f86Smrg if test $dstdir_status != 0; then 326b68e1f86Smrg case $posix_mkdir in 327b68e1f86Smrg '') 32825dbecb6Smrg # With -d, create the new directory with the user-specified mode. 32925dbecb6Smrg # Otherwise, rely on $mkdir_umask. 33025dbecb6Smrg if test -n "$dir_arg"; then 33125dbecb6Smrg mkdir_mode=-m$mode 33225dbecb6Smrg else 33325dbecb6Smrg mkdir_mode= 33425dbecb6Smrg fi 33525dbecb6Smrg 33625dbecb6Smrg posix_mkdir=false 33725dbecb6Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 33825dbecb6Smrg # here however when possible just to lower collision chance. 33925dbecb6Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34025dbecb6Smrg 34125dbecb6Smrg trap ' 34225dbecb6Smrg ret=$? 34325dbecb6Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 34425dbecb6Smrg exit $ret 34525dbecb6Smrg ' 0 34625dbecb6Smrg 34725dbecb6Smrg # Because "mkdir -p" follows existing symlinks and we likely work 34825dbecb6Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 34925dbecb6Smrg # directory is successfully created first before we actually test 35025dbecb6Smrg # 'mkdir -p'. 35125dbecb6Smrg if (umask $mkdir_umask && 35225dbecb6Smrg $mkdirprog $mkdir_mode "$tmpdir" && 35325dbecb6Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 35425dbecb6Smrg then 35525dbecb6Smrg if test -z "$dir_arg" || { 35625dbecb6Smrg # Check for POSIX incompatibilities with -m. 35725dbecb6Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35825dbecb6Smrg # other-writable bit of parent directory when it shouldn't. 35925dbecb6Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 36025dbecb6Smrg test_tmpdir="$tmpdir/a" 36125dbecb6Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 36225dbecb6Smrg case $ls_ld_tmpdir in 36325dbecb6Smrg d????-?r-*) different_mode=700;; 36425dbecb6Smrg d????-?--*) different_mode=755;; 36525dbecb6Smrg *) false;; 36625dbecb6Smrg esac && 36725dbecb6Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 36825dbecb6Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36925dbecb6Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 37025dbecb6Smrg } 37125dbecb6Smrg } 37225dbecb6Smrg then posix_mkdir=: 37325dbecb6Smrg fi 37425dbecb6Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375b68e1f86Smrg else 37625dbecb6Smrg # Remove any dirs left behind by ancient mkdir implementations. 37725dbecb6Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378b68e1f86Smrg fi 37925dbecb6Smrg trap '' 0;; 380b68e1f86Smrg esac 3816df26cacSmrg 382b68e1f86Smrg if 383b68e1f86Smrg $posix_mkdir && ( 38425dbecb6Smrg umask $mkdir_umask && 38525dbecb6Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386b68e1f86Smrg ) 387b68e1f86Smrg then : 388b68e1f86Smrg else 38916fd1166Smrg 39025dbecb6Smrg # mkdir does not conform to POSIX, 391b68e1f86Smrg # or it failed possibly due to a race condition. Create the 392b68e1f86Smrg # directory the slow way, step by step, checking for races as we go. 3936df26cacSmrg 394b68e1f86Smrg case $dstdir in 39525dbecb6Smrg /*) prefix='/';; 39625dbecb6Smrg [-=\(\)!]*) prefix='./';; 39725dbecb6Smrg *) prefix='';; 398b68e1f86Smrg esac 39916fd1166Smrg 400b68e1f86Smrg oIFS=$IFS 401b68e1f86Smrg IFS=/ 40225dbecb6Smrg set -f 403b68e1f86Smrg set fnord $dstdir 4046df26cacSmrg shift 40525dbecb6Smrg set +f 406b68e1f86Smrg IFS=$oIFS 407b68e1f86Smrg 408b68e1f86Smrg prefixes= 409b68e1f86Smrg 410b68e1f86Smrg for d 411b68e1f86Smrg do 41225dbecb6Smrg test X"$d" = X && continue 41325dbecb6Smrg 41425dbecb6Smrg prefix=$prefix$d 41525dbecb6Smrg if test -d "$prefix"; then 41625dbecb6Smrg prefixes= 41725dbecb6Smrg else 41825dbecb6Smrg if $posix_mkdir; then 41925dbecb6Smrg (umask $mkdir_umask && 42025dbecb6Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42125dbecb6Smrg # Don't fail if two instances are running concurrently. 42225dbecb6Smrg test -d "$prefix" || exit 1 42325dbecb6Smrg else 42425dbecb6Smrg case $prefix in 42525dbecb6Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42625dbecb6Smrg *) qprefix=$prefix;; 42725dbecb6Smrg esac 42825dbecb6Smrg prefixes="$prefixes '$qprefix'" 42925dbecb6Smrg fi 43025dbecb6Smrg fi 43125dbecb6Smrg prefix=$prefix/ 432b68e1f86Smrg done 433b68e1f86Smrg 434b68e1f86Smrg if test -n "$prefixes"; then 43525dbecb6Smrg # Don't fail if two instances are running concurrently. 43625dbecb6Smrg (umask $mkdir_umask && 43725dbecb6Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 43825dbecb6Smrg test -d "$dstdir" || exit 1 43925dbecb6Smrg obsolete_mkdir_used=true 4406df26cacSmrg fi 441b68e1f86Smrg fi 4426df26cacSmrg fi 4436df26cacSmrg 4446df26cacSmrg if test -n "$dir_arg"; then 445b68e1f86Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446b68e1f86Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447b68e1f86Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448b68e1f86Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4496df26cacSmrg else 4506df26cacSmrg 4516df26cacSmrg # Make a couple of temp file names in the proper directory. 45225dbecb6Smrg dsttmp=${dstdirslash}_inst.$$_ 45325dbecb6Smrg rmtmp=${dstdirslash}_rm.$$_ 4546df26cacSmrg 4556df26cacSmrg # Trap to clean up those temp files at exit. 4566df26cacSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4576df26cacSmrg 4586df26cacSmrg # Copy the file name to the temp name. 45925dbecb6Smrg (umask $cp_umask && 46025dbecb6Smrg { test -z "$stripcmd" || { 46125dbecb6Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 46225dbecb6Smrg # which would cause strip to fail. 46325dbecb6Smrg if test -z "$doit"; then 46425dbecb6Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 46525dbecb6Smrg else 46625dbecb6Smrg $doit touch "$dsttmp" 46725dbecb6Smrg fi 46825dbecb6Smrg } 46925dbecb6Smrg } && 47025dbecb6Smrg $doit_exec $cpprog "$src" "$dsttmp") && 4716df26cacSmrg 4726df26cacSmrg # and set any options; do chmod last to preserve setuid bits. 4736df26cacSmrg # 4746df26cacSmrg # If any of these fail, we abort the whole thing. If we want to 4756df26cacSmrg # ignore errors from any of these, just make sure not to ignore 4766df26cacSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4776df26cacSmrg # 478b68e1f86Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479b68e1f86Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480b68e1f86Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481b68e1f86Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482b68e1f86Smrg 483b68e1f86Smrg # If -C, don't bother to copy if it wouldn't change the file. 484b68e1f86Smrg if $copy_on_change && 48525dbecb6Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48625dbecb6Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48725dbecb6Smrg set -f && 488b68e1f86Smrg set X $old && old=:$2:$4:$5:$6 && 489b68e1f86Smrg set X $new && new=:$2:$4:$5:$6 && 49025dbecb6Smrg set +f && 491b68e1f86Smrg test "$old" = "$new" && 492b68e1f86Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493b68e1f86Smrg then 494b68e1f86Smrg rm -f "$dsttmp" 495b68e1f86Smrg else 49625dbecb6Smrg # If $backupsuffix is set, and the file being installed 49725dbecb6Smrg # already exists, attempt a backup. Don't worry if it fails, 49825dbecb6Smrg # e.g., if mv doesn't support -f. 49925dbecb6Smrg if test -n "$backupsuffix" && test -f "$dst"; then 50025dbecb6Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 50125dbecb6Smrg fi 50225dbecb6Smrg 503b68e1f86Smrg # Rename the file to the real destination. 504b68e1f86Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505b68e1f86Smrg 506b68e1f86Smrg # The rename failed, perhaps because mv can't rename something else 507b68e1f86Smrg # to itself, or perhaps because mv is so ancient that it does not 508b68e1f86Smrg # support -f. 509b68e1f86Smrg { 51025dbecb6Smrg # Now remove or move aside any old file at destination location. 51125dbecb6Smrg # We try this two ways since rm can't unlink itself on some 51225dbecb6Smrg # systems and the destination file might be busy for other 51325dbecb6Smrg # reasons. In this case, the final cleanup might fail but the new 51425dbecb6Smrg # file should still install successfully. 51525dbecb6Smrg { 51625dbecb6Smrg test ! -f "$dst" || 51725dbecb6Smrg $doit $rmcmd "$dst" 2>/dev/null || 51825dbecb6Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 51925dbecb6Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52025dbecb6Smrg } || 52125dbecb6Smrg { echo "$0: cannot unlink or rename $dst" >&2 52225dbecb6Smrg (exit 1); exit 1 52325dbecb6Smrg } 52425dbecb6Smrg } && 52525dbecb6Smrg 52625dbecb6Smrg # Now rename the file to the real destination. 52725dbecb6Smrg $doit $mvcmd "$dsttmp" "$dst" 528b68e1f86Smrg } 529b68e1f86Smrg fi || exit 1 530b68e1f86Smrg 531b68e1f86Smrg trap '' 0 532b68e1f86Smrg fi 5336df26cacSmrgdone 5346df26cacSmrg 5356df26cacSmrg# Local variables: 53625dbecb6Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 5376df26cacSmrg# time-stamp-start: "scriptversion=" 5386df26cacSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 53925dbecb6Smrg# time-stamp-time-zone: "UTC0" 54025dbecb6Smrg# time-stamp-end: "; # UTC" 5416df26cacSmrg# End: 542