install-sh revision 96d43ffd
15dfecf96Smrg#!/bin/sh 25dfecf96Smrg# install - install a program, script, or datafile 35dfecf96Smrg 496d43ffdSmrgscriptversion=2020-11-14.01; # UTC 55dfecf96Smrg 65dfecf96Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 75dfecf96Smrg# later released in X11R6 (xc/config/util/install.sh) with the 85dfecf96Smrg# following copyright and license. 95dfecf96Smrg# 105dfecf96Smrg# Copyright (C) 1994 X Consortium 115dfecf96Smrg# 125dfecf96Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 135dfecf96Smrg# of this software and associated documentation files (the "Software"), to 145dfecf96Smrg# deal in the Software without restriction, including without limitation the 155dfecf96Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 165dfecf96Smrg# sell copies of the Software, and to permit persons to whom the Software is 175dfecf96Smrg# furnished to do so, subject to the following conditions: 185dfecf96Smrg# 195dfecf96Smrg# The above copyright notice and this permission notice shall be included in 205dfecf96Smrg# all copies or substantial portions of the Software. 215dfecf96Smrg# 225dfecf96Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 235dfecf96Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 245dfecf96Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 255dfecf96Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 265dfecf96Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 275dfecf96Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 285dfecf96Smrg# 295dfecf96Smrg# Except as contained in this notice, the name of the X Consortium shall not 305dfecf96Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 315dfecf96Smrg# ings in this Software without prior written authorization from the X Consor- 325dfecf96Smrg# tium. 335dfecf96Smrg# 345dfecf96Smrg# 355dfecf96Smrg# FSF changes to this file are in the public domain. 365dfecf96Smrg# 375dfecf96Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38f765521fSmrg# 'make' implicit rules from creating a file called install from it 395dfecf96Smrg# when there is no Makefile. 405dfecf96Smrg# 415dfecf96Smrg# This script is compatible with the BSD install script, but was written 42f14f4646Smrg# from scratch. 43f14f4646Smrg 4496d43ffdSmrgtab=' ' 45f14f4646Smrgnl=' 46f14f4646Smrg' 4796d43ffdSmrgIFS=" $tab$nl" 485dfecf96Smrg 4996d43ffdSmrg# Set DOITPROG to "echo" to test this script. 505dfecf96Smrg 51f14f4646Smrgdoit=${DOITPROG-} 5296d43ffdSmrgdoit_exec=${doit:-exec} 535dfecf96Smrg 54f14f4646Smrg# Put in absolute file names if you don't have them in your path; 55f14f4646Smrg# or use environment vars. 56f14f4646Smrg 57f14f4646Smrgchgrpprog=${CHGRPPROG-chgrp} 58f14f4646Smrgchmodprog=${CHMODPROG-chmod} 59f14f4646Smrgchownprog=${CHOWNPROG-chown} 60f14f4646Smrgcmpprog=${CMPPROG-cmp} 61f14f4646Smrgcpprog=${CPPROG-cp} 62f14f4646Smrgmkdirprog=${MKDIRPROG-mkdir} 63f14f4646Smrgmvprog=${MVPROG-mv} 64f14f4646Smrgrmprog=${RMPROG-rm} 65f14f4646Smrgstripprog=${STRIPPROG-strip} 66f14f4646Smrg 67f14f4646Smrgposix_mkdir= 68f14f4646Smrg 69f14f4646Smrg# Desired mode of installed file. 70f14f4646Smrgmode=0755 715dfecf96Smrg 7296d43ffdSmrg# Create dirs (including intermediate dirs) using mode 755. 7396d43ffdSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 7496d43ffdSmrgmkdir_umask=22 7596d43ffdSmrg 7696d43ffdSmrgbackupsuffix= 775dfecf96Smrgchgrpcmd= 78f14f4646Smrgchmodcmd=$chmodprog 79f14f4646Smrgchowncmd= 80f14f4646Smrgmvcmd=$mvprog 815dfecf96Smrgrmcmd="$rmprog -f" 82f14f4646Smrgstripcmd= 83f14f4646Smrg 845dfecf96Smrgsrc= 855dfecf96Smrgdst= 865dfecf96Smrgdir_arg= 87f14f4646Smrgdst_arg= 88f14f4646Smrg 89f14f4646Smrgcopy_on_change=false 9096d43ffdSmrgis_target_a_directory=possibly 915dfecf96Smrg 92f14f4646Smrgusage="\ 93f14f4646SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 945dfecf96Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 955dfecf96Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 965dfecf96Smrg or: $0 [OPTION]... -d DIRECTORIES... 975dfecf96Smrg 985dfecf96SmrgIn the 1st form, copy SRCFILE to DSTFILE. 995dfecf96SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1005dfecf96SmrgIn the 4th, create DIRECTORIES. 1015dfecf96Smrg 1025dfecf96SmrgOptions: 103f14f4646Smrg --help display this help and exit. 104f14f4646Smrg --version display version info and exit. 105f14f4646Smrg 106f14f4646Smrg -c (ignored) 10796d43ffdSmrg -C install only if different (preserve data modification time) 108f14f4646Smrg -d create directories instead of installing files. 109f14f4646Smrg -g GROUP $chgrpprog installed files to GROUP. 110f14f4646Smrg -m MODE $chmodprog installed files to MODE. 111f14f4646Smrg -o USER $chownprog installed files to USER. 11296d43ffdSmrg -p pass -p to $cpprog. 113f14f4646Smrg -s $stripprog installed files. 11496d43ffdSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115f14f4646Smrg -t DIRECTORY install into DIRECTORY. 116f14f4646Smrg -T report an error if DSTFILE is a directory. 1175dfecf96Smrg 1185dfecf96SmrgEnvironment variables override the default commands: 119f14f4646Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120f14f4646Smrg RMPROG STRIPPROG 12196d43ffdSmrg 12296d43ffdSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 12396d43ffdSmrgit's up to you to specify -f if you want it. 12496d43ffdSmrg 12596d43ffdSmrgIf -S is not specified, no backups are attempted. 12696d43ffdSmrg 12796d43ffdSmrgEmail bug reports to bug-automake@gnu.org. 12896d43ffdSmrgAutomake home page: https://www.gnu.org/software/automake/ 1295dfecf96Smrg" 1305dfecf96Smrg 131f14f4646Smrgwhile test $# -ne 0; do 1325dfecf96Smrg case $1 in 133f14f4646Smrg -c) ;; 134f14f4646Smrg 135f14f4646Smrg -C) copy_on_change=true;; 1365dfecf96Smrg 137f14f4646Smrg -d) dir_arg=true;; 1385dfecf96Smrg 1395dfecf96Smrg -g) chgrpcmd="$chgrpprog $2" 14096d43ffdSmrg shift;; 1415dfecf96Smrg 1425dfecf96Smrg --help) echo "$usage"; exit $?;; 1435dfecf96Smrg 144f14f4646Smrg -m) mode=$2 14596d43ffdSmrg case $mode in 14696d43ffdSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14796d43ffdSmrg echo "$0: invalid mode: $mode" >&2 14896d43ffdSmrg exit 1;; 14996d43ffdSmrg esac 15096d43ffdSmrg shift;; 1515dfecf96Smrg 1525dfecf96Smrg -o) chowncmd="$chownprog $2" 15396d43ffdSmrg shift;; 15496d43ffdSmrg 15596d43ffdSmrg -p) cpprog="$cpprog -p";; 1565dfecf96Smrg 157f14f4646Smrg -s) stripcmd=$stripprog;; 1585dfecf96Smrg 15996d43ffdSmrg -S) backupsuffix="$2" 16096d43ffdSmrg shift;; 1615dfecf96Smrg 16296d43ffdSmrg -t) 16396d43ffdSmrg is_target_a_directory=always 16496d43ffdSmrg dst_arg=$2 16596d43ffdSmrg # Protect names problematic for 'test' and other utilities. 16696d43ffdSmrg case $dst_arg in 16796d43ffdSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16896d43ffdSmrg esac 16996d43ffdSmrg shift;; 17096d43ffdSmrg 17196d43ffdSmrg -T) is_target_a_directory=never;; 1725dfecf96Smrg 1735dfecf96Smrg --version) echo "$0 $scriptversion"; exit $?;; 1745dfecf96Smrg 17596d43ffdSmrg --) shift 17696d43ffdSmrg break;; 177f14f4646Smrg 17896d43ffdSmrg -*) echo "$0: invalid option: $1" >&2 17996d43ffdSmrg exit 1;; 180f14f4646Smrg 181f14f4646Smrg *) break;; 1825dfecf96Smrg esac 183f14f4646Smrg shift 1845dfecf96Smrgdone 1855dfecf96Smrg 18696d43ffdSmrg# We allow the use of options -d and -T together, by making -d 18796d43ffdSmrg# take the precedence; this is for compatibility with GNU install. 18896d43ffdSmrg 18996d43ffdSmrgif test -n "$dir_arg"; then 19096d43ffdSmrg if test -n "$dst_arg"; then 19196d43ffdSmrg echo "$0: target directory not allowed when installing a directory." >&2 19296d43ffdSmrg exit 1 19396d43ffdSmrg fi 19496d43ffdSmrgfi 19596d43ffdSmrg 196f14f4646Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197f14f4646Smrg # When -d is used, all remaining arguments are directories to create. 198f14f4646Smrg # When -t is used, the destination is already specified. 199f14f4646Smrg # Otherwise, the last argument is the destination. Remove it from $@. 200f14f4646Smrg for arg 201f14f4646Smrg do 202f14f4646Smrg if test -n "$dst_arg"; then 203f14f4646Smrg # $@ is not empty: it contains at least $arg. 204f14f4646Smrg set fnord "$@" "$dst_arg" 205f14f4646Smrg shift # fnord 206f14f4646Smrg fi 207f14f4646Smrg shift # arg 208f14f4646Smrg dst_arg=$arg 209f765521fSmrg # Protect names problematic for 'test' and other utilities. 21031de2854Smrg case $dst_arg in 21131de2854Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21231de2854Smrg esac 213f14f4646Smrg done 214f14f4646Smrgfi 215f14f4646Smrg 216f14f4646Smrgif test $# -eq 0; then 2175dfecf96Smrg if test -z "$dir_arg"; then 2185dfecf96Smrg echo "$0: no input file specified." >&2 2195dfecf96Smrg exit 1 2205dfecf96Smrg fi 221f765521fSmrg # It's OK to call 'install-sh -d' without argument. 2225dfecf96Smrg # This can happen when creating conditional directories. 2235dfecf96Smrg exit 0 2245dfecf96Smrgfi 2255dfecf96Smrg 22696d43ffdSmrgif test -z "$dir_arg"; then 22796d43ffdSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22896d43ffdSmrg if test ! -d "$dst_arg"; then 22996d43ffdSmrg echo "$0: $dst_arg: Is not a directory." >&2 23096d43ffdSmrg exit 1 23196d43ffdSmrg fi 23296d43ffdSmrg fi 23396d43ffdSmrgfi 23496d43ffdSmrg 235f14f4646Smrgif test -z "$dir_arg"; then 23631de2854Smrg do_exit='(exit $ret); exit $ret' 23731de2854Smrg trap "ret=129; $do_exit" 1 23831de2854Smrg trap "ret=130; $do_exit" 2 23931de2854Smrg trap "ret=141; $do_exit" 13 24031de2854Smrg trap "ret=143; $do_exit" 15 241f14f4646Smrg 242f14f4646Smrg # Set umask so as not to create temps with too-generous modes. 243f14f4646Smrg # However, 'strip' requires both read and write access to temps. 244f14f4646Smrg case $mode in 245f14f4646Smrg # Optimize common cases. 246f14f4646Smrg *644) cp_umask=133;; 247f14f4646Smrg *755) cp_umask=22;; 248f14f4646Smrg 249f14f4646Smrg *[0-7]) 250f14f4646Smrg if test -z "$stripcmd"; then 25196d43ffdSmrg u_plus_rw= 252f14f4646Smrg else 25396d43ffdSmrg u_plus_rw='% 200' 254f14f4646Smrg fi 255f14f4646Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256f14f4646Smrg *) 257f14f4646Smrg if test -z "$stripcmd"; then 25896d43ffdSmrg u_plus_rw= 259f14f4646Smrg else 26096d43ffdSmrg u_plus_rw=,u+rw 261f14f4646Smrg fi 262f14f4646Smrg cp_umask=$mode$u_plus_rw;; 263f14f4646Smrg esac 264f14f4646Smrgfi 265f14f4646Smrg 2665dfecf96Smrgfor src 2675dfecf96Smrgdo 268f765521fSmrg # Protect names problematic for 'test' and other utilities. 2695dfecf96Smrg case $src in 27031de2854Smrg -* | [=\(\)!]) src=./$src;; 2715dfecf96Smrg esac 2725dfecf96Smrg 2735dfecf96Smrg if test -n "$dir_arg"; then 2745dfecf96Smrg dst=$src 275f14f4646Smrg dstdir=$dst 276f14f4646Smrg test -d "$dstdir" 277f14f4646Smrg dstdir_status=$? 27896d43ffdSmrg # Don't chown directories that already exist. 27996d43ffdSmrg if test $dstdir_status = 0; then 28096d43ffdSmrg chowncmd="" 28196d43ffdSmrg fi 2825dfecf96Smrg else 283f14f4646Smrg 2845dfecf96Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2855dfecf96Smrg # might cause directories to be created, which would be especially bad 2865dfecf96Smrg # if $src (and thus $dsttmp) contains '*'. 2875dfecf96Smrg if test ! -f "$src" && test ! -d "$src"; then 2885dfecf96Smrg echo "$0: $src does not exist." >&2 2895dfecf96Smrg exit 1 2905dfecf96Smrg fi 2915dfecf96Smrg 292f14f4646Smrg if test -z "$dst_arg"; then 2935dfecf96Smrg echo "$0: no destination specified." >&2 2945dfecf96Smrg exit 1 2955dfecf96Smrg fi 296f14f4646Smrg dst=$dst_arg 2975dfecf96Smrg 29896d43ffdSmrg # If destination is a directory, append the input filename. 2995dfecf96Smrg if test -d "$dst"; then 30096d43ffdSmrg if test "$is_target_a_directory" = never; then 30196d43ffdSmrg echo "$0: $dst_arg: Is a directory" >&2 30296d43ffdSmrg exit 1 3035dfecf96Smrg fi 304f14f4646Smrg dstdir=$dst 30596d43ffdSmrg dstbase=`basename "$src"` 30696d43ffdSmrg case $dst in 30796d43ffdSmrg */) dst=$dst$dstbase;; 30896d43ffdSmrg *) dst=$dst/$dstbase;; 30996d43ffdSmrg esac 310f14f4646Smrg dstdir_status=0 311f14f4646Smrg else 31296d43ffdSmrg dstdir=`dirname "$dst"` 313f14f4646Smrg test -d "$dstdir" 314f14f4646Smrg dstdir_status=$? 3155dfecf96Smrg fi 3165dfecf96Smrg fi 3175dfecf96Smrg 31896d43ffdSmrg case $dstdir in 31996d43ffdSmrg */) dstdirslash=$dstdir;; 32096d43ffdSmrg *) dstdirslash=$dstdir/;; 32196d43ffdSmrg esac 32296d43ffdSmrg 323f14f4646Smrg obsolete_mkdir_used=false 324f14f4646Smrg 325f14f4646Smrg if test $dstdir_status != 0; then 326f14f4646Smrg case $posix_mkdir in 327f14f4646Smrg '') 32896d43ffdSmrg # With -d, create the new directory with the user-specified mode. 32996d43ffdSmrg # Otherwise, rely on $mkdir_umask. 33096d43ffdSmrg if test -n "$dir_arg"; then 33196d43ffdSmrg mkdir_mode=-m$mode 33296d43ffdSmrg else 33396d43ffdSmrg mkdir_mode= 33496d43ffdSmrg fi 33596d43ffdSmrg 33696d43ffdSmrg posix_mkdir=false 33796d43ffdSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 33896d43ffdSmrg # here however when possible just to lower collision chance. 33996d43ffdSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34096d43ffdSmrg 34196d43ffdSmrg trap ' 34296d43ffdSmrg ret=$? 34396d43ffdSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 34496d43ffdSmrg exit $ret 34596d43ffdSmrg ' 0 34696d43ffdSmrg 34796d43ffdSmrg # Because "mkdir -p" follows existing symlinks and we likely work 34896d43ffdSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 34996d43ffdSmrg # directory is successfully created first before we actually test 35096d43ffdSmrg # 'mkdir -p'. 35196d43ffdSmrg if (umask $mkdir_umask && 35296d43ffdSmrg $mkdirprog $mkdir_mode "$tmpdir" && 35396d43ffdSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 35496d43ffdSmrg then 35596d43ffdSmrg if test -z "$dir_arg" || { 35696d43ffdSmrg # Check for POSIX incompatibilities with -m. 35796d43ffdSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35896d43ffdSmrg # other-writable bit of parent directory when it shouldn't. 35996d43ffdSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 36096d43ffdSmrg test_tmpdir="$tmpdir/a" 36196d43ffdSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 36296d43ffdSmrg case $ls_ld_tmpdir in 36396d43ffdSmrg d????-?r-*) different_mode=700;; 36496d43ffdSmrg d????-?--*) different_mode=755;; 36596d43ffdSmrg *) false;; 36696d43ffdSmrg esac && 36796d43ffdSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 36896d43ffdSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36996d43ffdSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 37096d43ffdSmrg } 37196d43ffdSmrg } 37296d43ffdSmrg then posix_mkdir=: 37396d43ffdSmrg fi 37496d43ffdSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375f14f4646Smrg else 37696d43ffdSmrg # Remove any dirs left behind by ancient mkdir implementations. 37796d43ffdSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378f14f4646Smrg fi 37996d43ffdSmrg trap '' 0;; 380f14f4646Smrg esac 3815dfecf96Smrg 382f14f4646Smrg if 383f14f4646Smrg $posix_mkdir && ( 38496d43ffdSmrg umask $mkdir_umask && 38596d43ffdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386f14f4646Smrg ) 387f14f4646Smrg then : 388f14f4646Smrg else 3895dfecf96Smrg 39096d43ffdSmrg # mkdir does not conform to POSIX, 391f14f4646Smrg # or it failed possibly due to a race condition. Create the 392f14f4646Smrg # directory the slow way, step by step, checking for races as we go. 3935dfecf96Smrg 394f14f4646Smrg case $dstdir in 39596d43ffdSmrg /*) prefix='/';; 39696d43ffdSmrg [-=\(\)!]*) prefix='./';; 39796d43ffdSmrg *) prefix='';; 398f14f4646Smrg esac 3995dfecf96Smrg 400f14f4646Smrg oIFS=$IFS 401f14f4646Smrg IFS=/ 40296d43ffdSmrg set -f 403f14f4646Smrg set fnord $dstdir 4045dfecf96Smrg shift 40596d43ffdSmrg set +f 406f14f4646Smrg IFS=$oIFS 407f14f4646Smrg 408f14f4646Smrg prefixes= 409f14f4646Smrg 410f14f4646Smrg for d 411f14f4646Smrg do 41296d43ffdSmrg test X"$d" = X && continue 41396d43ffdSmrg 41496d43ffdSmrg prefix=$prefix$d 41596d43ffdSmrg if test -d "$prefix"; then 41696d43ffdSmrg prefixes= 41796d43ffdSmrg else 41896d43ffdSmrg if $posix_mkdir; then 41996d43ffdSmrg (umask $mkdir_umask && 42096d43ffdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42196d43ffdSmrg # Don't fail if two instances are running concurrently. 42296d43ffdSmrg test -d "$prefix" || exit 1 42396d43ffdSmrg else 42496d43ffdSmrg case $prefix in 42596d43ffdSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42696d43ffdSmrg *) qprefix=$prefix;; 42796d43ffdSmrg esac 42896d43ffdSmrg prefixes="$prefixes '$qprefix'" 42996d43ffdSmrg fi 43096d43ffdSmrg fi 43196d43ffdSmrg prefix=$prefix/ 432f14f4646Smrg done 433f14f4646Smrg 434f14f4646Smrg if test -n "$prefixes"; then 43596d43ffdSmrg # Don't fail if two instances are running concurrently. 43696d43ffdSmrg (umask $mkdir_umask && 43796d43ffdSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 43896d43ffdSmrg test -d "$dstdir" || exit 1 43996d43ffdSmrg obsolete_mkdir_used=true 4405dfecf96Smrg fi 441f14f4646Smrg fi 4425dfecf96Smrg fi 4435dfecf96Smrg 4445dfecf96Smrg if test -n "$dir_arg"; then 445f14f4646Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446f14f4646Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447f14f4646Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448f14f4646Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4495dfecf96Smrg else 4505dfecf96Smrg 4515dfecf96Smrg # Make a couple of temp file names in the proper directory. 45296d43ffdSmrg dsttmp=${dstdirslash}_inst.$$_ 45396d43ffdSmrg rmtmp=${dstdirslash}_rm.$$_ 4545dfecf96Smrg 4555dfecf96Smrg # Trap to clean up those temp files at exit. 4565dfecf96Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4575dfecf96Smrg 4585dfecf96Smrg # Copy the file name to the temp name. 45996d43ffdSmrg (umask $cp_umask && 46096d43ffdSmrg { test -z "$stripcmd" || { 46196d43ffdSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 46296d43ffdSmrg # which would cause strip to fail. 46396d43ffdSmrg if test -z "$doit"; then 46496d43ffdSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 46596d43ffdSmrg else 46696d43ffdSmrg $doit touch "$dsttmp" 46796d43ffdSmrg fi 46896d43ffdSmrg } 46996d43ffdSmrg } && 47096d43ffdSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4715dfecf96Smrg 4725dfecf96Smrg # and set any options; do chmod last to preserve setuid bits. 4735dfecf96Smrg # 4745dfecf96Smrg # If any of these fail, we abort the whole thing. If we want to 4755dfecf96Smrg # ignore errors from any of these, just make sure not to ignore 4765dfecf96Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4775dfecf96Smrg # 478f14f4646Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479f14f4646Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480f14f4646Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481f14f4646Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482f14f4646Smrg 483f14f4646Smrg # If -C, don't bother to copy if it wouldn't change the file. 484f14f4646Smrg if $copy_on_change && 48596d43ffdSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48696d43ffdSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48796d43ffdSmrg set -f && 488f14f4646Smrg set X $old && old=:$2:$4:$5:$6 && 489f14f4646Smrg set X $new && new=:$2:$4:$5:$6 && 49096d43ffdSmrg set +f && 491f14f4646Smrg test "$old" = "$new" && 492f14f4646Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493f14f4646Smrg then 494f14f4646Smrg rm -f "$dsttmp" 495f14f4646Smrg else 49696d43ffdSmrg # If $backupsuffix is set, and the file being installed 49796d43ffdSmrg # already exists, attempt a backup. Don't worry if it fails, 49896d43ffdSmrg # e.g., if mv doesn't support -f. 49996d43ffdSmrg if test -n "$backupsuffix" && test -f "$dst"; then 50096d43ffdSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 50196d43ffdSmrg fi 50296d43ffdSmrg 503f14f4646Smrg # Rename the file to the real destination. 504f14f4646Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505f14f4646Smrg 506f14f4646Smrg # The rename failed, perhaps because mv can't rename something else 507f14f4646Smrg # to itself, or perhaps because mv is so ancient that it does not 508f14f4646Smrg # support -f. 509f14f4646Smrg { 51096d43ffdSmrg # Now remove or move aside any old file at destination location. 51196d43ffdSmrg # We try this two ways since rm can't unlink itself on some 51296d43ffdSmrg # systems and the destination file might be busy for other 51396d43ffdSmrg # reasons. In this case, the final cleanup might fail but the new 51496d43ffdSmrg # file should still install successfully. 51596d43ffdSmrg { 51696d43ffdSmrg test ! -f "$dst" || 51796d43ffdSmrg $doit $rmcmd "$dst" 2>/dev/null || 51896d43ffdSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 51996d43ffdSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52096d43ffdSmrg } || 52196d43ffdSmrg { echo "$0: cannot unlink or rename $dst" >&2 52296d43ffdSmrg (exit 1); exit 1 52396d43ffdSmrg } 52496d43ffdSmrg } && 52596d43ffdSmrg 52696d43ffdSmrg # Now rename the file to the real destination. 52796d43ffdSmrg $doit $mvcmd "$dsttmp" "$dst" 528f14f4646Smrg } 529f14f4646Smrg fi || exit 1 530f14f4646Smrg 531f14f4646Smrg trap '' 0 532f14f4646Smrg fi 5335dfecf96Smrgdone 5345dfecf96Smrg 5355dfecf96Smrg# Local variables: 53696d43ffdSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5375dfecf96Smrg# time-stamp-start: "scriptversion=" 5385dfecf96Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 53996d43ffdSmrg# time-stamp-time-zone: "UTC0" 540c05e22d7Smrg# time-stamp-end: "; # UTC" 5415dfecf96Smrg# End: 542