install-sh revision 7591dea4
156f6b22bSmrg#!/bin/sh 256f6b22bSmrg# install - install a program, script, or datafile 3ef7198c0Smrg 47591dea4Smrgscriptversion=2020-11-14.01; # UTC 5ef7198c0Smrg 656f6b22bSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 756f6b22bSmrg# later released in X11R6 (xc/config/util/install.sh) with the 856f6b22bSmrg# following copyright and license. 956f6b22bSmrg# 1056f6b22bSmrg# Copyright (C) 1994 X Consortium 1156f6b22bSmrg# 1256f6b22bSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1356f6b22bSmrg# of this software and associated documentation files (the "Software"), to 1456f6b22bSmrg# deal in the Software without restriction, including without limitation the 1556f6b22bSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1656f6b22bSmrg# sell copies of the Software, and to permit persons to whom the Software is 1756f6b22bSmrg# furnished to do so, subject to the following conditions: 1856f6b22bSmrg# 1956f6b22bSmrg# The above copyright notice and this permission notice shall be included in 2056f6b22bSmrg# all copies or substantial portions of the Software. 2156f6b22bSmrg# 2256f6b22bSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2356f6b22bSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2456f6b22bSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2556f6b22bSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2656f6b22bSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2756f6b22bSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2856f6b22bSmrg# 2956f6b22bSmrg# Except as contained in this notice, the name of the X Consortium shall not 3056f6b22bSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 3156f6b22bSmrg# ings in this Software without prior written authorization from the X Consor- 3256f6b22bSmrg# tium. 3356f6b22bSmrg# 3456f6b22bSmrg# 3556f6b22bSmrg# FSF changes to this file are in the public domain. 3656f6b22bSmrg# 3756f6b22bSmrg# Calling this script install-sh is preferred over install.sh, to prevent 387591dea4Smrg# 'make' implicit rules from creating a file called install from it 3956f6b22bSmrg# when there is no Makefile. 4056f6b22bSmrg# 4156f6b22bSmrg# This script is compatible with the BSD install script, but was written 42ef7198c0Smrg# from scratch. 4356f6b22bSmrg 447591dea4Smrgtab=' ' 45ef7198c0Smrgnl=' 46ef7198c0Smrg' 477591dea4SmrgIFS=" $tab$nl" 4856f6b22bSmrg 497591dea4Smrg# Set DOITPROG to "echo" to test this script. 5056f6b22bSmrg 51ef7198c0Smrgdoit=${DOITPROG-} 527591dea4Smrgdoit_exec=${doit:-exec} 5356f6b22bSmrg 54ef7198c0Smrg# Put in absolute file names if you don't have them in your path; 55ef7198c0Smrg# or use environment vars. 56ef7198c0Smrg 57ef7198c0Smrgchgrpprog=${CHGRPPROG-chgrp} 58ef7198c0Smrgchmodprog=${CHMODPROG-chmod} 59ef7198c0Smrgchownprog=${CHOWNPROG-chown} 60ef7198c0Smrgcmpprog=${CMPPROG-cmp} 61ef7198c0Smrgcpprog=${CPPROG-cp} 62ef7198c0Smrgmkdirprog=${MKDIRPROG-mkdir} 63ef7198c0Smrgmvprog=${MVPROG-mv} 64ef7198c0Smrgrmprog=${RMPROG-rm} 65ef7198c0Smrgstripprog=${STRIPPROG-strip} 66ef7198c0Smrg 67ef7198c0Smrgposix_mkdir= 68ef7198c0Smrg 69ef7198c0Smrg# Desired mode of installed file. 70ef7198c0Smrgmode=0755 71ef7198c0Smrg 727591dea4Smrg# Create dirs (including intermediate dirs) using mode 755. 737591dea4Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 747591dea4Smrgmkdir_umask=22 757591dea4Smrg 767591dea4Smrgbackupsuffix= 77ef7198c0Smrgchgrpcmd= 78ef7198c0Smrgchmodcmd=$chmodprog 79ef7198c0Smrgchowncmd= 80ef7198c0Smrgmvcmd=$mvprog 81ef7198c0Smrgrmcmd="$rmprog -f" 82ef7198c0Smrgstripcmd= 8356f6b22bSmrg 84ef7198c0Smrgsrc= 85ef7198c0Smrgdst= 86ef7198c0Smrgdir_arg= 87ef7198c0Smrgdst_arg= 8856f6b22bSmrg 89ef7198c0Smrgcopy_on_change=false 907591dea4Smrgis_target_a_directory=possibly 9156f6b22bSmrg 92ef7198c0Smrgusage="\ 93ef7198c0SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94ef7198c0Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95ef7198c0Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96ef7198c0Smrg or: $0 [OPTION]... -d DIRECTORIES... 9756f6b22bSmrg 98ef7198c0SmrgIn the 1st form, copy SRCFILE to DSTFILE. 99ef7198c0SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100ef7198c0SmrgIn the 4th, create DIRECTORIES. 10156f6b22bSmrg 102ef7198c0SmrgOptions: 103ef7198c0Smrg --help display this help and exit. 104ef7198c0Smrg --version display version info and exit. 10556f6b22bSmrg 106ef7198c0Smrg -c (ignored) 1077591dea4Smrg -C install only if different (preserve data modification time) 108ef7198c0Smrg -d create directories instead of installing files. 109ef7198c0Smrg -g GROUP $chgrpprog installed files to GROUP. 110ef7198c0Smrg -m MODE $chmodprog installed files to MODE. 111ef7198c0Smrg -o USER $chownprog installed files to USER. 1127591dea4Smrg -p pass -p to $cpprog. 113ef7198c0Smrg -s $stripprog installed files. 1147591dea4Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115ef7198c0Smrg -t DIRECTORY install into DIRECTORY. 116ef7198c0Smrg -T report an error if DSTFILE is a directory. 11756f6b22bSmrg 118ef7198c0SmrgEnvironment variables override the default commands: 119ef7198c0Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120ef7198c0Smrg RMPROG STRIPPROG 1217591dea4Smrg 1227591dea4SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 1237591dea4Smrgit's up to you to specify -f if you want it. 1247591dea4Smrg 1257591dea4SmrgIf -S is not specified, no backups are attempted. 1267591dea4Smrg 1277591dea4SmrgEmail bug reports to bug-automake@gnu.org. 1287591dea4SmrgAutomake home page: https://www.gnu.org/software/automake/ 129ef7198c0Smrg" 13056f6b22bSmrg 131ef7198c0Smrgwhile test $# -ne 0; do 132ef7198c0Smrg case $1 in 133ef7198c0Smrg -c) ;; 13456f6b22bSmrg 135ef7198c0Smrg -C) copy_on_change=true;; 13656f6b22bSmrg 137ef7198c0Smrg -d) dir_arg=true;; 13856f6b22bSmrg 139ef7198c0Smrg -g) chgrpcmd="$chgrpprog $2" 1407591dea4Smrg shift;; 14156f6b22bSmrg 142ef7198c0Smrg --help) echo "$usage"; exit $?;; 14356f6b22bSmrg 144ef7198c0Smrg -m) mode=$2 1457591dea4Smrg case $mode in 1467591dea4Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1477591dea4Smrg echo "$0: invalid mode: $mode" >&2 1487591dea4Smrg exit 1;; 1497591dea4Smrg esac 1507591dea4Smrg shift;; 15156f6b22bSmrg 152ef7198c0Smrg -o) chowncmd="$chownprog $2" 1537591dea4Smrg shift;; 1547591dea4Smrg 1557591dea4Smrg -p) cpprog="$cpprog -p";; 15656f6b22bSmrg 157ef7198c0Smrg -s) stripcmd=$stripprog;; 15856f6b22bSmrg 1597591dea4Smrg -S) backupsuffix="$2" 1607591dea4Smrg shift;; 1617591dea4Smrg 1627591dea4Smrg -t) 1637591dea4Smrg is_target_a_directory=always 1647591dea4Smrg dst_arg=$2 1657591dea4Smrg # Protect names problematic for 'test' and other utilities. 1667591dea4Smrg case $dst_arg in 1677591dea4Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1687591dea4Smrg esac 1697591dea4Smrg shift;; 17056f6b22bSmrg 1717591dea4Smrg -T) is_target_a_directory=never;; 17256f6b22bSmrg 173ef7198c0Smrg --version) echo "$0 $scriptversion"; exit $?;; 17456f6b22bSmrg 1757591dea4Smrg --) shift 1767591dea4Smrg break;; 17756f6b22bSmrg 1787591dea4Smrg -*) echo "$0: invalid option: $1" >&2 1797591dea4Smrg exit 1;; 18056f6b22bSmrg 181ef7198c0Smrg *) break;; 182ef7198c0Smrg esac 183ef7198c0Smrg shift 184ef7198c0Smrgdone 18556f6b22bSmrg 1867591dea4Smrg# We allow the use of options -d and -T together, by making -d 1877591dea4Smrg# take the precedence; this is for compatibility with GNU install. 1887591dea4Smrg 1897591dea4Smrgif test -n "$dir_arg"; then 1907591dea4Smrg if test -n "$dst_arg"; then 1917591dea4Smrg echo "$0: target directory not allowed when installing a directory." >&2 1927591dea4Smrg exit 1 1937591dea4Smrg fi 1947591dea4Smrgfi 1957591dea4Smrg 196ef7198c0Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197ef7198c0Smrg # When -d is used, all remaining arguments are directories to create. 198ef7198c0Smrg # When -t is used, the destination is already specified. 199ef7198c0Smrg # Otherwise, the last argument is the destination. Remove it from $@. 200ef7198c0Smrg for arg 201ef7198c0Smrg do 202ef7198c0Smrg if test -n "$dst_arg"; then 203ef7198c0Smrg # $@ is not empty: it contains at least $arg. 204ef7198c0Smrg set fnord "$@" "$dst_arg" 205ef7198c0Smrg shift # fnord 206ef7198c0Smrg fi 207ef7198c0Smrg shift # arg 208ef7198c0Smrg dst_arg=$arg 2097591dea4Smrg # Protect names problematic for 'test' and other utilities. 2107591dea4Smrg case $dst_arg in 2117591dea4Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 2127591dea4Smrg esac 213ef7198c0Smrg done 214ef7198c0Smrgfi 21556f6b22bSmrg 216ef7198c0Smrgif test $# -eq 0; then 217ef7198c0Smrg if test -z "$dir_arg"; then 218ef7198c0Smrg echo "$0: no input file specified." >&2 219ef7198c0Smrg exit 1 220ef7198c0Smrg fi 2217591dea4Smrg # It's OK to call 'install-sh -d' without argument. 222ef7198c0Smrg # This can happen when creating conditional directories. 223ef7198c0Smrg exit 0 224ef7198c0Smrgfi 22556f6b22bSmrg 226ef7198c0Smrgif test -z "$dir_arg"; then 2277591dea4Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2287591dea4Smrg if test ! -d "$dst_arg"; then 2297591dea4Smrg echo "$0: $dst_arg: Is not a directory." >&2 2307591dea4Smrg exit 1 2317591dea4Smrg fi 2327591dea4Smrg fi 2337591dea4Smrgfi 2347591dea4Smrg 2357591dea4Smrgif test -z "$dir_arg"; then 2367591dea4Smrg do_exit='(exit $ret); exit $ret' 2377591dea4Smrg trap "ret=129; $do_exit" 1 2387591dea4Smrg trap "ret=130; $do_exit" 2 2397591dea4Smrg trap "ret=141; $do_exit" 13 2407591dea4Smrg trap "ret=143; $do_exit" 15 241ef7198c0Smrg 242ef7198c0Smrg # Set umask so as not to create temps with too-generous modes. 243ef7198c0Smrg # However, 'strip' requires both read and write access to temps. 244ef7198c0Smrg case $mode in 245ef7198c0Smrg # Optimize common cases. 246ef7198c0Smrg *644) cp_umask=133;; 247ef7198c0Smrg *755) cp_umask=22;; 248ef7198c0Smrg 249ef7198c0Smrg *[0-7]) 250ef7198c0Smrg if test -z "$stripcmd"; then 2517591dea4Smrg u_plus_rw= 252ef7198c0Smrg else 2537591dea4Smrg u_plus_rw='% 200' 254ef7198c0Smrg fi 255ef7198c0Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256ef7198c0Smrg *) 257ef7198c0Smrg if test -z "$stripcmd"; then 2587591dea4Smrg u_plus_rw= 259ef7198c0Smrg else 2607591dea4Smrg u_plus_rw=,u+rw 261ef7198c0Smrg fi 262ef7198c0Smrg cp_umask=$mode$u_plus_rw;; 263ef7198c0Smrg esac 264ef7198c0Smrgfi 26556f6b22bSmrg 266ef7198c0Smrgfor src 267ef7198c0Smrgdo 2687591dea4Smrg # Protect names problematic for 'test' and other utilities. 269ef7198c0Smrg case $src in 2707591dea4Smrg -* | [=\(\)!]) src=./$src;; 271ef7198c0Smrg esac 272ef7198c0Smrg 273ef7198c0Smrg if test -n "$dir_arg"; then 274ef7198c0Smrg dst=$src 275ef7198c0Smrg dstdir=$dst 276ef7198c0Smrg test -d "$dstdir" 277ef7198c0Smrg dstdir_status=$? 2787591dea4Smrg # Don't chown directories that already exist. 2797591dea4Smrg if test $dstdir_status = 0; then 2807591dea4Smrg chowncmd="" 2817591dea4Smrg fi 282ef7198c0Smrg else 283ef7198c0Smrg 284ef7198c0Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285ef7198c0Smrg # might cause directories to be created, which would be especially bad 286ef7198c0Smrg # if $src (and thus $dsttmp) contains '*'. 287ef7198c0Smrg if test ! -f "$src" && test ! -d "$src"; then 288ef7198c0Smrg echo "$0: $src does not exist." >&2 289ef7198c0Smrg exit 1 290ef7198c0Smrg fi 291ef7198c0Smrg 292ef7198c0Smrg if test -z "$dst_arg"; then 293ef7198c0Smrg echo "$0: no destination specified." >&2 294ef7198c0Smrg exit 1 295ef7198c0Smrg fi 296ef7198c0Smrg dst=$dst_arg 29756f6b22bSmrg 2987591dea4Smrg # If destination is a directory, append the input filename. 299ef7198c0Smrg if test -d "$dst"; then 3007591dea4Smrg if test "$is_target_a_directory" = never; then 3017591dea4Smrg echo "$0: $dst_arg: Is a directory" >&2 3027591dea4Smrg exit 1 303ef7198c0Smrg fi 304ef7198c0Smrg dstdir=$dst 3057591dea4Smrg dstbase=`basename "$src"` 3067591dea4Smrg case $dst in 3077591dea4Smrg */) dst=$dst$dstbase;; 3087591dea4Smrg *) dst=$dst/$dstbase;; 3097591dea4Smrg esac 310ef7198c0Smrg dstdir_status=0 311ef7198c0Smrg else 3127591dea4Smrg dstdir=`dirname "$dst"` 313ef7198c0Smrg test -d "$dstdir" 314ef7198c0Smrg dstdir_status=$? 315ef7198c0Smrg fi 316ef7198c0Smrg fi 317ef7198c0Smrg 3187591dea4Smrg case $dstdir in 3197591dea4Smrg */) dstdirslash=$dstdir;; 3207591dea4Smrg *) dstdirslash=$dstdir/;; 3217591dea4Smrg esac 3227591dea4Smrg 323ef7198c0Smrg obsolete_mkdir_used=false 324ef7198c0Smrg 325ef7198c0Smrg if test $dstdir_status != 0; then 326ef7198c0Smrg case $posix_mkdir in 327ef7198c0Smrg '') 3287591dea4Smrg # With -d, create the new directory with the user-specified mode. 3297591dea4Smrg # Otherwise, rely on $mkdir_umask. 3307591dea4Smrg if test -n "$dir_arg"; then 3317591dea4Smrg mkdir_mode=-m$mode 3327591dea4Smrg else 3337591dea4Smrg mkdir_mode= 3347591dea4Smrg fi 3357591dea4Smrg 3367591dea4Smrg posix_mkdir=false 3377591dea4Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 3387591dea4Smrg # here however when possible just to lower collision chance. 3397591dea4Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3407591dea4Smrg 3417591dea4Smrg trap ' 3427591dea4Smrg ret=$? 3437591dea4Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 3447591dea4Smrg exit $ret 3457591dea4Smrg ' 0 3467591dea4Smrg 3477591dea4Smrg # Because "mkdir -p" follows existing symlinks and we likely work 3487591dea4Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 3497591dea4Smrg # directory is successfully created first before we actually test 3507591dea4Smrg # 'mkdir -p'. 3517591dea4Smrg if (umask $mkdir_umask && 3527591dea4Smrg $mkdirprog $mkdir_mode "$tmpdir" && 3537591dea4Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 3547591dea4Smrg then 3557591dea4Smrg if test -z "$dir_arg" || { 3567591dea4Smrg # Check for POSIX incompatibilities with -m. 3577591dea4Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3587591dea4Smrg # other-writable bit of parent directory when it shouldn't. 3597591dea4Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3607591dea4Smrg test_tmpdir="$tmpdir/a" 3617591dea4Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 3627591dea4Smrg case $ls_ld_tmpdir in 3637591dea4Smrg d????-?r-*) different_mode=700;; 3647591dea4Smrg d????-?--*) different_mode=755;; 3657591dea4Smrg *) false;; 3667591dea4Smrg esac && 3677591dea4Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 3687591dea4Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 3697591dea4Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3707591dea4Smrg } 3717591dea4Smrg } 3727591dea4Smrg then posix_mkdir=: 3737591dea4Smrg fi 3747591dea4Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 37556f6b22bSmrg else 3767591dea4Smrg # Remove any dirs left behind by ancient mkdir implementations. 3777591dea4Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 37856f6b22bSmrg fi 3797591dea4Smrg trap '' 0;; 380ef7198c0Smrg esac 38156f6b22bSmrg 382ef7198c0Smrg if 383ef7198c0Smrg $posix_mkdir && ( 3847591dea4Smrg umask $mkdir_umask && 3857591dea4Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386ef7198c0Smrg ) 387ef7198c0Smrg then : 388ef7198c0Smrg else 389ef7198c0Smrg 3907591dea4Smrg # mkdir does not conform to POSIX, 391ef7198c0Smrg # or it failed possibly due to a race condition. Create the 392ef7198c0Smrg # directory the slow way, step by step, checking for races as we go. 393ef7198c0Smrg 394ef7198c0Smrg case $dstdir in 3957591dea4Smrg /*) prefix='/';; 3967591dea4Smrg [-=\(\)!]*) prefix='./';; 3977591dea4Smrg *) prefix='';; 398ef7198c0Smrg esac 399ef7198c0Smrg 400ef7198c0Smrg oIFS=$IFS 401ef7198c0Smrg IFS=/ 4027591dea4Smrg set -f 403ef7198c0Smrg set fnord $dstdir 404ef7198c0Smrg shift 4057591dea4Smrg set +f 406ef7198c0Smrg IFS=$oIFS 407ef7198c0Smrg 408ef7198c0Smrg prefixes= 409ef7198c0Smrg 410ef7198c0Smrg for d 411ef7198c0Smrg do 4127591dea4Smrg test X"$d" = X && continue 4137591dea4Smrg 4147591dea4Smrg prefix=$prefix$d 4157591dea4Smrg if test -d "$prefix"; then 4167591dea4Smrg prefixes= 4177591dea4Smrg else 4187591dea4Smrg if $posix_mkdir; then 4197591dea4Smrg (umask $mkdir_umask && 4207591dea4Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4217591dea4Smrg # Don't fail if two instances are running concurrently. 4227591dea4Smrg test -d "$prefix" || exit 1 4237591dea4Smrg else 4247591dea4Smrg case $prefix in 4257591dea4Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4267591dea4Smrg *) qprefix=$prefix;; 4277591dea4Smrg esac 4287591dea4Smrg prefixes="$prefixes '$qprefix'" 4297591dea4Smrg fi 4307591dea4Smrg fi 4317591dea4Smrg prefix=$prefix/ 432ef7198c0Smrg done 433ef7198c0Smrg 434ef7198c0Smrg if test -n "$prefixes"; then 4357591dea4Smrg # Don't fail if two instances are running concurrently. 4367591dea4Smrg (umask $mkdir_umask && 4377591dea4Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4387591dea4Smrg test -d "$dstdir" || exit 1 4397591dea4Smrg obsolete_mkdir_used=true 440ef7198c0Smrg fi 441ef7198c0Smrg fi 442ef7198c0Smrg fi 443ef7198c0Smrg 444ef7198c0Smrg if test -n "$dir_arg"; then 445ef7198c0Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446ef7198c0Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447ef7198c0Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448ef7198c0Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449ef7198c0Smrg else 450ef7198c0Smrg 451ef7198c0Smrg # Make a couple of temp file names in the proper directory. 4527591dea4Smrg dsttmp=${dstdirslash}_inst.$$_ 4537591dea4Smrg rmtmp=${dstdirslash}_rm.$$_ 454ef7198c0Smrg 455ef7198c0Smrg # Trap to clean up those temp files at exit. 456ef7198c0Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457ef7198c0Smrg 458ef7198c0Smrg # Copy the file name to the temp name. 4597591dea4Smrg (umask $cp_umask && 4607591dea4Smrg { test -z "$stripcmd" || { 4617591dea4Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 4627591dea4Smrg # which would cause strip to fail. 4637591dea4Smrg if test -z "$doit"; then 4647591dea4Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 4657591dea4Smrg else 4667591dea4Smrg $doit touch "$dsttmp" 4677591dea4Smrg fi 4687591dea4Smrg } 4697591dea4Smrg } && 4707591dea4Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471ef7198c0Smrg 472ef7198c0Smrg # and set any options; do chmod last to preserve setuid bits. 473ef7198c0Smrg # 474ef7198c0Smrg # If any of these fail, we abort the whole thing. If we want to 475ef7198c0Smrg # ignore errors from any of these, just make sure not to ignore 476ef7198c0Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477ef7198c0Smrg # 478ef7198c0Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479ef7198c0Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480ef7198c0Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481ef7198c0Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482ef7198c0Smrg 483ef7198c0Smrg # If -C, don't bother to copy if it wouldn't change the file. 484ef7198c0Smrg if $copy_on_change && 4857591dea4Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4867591dea4Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4877591dea4Smrg set -f && 488ef7198c0Smrg set X $old && old=:$2:$4:$5:$6 && 489ef7198c0Smrg set X $new && new=:$2:$4:$5:$6 && 4907591dea4Smrg set +f && 491ef7198c0Smrg test "$old" = "$new" && 492ef7198c0Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493ef7198c0Smrg then 494ef7198c0Smrg rm -f "$dsttmp" 495ef7198c0Smrg else 4967591dea4Smrg # If $backupsuffix is set, and the file being installed 4977591dea4Smrg # already exists, attempt a backup. Don't worry if it fails, 4987591dea4Smrg # e.g., if mv doesn't support -f. 4997591dea4Smrg if test -n "$backupsuffix" && test -f "$dst"; then 5007591dea4Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 5017591dea4Smrg fi 5027591dea4Smrg 503ef7198c0Smrg # Rename the file to the real destination. 504ef7198c0Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505ef7198c0Smrg 506ef7198c0Smrg # The rename failed, perhaps because mv can't rename something else 507ef7198c0Smrg # to itself, or perhaps because mv is so ancient that it does not 508ef7198c0Smrg # support -f. 509ef7198c0Smrg { 5107591dea4Smrg # Now remove or move aside any old file at destination location. 5117591dea4Smrg # We try this two ways since rm can't unlink itself on some 5127591dea4Smrg # systems and the destination file might be busy for other 5137591dea4Smrg # reasons. In this case, the final cleanup might fail but the new 5147591dea4Smrg # file should still install successfully. 5157591dea4Smrg { 5167591dea4Smrg test ! -f "$dst" || 5177591dea4Smrg $doit $rmcmd "$dst" 2>/dev/null || 5187591dea4Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5197591dea4Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 5207591dea4Smrg } || 5217591dea4Smrg { echo "$0: cannot unlink or rename $dst" >&2 5227591dea4Smrg (exit 1); exit 1 5237591dea4Smrg } 5247591dea4Smrg } && 5257591dea4Smrg 5267591dea4Smrg # Now rename the file to the real destination. 5277591dea4Smrg $doit $mvcmd "$dsttmp" "$dst" 528ef7198c0Smrg } 529ef7198c0Smrg fi || exit 1 530ef7198c0Smrg 531ef7198c0Smrg trap '' 0 532ef7198c0Smrg fi 533ef7198c0Smrgdone 53456f6b22bSmrg 535ef7198c0Smrg# Local variables: 5367591dea4Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537ef7198c0Smrg# time-stamp-start: "scriptversion=" 538ef7198c0Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5397591dea4Smrg# time-stamp-time-zone: "UTC0" 540ef7198c0Smrg# time-stamp-end: "; # UTC" 541ef7198c0Smrg# End: 542