install-sh revision 15adf0bf
1dcae5b9eSmrg#!/bin/sh 2dcae5b9eSmrg# install - install a program, script, or datafile 35b28e182Smrg 415adf0bfSmrgscriptversion=2020-11-14.01; # UTC 55b28e182Smrg 6dcae5b9eSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7dcae5b9eSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8dcae5b9eSmrg# following copyright and license. 9dcae5b9eSmrg# 10dcae5b9eSmrg# Copyright (C) 1994 X Consortium 11dcae5b9eSmrg# 12dcae5b9eSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13dcae5b9eSmrg# of this software and associated documentation files (the "Software"), to 14dcae5b9eSmrg# deal in the Software without restriction, including without limitation the 15dcae5b9eSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16dcae5b9eSmrg# sell copies of the Software, and to permit persons to whom the Software is 17dcae5b9eSmrg# furnished to do so, subject to the following conditions: 18dcae5b9eSmrg# 19dcae5b9eSmrg# The above copyright notice and this permission notice shall be included in 20dcae5b9eSmrg# all copies or substantial portions of the Software. 21dcae5b9eSmrg# 22dcae5b9eSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23dcae5b9eSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24dcae5b9eSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25dcae5b9eSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26dcae5b9eSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27dcae5b9eSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28dcae5b9eSmrg# 29dcae5b9eSmrg# Except as contained in this notice, the name of the X Consortium shall not 30dcae5b9eSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31dcae5b9eSmrg# ings in this Software without prior written authorization from the X Consor- 32dcae5b9eSmrg# tium. 33dcae5b9eSmrg# 34dcae5b9eSmrg# 35dcae5b9eSmrg# FSF changes to this file are in the public domain. 36dcae5b9eSmrg# 37dcae5b9eSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3815adf0bfSmrg# 'make' implicit rules from creating a file called install from it 39dcae5b9eSmrg# when there is no Makefile. 40dcae5b9eSmrg# 41dcae5b9eSmrg# This script is compatible with the BSD install script, but was written 425b28e182Smrg# from scratch. 43dcae5b9eSmrg 4415adf0bfSmrgtab=' ' 455b28e182Smrgnl=' 465b28e182Smrg' 4715adf0bfSmrgIFS=" $tab$nl" 48dcae5b9eSmrg 4915adf0bfSmrg# Set DOITPROG to "echo" to test this script. 50dcae5b9eSmrg 515b28e182Smrgdoit=${DOITPROG-} 5215adf0bfSmrgdoit_exec=${doit:-exec} 53dcae5b9eSmrg 545b28e182Smrg# Put in absolute file names if you don't have them in your path; 555b28e182Smrg# or use environment vars. 565b28e182Smrg 575b28e182Smrgchgrpprog=${CHGRPPROG-chgrp} 585b28e182Smrgchmodprog=${CHMODPROG-chmod} 595b28e182Smrgchownprog=${CHOWNPROG-chown} 605b28e182Smrgcmpprog=${CMPPROG-cmp} 615b28e182Smrgcpprog=${CPPROG-cp} 625b28e182Smrgmkdirprog=${MKDIRPROG-mkdir} 635b28e182Smrgmvprog=${MVPROG-mv} 645b28e182Smrgrmprog=${RMPROG-rm} 655b28e182Smrgstripprog=${STRIPPROG-strip} 665b28e182Smrg 675b28e182Smrgposix_mkdir= 685b28e182Smrg 695b28e182Smrg# Desired mode of installed file. 705b28e182Smrgmode=0755 715b28e182Smrg 7215adf0bfSmrg# Create dirs (including intermediate dirs) using mode 755. 7315adf0bfSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 7415adf0bfSmrgmkdir_umask=22 7515adf0bfSmrg 7615adf0bfSmrgbackupsuffix= 775b28e182Smrgchgrpcmd= 785b28e182Smrgchmodcmd=$chmodprog 795b28e182Smrgchowncmd= 805b28e182Smrgmvcmd=$mvprog 815b28e182Smrgrmcmd="$rmprog -f" 825b28e182Smrgstripcmd= 83dcae5b9eSmrg 845b28e182Smrgsrc= 855b28e182Smrgdst= 865b28e182Smrgdir_arg= 875b28e182Smrgdst_arg= 88dcae5b9eSmrg 895b28e182Smrgcopy_on_change=false 9015adf0bfSmrgis_target_a_directory=possibly 91dcae5b9eSmrg 925b28e182Smrgusage="\ 935b28e182SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 945b28e182Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 955b28e182Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 965b28e182Smrg or: $0 [OPTION]... -d DIRECTORIES... 97dcae5b9eSmrg 985b28e182SmrgIn the 1st form, copy SRCFILE to DSTFILE. 995b28e182SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1005b28e182SmrgIn the 4th, create DIRECTORIES. 101dcae5b9eSmrg 1025b28e182SmrgOptions: 1035b28e182Smrg --help display this help and exit. 1045b28e182Smrg --version display version info and exit. 105dcae5b9eSmrg 1065b28e182Smrg -c (ignored) 10715adf0bfSmrg -C install only if different (preserve data modification time) 1085b28e182Smrg -d create directories instead of installing files. 1095b28e182Smrg -g GROUP $chgrpprog installed files to GROUP. 1105b28e182Smrg -m MODE $chmodprog installed files to MODE. 1115b28e182Smrg -o USER $chownprog installed files to USER. 11215adf0bfSmrg -p pass -p to $cpprog. 1135b28e182Smrg -s $stripprog installed files. 11415adf0bfSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1155b28e182Smrg -t DIRECTORY install into DIRECTORY. 1165b28e182Smrg -T report an error if DSTFILE is a directory. 117dcae5b9eSmrg 1185b28e182SmrgEnvironment variables override the default commands: 1195b28e182Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1205b28e182Smrg RMPROG STRIPPROG 12115adf0bfSmrg 12215adf0bfSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 12315adf0bfSmrgit's up to you to specify -f if you want it. 12415adf0bfSmrg 12515adf0bfSmrgIf -S is not specified, no backups are attempted. 12615adf0bfSmrg 12715adf0bfSmrgEmail bug reports to bug-automake@gnu.org. 12815adf0bfSmrgAutomake home page: https://www.gnu.org/software/automake/ 1295b28e182Smrg" 130dcae5b9eSmrg 1315b28e182Smrgwhile test $# -ne 0; do 1325b28e182Smrg case $1 in 1335b28e182Smrg -c) ;; 134dcae5b9eSmrg 1355b28e182Smrg -C) copy_on_change=true;; 136dcae5b9eSmrg 1375b28e182Smrg -d) dir_arg=true;; 138dcae5b9eSmrg 1395b28e182Smrg -g) chgrpcmd="$chgrpprog $2" 14015adf0bfSmrg shift;; 141dcae5b9eSmrg 1425b28e182Smrg --help) echo "$usage"; exit $?;; 143dcae5b9eSmrg 1445b28e182Smrg -m) mode=$2 14515adf0bfSmrg case $mode in 14615adf0bfSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14715adf0bfSmrg echo "$0: invalid mode: $mode" >&2 14815adf0bfSmrg exit 1;; 14915adf0bfSmrg esac 15015adf0bfSmrg shift;; 151dcae5b9eSmrg 1525b28e182Smrg -o) chowncmd="$chownprog $2" 15315adf0bfSmrg shift;; 15415adf0bfSmrg 15515adf0bfSmrg -p) cpprog="$cpprog -p";; 156dcae5b9eSmrg 1575b28e182Smrg -s) stripcmd=$stripprog;; 158dcae5b9eSmrg 15915adf0bfSmrg -S) backupsuffix="$2" 16015adf0bfSmrg shift;; 16115adf0bfSmrg 16215adf0bfSmrg -t) 16315adf0bfSmrg is_target_a_directory=always 16415adf0bfSmrg dst_arg=$2 16515adf0bfSmrg # Protect names problematic for 'test' and other utilities. 16615adf0bfSmrg case $dst_arg in 16715adf0bfSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16815adf0bfSmrg esac 16915adf0bfSmrg shift;; 170dcae5b9eSmrg 17115adf0bfSmrg -T) is_target_a_directory=never;; 172dcae5b9eSmrg 1735b28e182Smrg --version) echo "$0 $scriptversion"; exit $?;; 174dcae5b9eSmrg 17515adf0bfSmrg --) shift 17615adf0bfSmrg break;; 177dcae5b9eSmrg 17815adf0bfSmrg -*) echo "$0: invalid option: $1" >&2 17915adf0bfSmrg exit 1;; 180dcae5b9eSmrg 1815b28e182Smrg *) break;; 1825b28e182Smrg esac 1835b28e182Smrg shift 1845b28e182Smrgdone 185dcae5b9eSmrg 18615adf0bfSmrg# We allow the use of options -d and -T together, by making -d 18715adf0bfSmrg# take the precedence; this is for compatibility with GNU install. 18815adf0bfSmrg 18915adf0bfSmrgif test -n "$dir_arg"; then 19015adf0bfSmrg if test -n "$dst_arg"; then 19115adf0bfSmrg echo "$0: target directory not allowed when installing a directory." >&2 19215adf0bfSmrg exit 1 19315adf0bfSmrg fi 19415adf0bfSmrgfi 19515adf0bfSmrg 1965b28e182Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1975b28e182Smrg # When -d is used, all remaining arguments are directories to create. 1985b28e182Smrg # When -t is used, the destination is already specified. 1995b28e182Smrg # Otherwise, the last argument is the destination. Remove it from $@. 2005b28e182Smrg for arg 2015b28e182Smrg do 2025b28e182Smrg if test -n "$dst_arg"; then 2035b28e182Smrg # $@ is not empty: it contains at least $arg. 2045b28e182Smrg set fnord "$@" "$dst_arg" 2055b28e182Smrg shift # fnord 2065b28e182Smrg fi 2075b28e182Smrg shift # arg 2085b28e182Smrg dst_arg=$arg 20915adf0bfSmrg # Protect names problematic for 'test' and other utilities. 21015adf0bfSmrg case $dst_arg in 21115adf0bfSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21215adf0bfSmrg esac 2135b28e182Smrg done 2145b28e182Smrgfi 215dcae5b9eSmrg 2165b28e182Smrgif test $# -eq 0; then 2175b28e182Smrg if test -z "$dir_arg"; then 2185b28e182Smrg echo "$0: no input file specified." >&2 2195b28e182Smrg exit 1 2205b28e182Smrg fi 22115adf0bfSmrg # It's OK to call 'install-sh -d' without argument. 2225b28e182Smrg # This can happen when creating conditional directories. 2235b28e182Smrg exit 0 2245b28e182Smrgfi 225dcae5b9eSmrg 2265b28e182Smrgif test -z "$dir_arg"; then 22715adf0bfSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22815adf0bfSmrg if test ! -d "$dst_arg"; then 22915adf0bfSmrg echo "$0: $dst_arg: Is not a directory." >&2 23015adf0bfSmrg exit 1 23115adf0bfSmrg fi 23215adf0bfSmrg fi 23315adf0bfSmrgfi 23415adf0bfSmrg 23515adf0bfSmrgif test -z "$dir_arg"; then 23615adf0bfSmrg do_exit='(exit $ret); exit $ret' 23715adf0bfSmrg trap "ret=129; $do_exit" 1 23815adf0bfSmrg trap "ret=130; $do_exit" 2 23915adf0bfSmrg trap "ret=141; $do_exit" 13 24015adf0bfSmrg trap "ret=143; $do_exit" 15 2415b28e182Smrg 2425b28e182Smrg # Set umask so as not to create temps with too-generous modes. 2435b28e182Smrg # However, 'strip' requires both read and write access to temps. 2445b28e182Smrg case $mode in 2455b28e182Smrg # Optimize common cases. 2465b28e182Smrg *644) cp_umask=133;; 2475b28e182Smrg *755) cp_umask=22;; 2485b28e182Smrg 2495b28e182Smrg *[0-7]) 2505b28e182Smrg if test -z "$stripcmd"; then 25115adf0bfSmrg u_plus_rw= 2525b28e182Smrg else 25315adf0bfSmrg u_plus_rw='% 200' 2545b28e182Smrg fi 2555b28e182Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2565b28e182Smrg *) 2575b28e182Smrg if test -z "$stripcmd"; then 25815adf0bfSmrg u_plus_rw= 2595b28e182Smrg else 26015adf0bfSmrg u_plus_rw=,u+rw 2615b28e182Smrg fi 2625b28e182Smrg cp_umask=$mode$u_plus_rw;; 2635b28e182Smrg esac 2645b28e182Smrgfi 265dcae5b9eSmrg 2665b28e182Smrgfor src 2675b28e182Smrgdo 26815adf0bfSmrg # Protect names problematic for 'test' and other utilities. 2695b28e182Smrg case $src in 27015adf0bfSmrg -* | [=\(\)!]) src=./$src;; 2715b28e182Smrg esac 2725b28e182Smrg 2735b28e182Smrg if test -n "$dir_arg"; then 2745b28e182Smrg dst=$src 2755b28e182Smrg dstdir=$dst 2765b28e182Smrg test -d "$dstdir" 2775b28e182Smrg dstdir_status=$? 27815adf0bfSmrg # Don't chown directories that already exist. 27915adf0bfSmrg if test $dstdir_status = 0; then 28015adf0bfSmrg chowncmd="" 28115adf0bfSmrg fi 2825b28e182Smrg else 2835b28e182Smrg 2845b28e182Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2855b28e182Smrg # might cause directories to be created, which would be especially bad 2865b28e182Smrg # if $src (and thus $dsttmp) contains '*'. 2875b28e182Smrg if test ! -f "$src" && test ! -d "$src"; then 2885b28e182Smrg echo "$0: $src does not exist." >&2 2895b28e182Smrg exit 1 2905b28e182Smrg fi 2915b28e182Smrg 2925b28e182Smrg if test -z "$dst_arg"; then 2935b28e182Smrg echo "$0: no destination specified." >&2 2945b28e182Smrg exit 1 2955b28e182Smrg fi 2965b28e182Smrg dst=$dst_arg 297dcae5b9eSmrg 29815adf0bfSmrg # If destination is a directory, append the input filename. 2995b28e182Smrg if test -d "$dst"; then 30015adf0bfSmrg if test "$is_target_a_directory" = never; then 30115adf0bfSmrg echo "$0: $dst_arg: Is a directory" >&2 30215adf0bfSmrg exit 1 3035b28e182Smrg fi 3045b28e182Smrg dstdir=$dst 30515adf0bfSmrg dstbase=`basename "$src"` 30615adf0bfSmrg case $dst in 30715adf0bfSmrg */) dst=$dst$dstbase;; 30815adf0bfSmrg *) dst=$dst/$dstbase;; 30915adf0bfSmrg esac 3105b28e182Smrg dstdir_status=0 3115b28e182Smrg else 31215adf0bfSmrg dstdir=`dirname "$dst"` 3135b28e182Smrg test -d "$dstdir" 3145b28e182Smrg dstdir_status=$? 3155b28e182Smrg fi 3165b28e182Smrg fi 3175b28e182Smrg 31815adf0bfSmrg case $dstdir in 31915adf0bfSmrg */) dstdirslash=$dstdir;; 32015adf0bfSmrg *) dstdirslash=$dstdir/;; 32115adf0bfSmrg esac 32215adf0bfSmrg 3235b28e182Smrg obsolete_mkdir_used=false 3245b28e182Smrg 3255b28e182Smrg if test $dstdir_status != 0; then 3265b28e182Smrg case $posix_mkdir in 3275b28e182Smrg '') 32815adf0bfSmrg # With -d, create the new directory with the user-specified mode. 32915adf0bfSmrg # Otherwise, rely on $mkdir_umask. 33015adf0bfSmrg if test -n "$dir_arg"; then 33115adf0bfSmrg mkdir_mode=-m$mode 33215adf0bfSmrg else 33315adf0bfSmrg mkdir_mode= 33415adf0bfSmrg fi 33515adf0bfSmrg 33615adf0bfSmrg posix_mkdir=false 33715adf0bfSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 33815adf0bfSmrg # here however when possible just to lower collision chance. 33915adf0bfSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34015adf0bfSmrg 34115adf0bfSmrg trap ' 34215adf0bfSmrg ret=$? 34315adf0bfSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 34415adf0bfSmrg exit $ret 34515adf0bfSmrg ' 0 34615adf0bfSmrg 34715adf0bfSmrg # Because "mkdir -p" follows existing symlinks and we likely work 34815adf0bfSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 34915adf0bfSmrg # directory is successfully created first before we actually test 35015adf0bfSmrg # 'mkdir -p'. 35115adf0bfSmrg if (umask $mkdir_umask && 35215adf0bfSmrg $mkdirprog $mkdir_mode "$tmpdir" && 35315adf0bfSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 35415adf0bfSmrg then 35515adf0bfSmrg if test -z "$dir_arg" || { 35615adf0bfSmrg # Check for POSIX incompatibilities with -m. 35715adf0bfSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35815adf0bfSmrg # other-writable bit of parent directory when it shouldn't. 35915adf0bfSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 36015adf0bfSmrg test_tmpdir="$tmpdir/a" 36115adf0bfSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 36215adf0bfSmrg case $ls_ld_tmpdir in 36315adf0bfSmrg d????-?r-*) different_mode=700;; 36415adf0bfSmrg d????-?--*) different_mode=755;; 36515adf0bfSmrg *) false;; 36615adf0bfSmrg esac && 36715adf0bfSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 36815adf0bfSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36915adf0bfSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 37015adf0bfSmrg } 37115adf0bfSmrg } 37215adf0bfSmrg then posix_mkdir=: 37315adf0bfSmrg fi 37415adf0bfSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375dcae5b9eSmrg else 37615adf0bfSmrg # Remove any dirs left behind by ancient mkdir implementations. 37715adf0bfSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378dcae5b9eSmrg fi 37915adf0bfSmrg trap '' 0;; 3805b28e182Smrg esac 381dcae5b9eSmrg 3825b28e182Smrg if 3835b28e182Smrg $posix_mkdir && ( 38415adf0bfSmrg umask $mkdir_umask && 38515adf0bfSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3865b28e182Smrg ) 3875b28e182Smrg then : 3885b28e182Smrg else 3895b28e182Smrg 39015adf0bfSmrg # mkdir does not conform to POSIX, 3915b28e182Smrg # or it failed possibly due to a race condition. Create the 3925b28e182Smrg # directory the slow way, step by step, checking for races as we go. 3935b28e182Smrg 3945b28e182Smrg case $dstdir in 39515adf0bfSmrg /*) prefix='/';; 39615adf0bfSmrg [-=\(\)!]*) prefix='./';; 39715adf0bfSmrg *) prefix='';; 3985b28e182Smrg esac 3995b28e182Smrg 4005b28e182Smrg oIFS=$IFS 4015b28e182Smrg IFS=/ 40215adf0bfSmrg set -f 4035b28e182Smrg set fnord $dstdir 4045b28e182Smrg shift 40515adf0bfSmrg set +f 4065b28e182Smrg IFS=$oIFS 4075b28e182Smrg 4085b28e182Smrg prefixes= 4095b28e182Smrg 4105b28e182Smrg for d 4115b28e182Smrg do 41215adf0bfSmrg test X"$d" = X && continue 41315adf0bfSmrg 41415adf0bfSmrg prefix=$prefix$d 41515adf0bfSmrg if test -d "$prefix"; then 41615adf0bfSmrg prefixes= 41715adf0bfSmrg else 41815adf0bfSmrg if $posix_mkdir; then 41915adf0bfSmrg (umask $mkdir_umask && 42015adf0bfSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42115adf0bfSmrg # Don't fail if two instances are running concurrently. 42215adf0bfSmrg test -d "$prefix" || exit 1 42315adf0bfSmrg else 42415adf0bfSmrg case $prefix in 42515adf0bfSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42615adf0bfSmrg *) qprefix=$prefix;; 42715adf0bfSmrg esac 42815adf0bfSmrg prefixes="$prefixes '$qprefix'" 42915adf0bfSmrg fi 43015adf0bfSmrg fi 43115adf0bfSmrg prefix=$prefix/ 4325b28e182Smrg done 4335b28e182Smrg 4345b28e182Smrg if test -n "$prefixes"; then 43515adf0bfSmrg # Don't fail if two instances are running concurrently. 43615adf0bfSmrg (umask $mkdir_umask && 43715adf0bfSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 43815adf0bfSmrg test -d "$dstdir" || exit 1 43915adf0bfSmrg obsolete_mkdir_used=true 4405b28e182Smrg fi 4415b28e182Smrg fi 4425b28e182Smrg fi 4435b28e182Smrg 4445b28e182Smrg if test -n "$dir_arg"; then 4455b28e182Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4465b28e182Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4475b28e182Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4485b28e182Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4495b28e182Smrg else 4505b28e182Smrg 4515b28e182Smrg # Make a couple of temp file names in the proper directory. 45215adf0bfSmrg dsttmp=${dstdirslash}_inst.$$_ 45315adf0bfSmrg rmtmp=${dstdirslash}_rm.$$_ 4545b28e182Smrg 4555b28e182Smrg # Trap to clean up those temp files at exit. 4565b28e182Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4575b28e182Smrg 4585b28e182Smrg # Copy the file name to the temp name. 45915adf0bfSmrg (umask $cp_umask && 46015adf0bfSmrg { test -z "$stripcmd" || { 46115adf0bfSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 46215adf0bfSmrg # which would cause strip to fail. 46315adf0bfSmrg if test -z "$doit"; then 46415adf0bfSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 46515adf0bfSmrg else 46615adf0bfSmrg $doit touch "$dsttmp" 46715adf0bfSmrg fi 46815adf0bfSmrg } 46915adf0bfSmrg } && 47015adf0bfSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4715b28e182Smrg 4725b28e182Smrg # and set any options; do chmod last to preserve setuid bits. 4735b28e182Smrg # 4745b28e182Smrg # If any of these fail, we abort the whole thing. If we want to 4755b28e182Smrg # ignore errors from any of these, just make sure not to ignore 4765b28e182Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4775b28e182Smrg # 4785b28e182Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4795b28e182Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4805b28e182Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4815b28e182Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4825b28e182Smrg 4835b28e182Smrg # If -C, don't bother to copy if it wouldn't change the file. 4845b28e182Smrg if $copy_on_change && 48515adf0bfSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48615adf0bfSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48715adf0bfSmrg set -f && 4885b28e182Smrg set X $old && old=:$2:$4:$5:$6 && 4895b28e182Smrg set X $new && new=:$2:$4:$5:$6 && 49015adf0bfSmrg set +f && 4915b28e182Smrg test "$old" = "$new" && 4925b28e182Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4935b28e182Smrg then 4945b28e182Smrg rm -f "$dsttmp" 4955b28e182Smrg else 49615adf0bfSmrg # If $backupsuffix is set, and the file being installed 49715adf0bfSmrg # already exists, attempt a backup. Don't worry if it fails, 49815adf0bfSmrg # e.g., if mv doesn't support -f. 49915adf0bfSmrg if test -n "$backupsuffix" && test -f "$dst"; then 50015adf0bfSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 50115adf0bfSmrg fi 50215adf0bfSmrg 5035b28e182Smrg # Rename the file to the real destination. 5045b28e182Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5055b28e182Smrg 5065b28e182Smrg # The rename failed, perhaps because mv can't rename something else 5075b28e182Smrg # to itself, or perhaps because mv is so ancient that it does not 5085b28e182Smrg # support -f. 5095b28e182Smrg { 51015adf0bfSmrg # Now remove or move aside any old file at destination location. 51115adf0bfSmrg # We try this two ways since rm can't unlink itself on some 51215adf0bfSmrg # systems and the destination file might be busy for other 51315adf0bfSmrg # reasons. In this case, the final cleanup might fail but the new 51415adf0bfSmrg # file should still install successfully. 51515adf0bfSmrg { 51615adf0bfSmrg test ! -f "$dst" || 51715adf0bfSmrg $doit $rmcmd "$dst" 2>/dev/null || 51815adf0bfSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 51915adf0bfSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52015adf0bfSmrg } || 52115adf0bfSmrg { echo "$0: cannot unlink or rename $dst" >&2 52215adf0bfSmrg (exit 1); exit 1 52315adf0bfSmrg } 52415adf0bfSmrg } && 52515adf0bfSmrg 52615adf0bfSmrg # Now rename the file to the real destination. 52715adf0bfSmrg $doit $mvcmd "$dsttmp" "$dst" 5285b28e182Smrg } 5295b28e182Smrg fi || exit 1 5305b28e182Smrg 5315b28e182Smrg trap '' 0 5325b28e182Smrg fi 5335b28e182Smrgdone 534dcae5b9eSmrg 5355b28e182Smrg# Local variables: 53615adf0bfSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5375b28e182Smrg# time-stamp-start: "scriptversion=" 5385b28e182Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 53915adf0bfSmrg# time-stamp-time-zone: "UTC0" 5405b28e182Smrg# time-stamp-end: "; # UTC" 5415b28e182Smrg# End: 542