15eefee25Smacallan#!/bin/sh 25eefee25Smacallan# install - install a program, script, or datafile 35eefee25Smacallan 45c30ecadSmrgscriptversion=2020-11-14.01; # UTC 55eefee25Smacallan 65eefee25Smacallan# This originates from X11R5 (mit/util/scripts/install.sh), which was 75eefee25Smacallan# later released in X11R6 (xc/config/util/install.sh) with the 85eefee25Smacallan# following copyright and license. 95eefee25Smacallan# 105eefee25Smacallan# Copyright (C) 1994 X Consortium 115eefee25Smacallan# 125eefee25Smacallan# Permission is hereby granted, free of charge, to any person obtaining a copy 135eefee25Smacallan# of this software and associated documentation files (the "Software"), to 145eefee25Smacallan# deal in the Software without restriction, including without limitation the 155eefee25Smacallan# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 165eefee25Smacallan# sell copies of the Software, and to permit persons to whom the Software is 175eefee25Smacallan# furnished to do so, subject to the following conditions: 185eefee25Smacallan# 195eefee25Smacallan# The above copyright notice and this permission notice shall be included in 205eefee25Smacallan# all copies or substantial portions of the Software. 215eefee25Smacallan# 225eefee25Smacallan# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 235eefee25Smacallan# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 245eefee25Smacallan# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 255eefee25Smacallan# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 265eefee25Smacallan# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 275eefee25Smacallan# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 285eefee25Smacallan# 295eefee25Smacallan# Except as contained in this notice, the name of the X Consortium shall not 305eefee25Smacallan# be used in advertising or otherwise to promote the sale, use or other deal- 315eefee25Smacallan# ings in this Software without prior written authorization from the X Consor- 325eefee25Smacallan# tium. 335eefee25Smacallan# 345eefee25Smacallan# 355eefee25Smacallan# FSF changes to this file are in the public domain. 365eefee25Smacallan# 375eefee25Smacallan# Calling this script install-sh is preferred over install.sh, to prevent 38dc99b369Smrg# 'make' implicit rules from creating a file called install from it 395eefee25Smacallan# when there is no Makefile. 405eefee25Smacallan# 415eefee25Smacallan# This script is compatible with the BSD install script, but was written 4262ab96baSmrg# from scratch. 4362ab96baSmrg 445c30ecadSmrgtab=' ' 4562ab96baSmrgnl=' 4662ab96baSmrg' 475c30ecadSmrgIFS=" $tab$nl" 485eefee25Smacallan 495c30ecadSmrg# Set DOITPROG to "echo" to test this script. 505eefee25Smacallan 5162ab96baSmrgdoit=${DOITPROG-} 525c30ecadSmrgdoit_exec=${doit:-exec} 535eefee25Smacallan 5462ab96baSmrg# Put in absolute file names if you don't have them in your path; 5562ab96baSmrg# or use environment vars. 5662ab96baSmrg 5762ab96baSmrgchgrpprog=${CHGRPPROG-chgrp} 5862ab96baSmrgchmodprog=${CHMODPROG-chmod} 5962ab96baSmrgchownprog=${CHOWNPROG-chown} 6062ab96baSmrgcmpprog=${CMPPROG-cmp} 6162ab96baSmrgcpprog=${CPPROG-cp} 6262ab96baSmrgmkdirprog=${MKDIRPROG-mkdir} 6362ab96baSmrgmvprog=${MVPROG-mv} 6462ab96baSmrgrmprog=${RMPROG-rm} 6562ab96baSmrgstripprog=${STRIPPROG-strip} 6662ab96baSmrg 6762ab96baSmrgposix_mkdir= 6862ab96baSmrg 6962ab96baSmrg# Desired mode of installed file. 7062ab96baSmrgmode=0755 715eefee25Smacallan 725c30ecadSmrg# Create dirs (including intermediate dirs) using mode 755. 735c30ecadSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 745c30ecadSmrgmkdir_umask=22 755c30ecadSmrg 765c30ecadSmrgbackupsuffix= 775eefee25Smacallanchgrpcmd= 7862ab96baSmrgchmodcmd=$chmodprog 7962ab96baSmrgchowncmd= 8062ab96baSmrgmvcmd=$mvprog 815eefee25Smacallanrmcmd="$rmprog -f" 8262ab96baSmrgstripcmd= 8362ab96baSmrg 845eefee25Smacallansrc= 855eefee25Smacallandst= 865eefee25Smacallandir_arg= 8762ab96baSmrgdst_arg= 8862ab96baSmrg 8962ab96baSmrgcopy_on_change=false 905c30ecadSmrgis_target_a_directory=possibly 915eefee25Smacallan 9262ab96baSmrgusage="\ 9362ab96baSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 945eefee25Smacallan or: $0 [OPTION]... SRCFILES... DIRECTORY 955eefee25Smacallan or: $0 [OPTION]... -t DIRECTORY SRCFILES... 965eefee25Smacallan or: $0 [OPTION]... -d DIRECTORIES... 975eefee25Smacallan 985eefee25SmacallanIn the 1st form, copy SRCFILE to DSTFILE. 995eefee25SmacallanIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1005eefee25SmacallanIn the 4th, create DIRECTORIES. 1015eefee25Smacallan 1025eefee25SmacallanOptions: 10362ab96baSmrg --help display this help and exit. 10462ab96baSmrg --version display version info and exit. 10562ab96baSmrg 10662ab96baSmrg -c (ignored) 1075c30ecadSmrg -C install only if different (preserve data modification time) 10862ab96baSmrg -d create directories instead of installing files. 10962ab96baSmrg -g GROUP $chgrpprog installed files to GROUP. 11062ab96baSmrg -m MODE $chmodprog installed files to MODE. 11162ab96baSmrg -o USER $chownprog installed files to USER. 1125c30ecadSmrg -p pass -p to $cpprog. 11362ab96baSmrg -s $stripprog installed files. 1145c30ecadSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 11562ab96baSmrg -t DIRECTORY install into DIRECTORY. 11662ab96baSmrg -T report an error if DSTFILE is a directory. 1175eefee25Smacallan 1185eefee25SmacallanEnvironment variables override the default commands: 11962ab96baSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 12062ab96baSmrg RMPROG STRIPPROG 1215c30ecadSmrg 1225c30ecadSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 1235c30ecadSmrgit's up to you to specify -f if you want it. 1245c30ecadSmrg 1255c30ecadSmrgIf -S is not specified, no backups are attempted. 1265c30ecadSmrg 1275c30ecadSmrgEmail bug reports to bug-automake@gnu.org. 1285c30ecadSmrgAutomake home page: https://www.gnu.org/software/automake/ 1295eefee25Smacallan" 1305eefee25Smacallan 13162ab96baSmrgwhile test $# -ne 0; do 1325eefee25Smacallan case $1 in 13362ab96baSmrg -c) ;; 13462ab96baSmrg 13562ab96baSmrg -C) copy_on_change=true;; 1365eefee25Smacallan 13762ab96baSmrg -d) dir_arg=true;; 1385eefee25Smacallan 1395eefee25Smacallan -g) chgrpcmd="$chgrpprog $2" 1405c30ecadSmrg shift;; 1415eefee25Smacallan 1425eefee25Smacallan --help) echo "$usage"; exit $?;; 1435eefee25Smacallan 14462ab96baSmrg -m) mode=$2 1455c30ecadSmrg case $mode in 1465c30ecadSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1475c30ecadSmrg echo "$0: invalid mode: $mode" >&2 1485c30ecadSmrg exit 1;; 1495c30ecadSmrg esac 1505c30ecadSmrg shift;; 1515eefee25Smacallan 1525eefee25Smacallan -o) chowncmd="$chownprog $2" 1535c30ecadSmrg shift;; 1545c30ecadSmrg 1555c30ecadSmrg -p) cpprog="$cpprog -p";; 1565eefee25Smacallan 15762ab96baSmrg -s) stripcmd=$stripprog;; 1585eefee25Smacallan 1595c30ecadSmrg -S) backupsuffix="$2" 1605c30ecadSmrg shift;; 1615eefee25Smacallan 1625c30ecadSmrg -t) 1635c30ecadSmrg is_target_a_directory=always 1645c30ecadSmrg dst_arg=$2 1655c30ecadSmrg # Protect names problematic for 'test' and other utilities. 1665c30ecadSmrg case $dst_arg in 1675c30ecadSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1685c30ecadSmrg esac 1695c30ecadSmrg shift;; 1705c30ecadSmrg 1715c30ecadSmrg -T) is_target_a_directory=never;; 1725eefee25Smacallan 1735eefee25Smacallan --version) echo "$0 $scriptversion"; exit $?;; 1745eefee25Smacallan 1755c30ecadSmrg --) shift 1765c30ecadSmrg break;; 17762ab96baSmrg 1785c30ecadSmrg -*) echo "$0: invalid option: $1" >&2 1795c30ecadSmrg exit 1;; 18062ab96baSmrg 18162ab96baSmrg *) break;; 1825eefee25Smacallan esac 18362ab96baSmrg shift 1845eefee25Smacallandone 1855eefee25Smacallan 1865c30ecadSmrg# We allow the use of options -d and -T together, by making -d 1875c30ecadSmrg# take the precedence; this is for compatibility with GNU install. 1885c30ecadSmrg 1895c30ecadSmrgif test -n "$dir_arg"; then 1905c30ecadSmrg if test -n "$dst_arg"; then 1915c30ecadSmrg echo "$0: target directory not allowed when installing a directory." >&2 1925c30ecadSmrg exit 1 1935c30ecadSmrg fi 1945c30ecadSmrgfi 1955c30ecadSmrg 19662ab96baSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 19762ab96baSmrg # When -d is used, all remaining arguments are directories to create. 19862ab96baSmrg # When -t is used, the destination is already specified. 19962ab96baSmrg # Otherwise, the last argument is the destination. Remove it from $@. 20062ab96baSmrg for arg 20162ab96baSmrg do 20262ab96baSmrg if test -n "$dst_arg"; then 20362ab96baSmrg # $@ is not empty: it contains at least $arg. 20462ab96baSmrg set fnord "$@" "$dst_arg" 20562ab96baSmrg shift # fnord 20662ab96baSmrg fi 20762ab96baSmrg shift # arg 20862ab96baSmrg dst_arg=$arg 209dc99b369Smrg # Protect names problematic for 'test' and other utilities. 210dc99b369Smrg case $dst_arg in 211dc99b369Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212dc99b369Smrg esac 21362ab96baSmrg done 21462ab96baSmrgfi 21562ab96baSmrg 21662ab96baSmrgif test $# -eq 0; then 2175eefee25Smacallan if test -z "$dir_arg"; then 2185eefee25Smacallan echo "$0: no input file specified." >&2 2195eefee25Smacallan exit 1 2205eefee25Smacallan fi 221dc99b369Smrg # It's OK to call 'install-sh -d' without argument. 2225eefee25Smacallan # This can happen when creating conditional directories. 2235eefee25Smacallan exit 0 2245eefee25Smacallanfi 2255eefee25Smacallan 2265c30ecadSmrgif test -z "$dir_arg"; then 2275c30ecadSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2285c30ecadSmrg if test ! -d "$dst_arg"; then 2295c30ecadSmrg echo "$0: $dst_arg: Is not a directory." >&2 2305c30ecadSmrg exit 1 2315c30ecadSmrg fi 2325c30ecadSmrg fi 2335c30ecadSmrgfi 2345c30ecadSmrg 23562ab96baSmrgif test -z "$dir_arg"; then 236dc99b369Smrg do_exit='(exit $ret); exit $ret' 237dc99b369Smrg trap "ret=129; $do_exit" 1 238dc99b369Smrg trap "ret=130; $do_exit" 2 239dc99b369Smrg trap "ret=141; $do_exit" 13 240dc99b369Smrg trap "ret=143; $do_exit" 15 24162ab96baSmrg 24262ab96baSmrg # Set umask so as not to create temps with too-generous modes. 24362ab96baSmrg # However, 'strip' requires both read and write access to temps. 24462ab96baSmrg case $mode in 24562ab96baSmrg # Optimize common cases. 24662ab96baSmrg *644) cp_umask=133;; 24762ab96baSmrg *755) cp_umask=22;; 24862ab96baSmrg 24962ab96baSmrg *[0-7]) 25062ab96baSmrg if test -z "$stripcmd"; then 2515c30ecadSmrg u_plus_rw= 25262ab96baSmrg else 2535c30ecadSmrg u_plus_rw='% 200' 25462ab96baSmrg fi 25562ab96baSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 25662ab96baSmrg *) 25762ab96baSmrg if test -z "$stripcmd"; then 2585c30ecadSmrg u_plus_rw= 25962ab96baSmrg else 2605c30ecadSmrg u_plus_rw=,u+rw 26162ab96baSmrg fi 26262ab96baSmrg cp_umask=$mode$u_plus_rw;; 26362ab96baSmrg esac 26462ab96baSmrgfi 26562ab96baSmrg 2665eefee25Smacallanfor src 2675eefee25Smacallando 268dc99b369Smrg # Protect names problematic for 'test' and other utilities. 2695eefee25Smacallan case $src in 270dc99b369Smrg -* | [=\(\)!]) src=./$src;; 2715eefee25Smacallan esac 2725eefee25Smacallan 2735eefee25Smacallan if test -n "$dir_arg"; then 2745eefee25Smacallan dst=$src 27562ab96baSmrg dstdir=$dst 27662ab96baSmrg test -d "$dstdir" 27762ab96baSmrg dstdir_status=$? 2785c30ecadSmrg # Don't chown directories that already exist. 2795c30ecadSmrg if test $dstdir_status = 0; then 2805c30ecadSmrg chowncmd="" 2815c30ecadSmrg fi 2825eefee25Smacallan else 28362ab96baSmrg 2845eefee25Smacallan # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2855eefee25Smacallan # might cause directories to be created, which would be especially bad 2865eefee25Smacallan # if $src (and thus $dsttmp) contains '*'. 2875eefee25Smacallan if test ! -f "$src" && test ! -d "$src"; then 2885eefee25Smacallan echo "$0: $src does not exist." >&2 2895eefee25Smacallan exit 1 2905eefee25Smacallan fi 2915eefee25Smacallan 29262ab96baSmrg if test -z "$dst_arg"; then 2935eefee25Smacallan echo "$0: no destination specified." >&2 2945eefee25Smacallan exit 1 2955eefee25Smacallan fi 29662ab96baSmrg dst=$dst_arg 2975eefee25Smacallan 2985c30ecadSmrg # If destination is a directory, append the input filename. 2995eefee25Smacallan if test -d "$dst"; then 3005c30ecadSmrg if test "$is_target_a_directory" = never; then 3015c30ecadSmrg echo "$0: $dst_arg: Is a directory" >&2 3025c30ecadSmrg exit 1 3035eefee25Smacallan fi 30462ab96baSmrg dstdir=$dst 3055c30ecadSmrg dstbase=`basename "$src"` 3065c30ecadSmrg case $dst in 3075c30ecadSmrg */) dst=$dst$dstbase;; 3085c30ecadSmrg *) dst=$dst/$dstbase;; 3095c30ecadSmrg esac 31062ab96baSmrg dstdir_status=0 31162ab96baSmrg else 3125c30ecadSmrg dstdir=`dirname "$dst"` 31362ab96baSmrg test -d "$dstdir" 31462ab96baSmrg dstdir_status=$? 3155eefee25Smacallan fi 3165eefee25Smacallan fi 3175eefee25Smacallan 3185c30ecadSmrg case $dstdir in 3195c30ecadSmrg */) dstdirslash=$dstdir;; 3205c30ecadSmrg *) dstdirslash=$dstdir/;; 3215c30ecadSmrg esac 3225c30ecadSmrg 32362ab96baSmrg obsolete_mkdir_used=false 32462ab96baSmrg 32562ab96baSmrg if test $dstdir_status != 0; then 32662ab96baSmrg case $posix_mkdir in 32762ab96baSmrg '') 3285c30ecadSmrg # With -d, create the new directory with the user-specified mode. 3295c30ecadSmrg # Otherwise, rely on $mkdir_umask. 3305c30ecadSmrg if test -n "$dir_arg"; then 3315c30ecadSmrg mkdir_mode=-m$mode 3325c30ecadSmrg else 3335c30ecadSmrg mkdir_mode= 3345c30ecadSmrg fi 3355c30ecadSmrg 3365c30ecadSmrg posix_mkdir=false 3375c30ecadSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 3385c30ecadSmrg # here however when possible just to lower collision chance. 3395c30ecadSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3405c30ecadSmrg 3415c30ecadSmrg trap ' 3425c30ecadSmrg ret=$? 3435c30ecadSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 3445c30ecadSmrg exit $ret 3455c30ecadSmrg ' 0 3465c30ecadSmrg 3475c30ecadSmrg # Because "mkdir -p" follows existing symlinks and we likely work 3485c30ecadSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 3495c30ecadSmrg # directory is successfully created first before we actually test 3505c30ecadSmrg # 'mkdir -p'. 3515c30ecadSmrg if (umask $mkdir_umask && 3525c30ecadSmrg $mkdirprog $mkdir_mode "$tmpdir" && 3535c30ecadSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 3545c30ecadSmrg then 3555c30ecadSmrg if test -z "$dir_arg" || { 3565c30ecadSmrg # Check for POSIX incompatibilities with -m. 3575c30ecadSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3585c30ecadSmrg # other-writable bit of parent directory when it shouldn't. 3595c30ecadSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3605c30ecadSmrg test_tmpdir="$tmpdir/a" 3615c30ecadSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 3625c30ecadSmrg case $ls_ld_tmpdir in 3635c30ecadSmrg d????-?r-*) different_mode=700;; 3645c30ecadSmrg d????-?--*) different_mode=755;; 3655c30ecadSmrg *) false;; 3665c30ecadSmrg esac && 3675c30ecadSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 3685c30ecadSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 3695c30ecadSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3705c30ecadSmrg } 3715c30ecadSmrg } 3725c30ecadSmrg then posix_mkdir=: 3735c30ecadSmrg fi 3745c30ecadSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 37562ab96baSmrg else 3765c30ecadSmrg # Remove any dirs left behind by ancient mkdir implementations. 3775c30ecadSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 37862ab96baSmrg fi 3795c30ecadSmrg trap '' 0;; 38062ab96baSmrg esac 3815eefee25Smacallan 38262ab96baSmrg if 38362ab96baSmrg $posix_mkdir && ( 3845c30ecadSmrg umask $mkdir_umask && 3855c30ecadSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 38662ab96baSmrg ) 38762ab96baSmrg then : 38862ab96baSmrg else 3895eefee25Smacallan 3905c30ecadSmrg # mkdir does not conform to POSIX, 39162ab96baSmrg # or it failed possibly due to a race condition. Create the 39262ab96baSmrg # directory the slow way, step by step, checking for races as we go. 3935eefee25Smacallan 39462ab96baSmrg case $dstdir in 3955c30ecadSmrg /*) prefix='/';; 3965c30ecadSmrg [-=\(\)!]*) prefix='./';; 3975c30ecadSmrg *) prefix='';; 39862ab96baSmrg esac 3995eefee25Smacallan 40062ab96baSmrg oIFS=$IFS 40162ab96baSmrg IFS=/ 4025c30ecadSmrg set -f 40362ab96baSmrg set fnord $dstdir 4045eefee25Smacallan shift 4055c30ecadSmrg set +f 40662ab96baSmrg IFS=$oIFS 40762ab96baSmrg 40862ab96baSmrg prefixes= 40962ab96baSmrg 41062ab96baSmrg for d 41162ab96baSmrg do 4125c30ecadSmrg test X"$d" = X && continue 4135c30ecadSmrg 4145c30ecadSmrg prefix=$prefix$d 4155c30ecadSmrg if test -d "$prefix"; then 4165c30ecadSmrg prefixes= 4175c30ecadSmrg else 4185c30ecadSmrg if $posix_mkdir; then 4195c30ecadSmrg (umask $mkdir_umask && 4205c30ecadSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4215c30ecadSmrg # Don't fail if two instances are running concurrently. 4225c30ecadSmrg test -d "$prefix" || exit 1 4235c30ecadSmrg else 4245c30ecadSmrg case $prefix in 4255c30ecadSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4265c30ecadSmrg *) qprefix=$prefix;; 4275c30ecadSmrg esac 4285c30ecadSmrg prefixes="$prefixes '$qprefix'" 4295c30ecadSmrg fi 4305c30ecadSmrg fi 4315c30ecadSmrg prefix=$prefix/ 43262ab96baSmrg done 43362ab96baSmrg 43462ab96baSmrg if test -n "$prefixes"; then 4355c30ecadSmrg # Don't fail if two instances are running concurrently. 4365c30ecadSmrg (umask $mkdir_umask && 4375c30ecadSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 4385c30ecadSmrg test -d "$dstdir" || exit 1 4395c30ecadSmrg obsolete_mkdir_used=true 4405eefee25Smacallan fi 44162ab96baSmrg fi 4425eefee25Smacallan fi 4435eefee25Smacallan 4445eefee25Smacallan if test -n "$dir_arg"; then 44562ab96baSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 44662ab96baSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 44762ab96baSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 44862ab96baSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4495eefee25Smacallan else 4505eefee25Smacallan 4515eefee25Smacallan # Make a couple of temp file names in the proper directory. 4525c30ecadSmrg dsttmp=${dstdirslash}_inst.$$_ 4535c30ecadSmrg rmtmp=${dstdirslash}_rm.$$_ 4545eefee25Smacallan 4555eefee25Smacallan # Trap to clean up those temp files at exit. 4565eefee25Smacallan trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4575eefee25Smacallan 4585eefee25Smacallan # Copy the file name to the temp name. 4595c30ecadSmrg (umask $cp_umask && 4605c30ecadSmrg { test -z "$stripcmd" || { 4615c30ecadSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 4625c30ecadSmrg # which would cause strip to fail. 4635c30ecadSmrg if test -z "$doit"; then 4645c30ecadSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 4655c30ecadSmrg else 4665c30ecadSmrg $doit touch "$dsttmp" 4675c30ecadSmrg fi 4685c30ecadSmrg } 4695c30ecadSmrg } && 4705c30ecadSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4715eefee25Smacallan 4725eefee25Smacallan # and set any options; do chmod last to preserve setuid bits. 4735eefee25Smacallan # 4745eefee25Smacallan # If any of these fail, we abort the whole thing. If we want to 4755eefee25Smacallan # ignore errors from any of these, just make sure not to ignore 4765eefee25Smacallan # errors from the above "$doit $cpprog $src $dsttmp" command. 4775eefee25Smacallan # 47862ab96baSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 47962ab96baSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 48062ab96baSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 48162ab96baSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 48262ab96baSmrg 48362ab96baSmrg # If -C, don't bother to copy if it wouldn't change the file. 48462ab96baSmrg if $copy_on_change && 4855c30ecadSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4865c30ecadSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4875c30ecadSmrg set -f && 48862ab96baSmrg set X $old && old=:$2:$4:$5:$6 && 48962ab96baSmrg set X $new && new=:$2:$4:$5:$6 && 4905c30ecadSmrg set +f && 49162ab96baSmrg test "$old" = "$new" && 49262ab96baSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 49362ab96baSmrg then 49462ab96baSmrg rm -f "$dsttmp" 49562ab96baSmrg else 4965c30ecadSmrg # If $backupsuffix is set, and the file being installed 4975c30ecadSmrg # already exists, attempt a backup. Don't worry if it fails, 4985c30ecadSmrg # e.g., if mv doesn't support -f. 4995c30ecadSmrg if test -n "$backupsuffix" && test -f "$dst"; then 5005c30ecadSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 5015c30ecadSmrg fi 5025c30ecadSmrg 50362ab96baSmrg # Rename the file to the real destination. 50462ab96baSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 50562ab96baSmrg 50662ab96baSmrg # The rename failed, perhaps because mv can't rename something else 50762ab96baSmrg # to itself, or perhaps because mv is so ancient that it does not 50862ab96baSmrg # support -f. 50962ab96baSmrg { 5105c30ecadSmrg # Now remove or move aside any old file at destination location. 5115c30ecadSmrg # We try this two ways since rm can't unlink itself on some 5125c30ecadSmrg # systems and the destination file might be busy for other 5135c30ecadSmrg # reasons. In this case, the final cleanup might fail but the new 5145c30ecadSmrg # file should still install successfully. 5155c30ecadSmrg { 5165c30ecadSmrg test ! -f "$dst" || 5175c30ecadSmrg $doit $rmcmd "$dst" 2>/dev/null || 5185c30ecadSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5195c30ecadSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 5205c30ecadSmrg } || 5215c30ecadSmrg { echo "$0: cannot unlink or rename $dst" >&2 5225c30ecadSmrg (exit 1); exit 1 5235c30ecadSmrg } 5245c30ecadSmrg } && 5255c30ecadSmrg 5265c30ecadSmrg # Now rename the file to the real destination. 5275c30ecadSmrg $doit $mvcmd "$dsttmp" "$dst" 52862ab96baSmrg } 52962ab96baSmrg fi || exit 1 53062ab96baSmrg 53162ab96baSmrg trap '' 0 53262ab96baSmrg fi 5335eefee25Smacallandone 5345eefee25Smacallan 5355eefee25Smacallan# Local variables: 5365c30ecadSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5375eefee25Smacallan# time-stamp-start: "scriptversion=" 5385eefee25Smacallan# time-stamp-format: "%:y-%02m-%02d.%02H" 5395c30ecadSmrg# time-stamp-time-zone: "UTC0" 540dc99b369Smrg# time-stamp-end: "; # UTC" 5415eefee25Smacallan# End: 542