1f299d47fSmrg#!/bin/sh 2f299d47fSmrg# install - install a program, script, or datafile 3f299d47fSmrg 498d75b17Smrgscriptversion=2020-11-14.01; # UTC 5f299d47fSmrg 6f299d47fSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7f299d47fSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8f299d47fSmrg# following copyright and license. 9f299d47fSmrg# 10f299d47fSmrg# Copyright (C) 1994 X Consortium 11f299d47fSmrg# 12f299d47fSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13f299d47fSmrg# of this software and associated documentation files (the "Software"), to 14f299d47fSmrg# deal in the Software without restriction, including without limitation the 15f299d47fSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16f299d47fSmrg# sell copies of the Software, and to permit persons to whom the Software is 17f299d47fSmrg# furnished to do so, subject to the following conditions: 18f299d47fSmrg# 19f299d47fSmrg# The above copyright notice and this permission notice shall be included in 20f299d47fSmrg# all copies or substantial portions of the Software. 21f299d47fSmrg# 22f299d47fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23f299d47fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24f299d47fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25f299d47fSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26f299d47fSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27f299d47fSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28f299d47fSmrg# 29f299d47fSmrg# Except as contained in this notice, the name of the X Consortium shall not 30f299d47fSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31f299d47fSmrg# ings in this Software without prior written authorization from the X Consor- 32f299d47fSmrg# tium. 33f299d47fSmrg# 34f299d47fSmrg# 35f299d47fSmrg# FSF changes to this file are in the public domain. 36f299d47fSmrg# 37f299d47fSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3805641e18Smrg# 'make' implicit rules from creating a file called install from it 39f299d47fSmrg# when there is no Makefile. 40f299d47fSmrg# 41f299d47fSmrg# This script is compatible with the BSD install script, but was written 42f299d47fSmrg# from scratch. 43f299d47fSmrg 4405641e18Smrgtab=' ' 45f299d47fSmrgnl=' 46f299d47fSmrg' 4705641e18SmrgIFS=" $tab$nl" 48f299d47fSmrg 4905641e18Smrg# Set DOITPROG to "echo" to test this script. 50f299d47fSmrg 51f299d47fSmrgdoit=${DOITPROG-} 5205641e18Smrgdoit_exec=${doit:-exec} 53f299d47fSmrg 54f299d47fSmrg# Put in absolute file names if you don't have them in your path; 55f299d47fSmrg# or use environment vars. 56f299d47fSmrg 57f299d47fSmrgchgrpprog=${CHGRPPROG-chgrp} 58f299d47fSmrgchmodprog=${CHMODPROG-chmod} 59f299d47fSmrgchownprog=${CHOWNPROG-chown} 60f299d47fSmrgcmpprog=${CMPPROG-cmp} 61f299d47fSmrgcpprog=${CPPROG-cp} 62f299d47fSmrgmkdirprog=${MKDIRPROG-mkdir} 63f299d47fSmrgmvprog=${MVPROG-mv} 64f299d47fSmrgrmprog=${RMPROG-rm} 65f299d47fSmrgstripprog=${STRIPPROG-strip} 66f299d47fSmrg 67f299d47fSmrgposix_mkdir= 68f299d47fSmrg 69f299d47fSmrg# Desired mode of installed file. 70f299d47fSmrgmode=0755 71f299d47fSmrg 7298d75b17Smrg# Create dirs (including intermediate dirs) using mode 755. 7398d75b17Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 7498d75b17Smrgmkdir_umask=22 7598d75b17Smrg 7698d75b17Smrgbackupsuffix= 77f299d47fSmrgchgrpcmd= 78f299d47fSmrgchmodcmd=$chmodprog 79f299d47fSmrgchowncmd= 80f299d47fSmrgmvcmd=$mvprog 81f299d47fSmrgrmcmd="$rmprog -f" 82f299d47fSmrgstripcmd= 83f299d47fSmrg 84f299d47fSmrgsrc= 85f299d47fSmrgdst= 86f299d47fSmrgdir_arg= 87f299d47fSmrgdst_arg= 88f299d47fSmrg 89f299d47fSmrgcopy_on_change=false 9005641e18Smrgis_target_a_directory=possibly 91f299d47fSmrg 92f299d47fSmrgusage="\ 93f299d47fSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94f299d47fSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95f299d47fSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96f299d47fSmrg or: $0 [OPTION]... -d DIRECTORIES... 97f299d47fSmrg 98f299d47fSmrgIn the 1st form, copy SRCFILE to DSTFILE. 99f299d47fSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100f299d47fSmrgIn the 4th, create DIRECTORIES. 101f299d47fSmrg 102f299d47fSmrgOptions: 103f299d47fSmrg --help display this help and exit. 104f299d47fSmrg --version display version info and exit. 105f299d47fSmrg 106f299d47fSmrg -c (ignored) 10798d75b17Smrg -C install only if different (preserve data modification time) 108f299d47fSmrg -d create directories instead of installing files. 109f299d47fSmrg -g GROUP $chgrpprog installed files to GROUP. 110f299d47fSmrg -m MODE $chmodprog installed files to MODE. 111f299d47fSmrg -o USER $chownprog installed files to USER. 11298d75b17Smrg -p pass -p to $cpprog. 113f299d47fSmrg -s $stripprog installed files. 11498d75b17Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115f299d47fSmrg -t DIRECTORY install into DIRECTORY. 116f299d47fSmrg -T report an error if DSTFILE is a directory. 117f299d47fSmrg 118f299d47fSmrgEnvironment variables override the default commands: 119f299d47fSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120f299d47fSmrg RMPROG STRIPPROG 12198d75b17Smrg 12298d75b17SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 12398d75b17Smrgit's up to you to specify -f if you want it. 12498d75b17Smrg 12598d75b17SmrgIf -S is not specified, no backups are attempted. 12698d75b17Smrg 12798d75b17SmrgEmail bug reports to bug-automake@gnu.org. 12898d75b17SmrgAutomake home page: https://www.gnu.org/software/automake/ 129f299d47fSmrg" 130f299d47fSmrg 131f299d47fSmrgwhile test $# -ne 0; do 132f299d47fSmrg case $1 in 133f299d47fSmrg -c) ;; 134f299d47fSmrg 135f299d47fSmrg -C) copy_on_change=true;; 136f299d47fSmrg 137f299d47fSmrg -d) dir_arg=true;; 138f299d47fSmrg 139f299d47fSmrg -g) chgrpcmd="$chgrpprog $2" 14005641e18Smrg shift;; 141f299d47fSmrg 142f299d47fSmrg --help) echo "$usage"; exit $?;; 143f299d47fSmrg 144f299d47fSmrg -m) mode=$2 14505641e18Smrg case $mode in 14605641e18Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 14705641e18Smrg echo "$0: invalid mode: $mode" >&2 14805641e18Smrg exit 1;; 14905641e18Smrg esac 15005641e18Smrg shift;; 151f299d47fSmrg 152f299d47fSmrg -o) chowncmd="$chownprog $2" 15305641e18Smrg shift;; 154f299d47fSmrg 15598d75b17Smrg -p) cpprog="$cpprog -p";; 15698d75b17Smrg 157f299d47fSmrg -s) stripcmd=$stripprog;; 158f299d47fSmrg 15998d75b17Smrg -S) backupsuffix="$2" 16098d75b17Smrg shift;; 16198d75b17Smrg 16205641e18Smrg -t) 16305641e18Smrg is_target_a_directory=always 16405641e18Smrg dst_arg=$2 16505641e18Smrg # Protect names problematic for 'test' and other utilities. 16605641e18Smrg case $dst_arg in 16705641e18Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16805641e18Smrg esac 16905641e18Smrg shift;; 170f299d47fSmrg 17105641e18Smrg -T) is_target_a_directory=never;; 172f299d47fSmrg 173f299d47fSmrg --version) echo "$0 $scriptversion"; exit $?;; 174f299d47fSmrg 17505641e18Smrg --) shift 17605641e18Smrg break;; 177f299d47fSmrg 17805641e18Smrg -*) echo "$0: invalid option: $1" >&2 17905641e18Smrg exit 1;; 180f299d47fSmrg 181f299d47fSmrg *) break;; 182f299d47fSmrg esac 183f299d47fSmrg shift 184f299d47fSmrgdone 185f299d47fSmrg 18605641e18Smrg# We allow the use of options -d and -T together, by making -d 18705641e18Smrg# take the precedence; this is for compatibility with GNU install. 18805641e18Smrg 18905641e18Smrgif test -n "$dir_arg"; then 19005641e18Smrg if test -n "$dst_arg"; then 19105641e18Smrg echo "$0: target directory not allowed when installing a directory." >&2 19205641e18Smrg exit 1 19305641e18Smrg fi 19405641e18Smrgfi 19505641e18Smrg 196f299d47fSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197f299d47fSmrg # When -d is used, all remaining arguments are directories to create. 198f299d47fSmrg # When -t is used, the destination is already specified. 199f299d47fSmrg # Otherwise, the last argument is the destination. Remove it from $@. 200f299d47fSmrg for arg 201f299d47fSmrg do 202f299d47fSmrg if test -n "$dst_arg"; then 203f299d47fSmrg # $@ is not empty: it contains at least $arg. 204f299d47fSmrg set fnord "$@" "$dst_arg" 205f299d47fSmrg shift # fnord 206f299d47fSmrg fi 207f299d47fSmrg shift # arg 208f299d47fSmrg dst_arg=$arg 20905641e18Smrg # Protect names problematic for 'test' and other utilities. 2101a2dd139Smrg case $dst_arg in 2111a2dd139Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 2121a2dd139Smrg esac 213f299d47fSmrg done 214f299d47fSmrgfi 215f299d47fSmrg 216f299d47fSmrgif test $# -eq 0; then 217f299d47fSmrg if test -z "$dir_arg"; then 218f299d47fSmrg echo "$0: no input file specified." >&2 219f299d47fSmrg exit 1 220f299d47fSmrg fi 22105641e18Smrg # It's OK to call 'install-sh -d' without argument. 222f299d47fSmrg # This can happen when creating conditional directories. 223f299d47fSmrg exit 0 224f299d47fSmrgfi 225f299d47fSmrg 22605641e18Smrgif test -z "$dir_arg"; then 22705641e18Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 22805641e18Smrg if test ! -d "$dst_arg"; then 22905641e18Smrg echo "$0: $dst_arg: Is not a directory." >&2 23005641e18Smrg exit 1 23105641e18Smrg fi 23205641e18Smrg fi 23305641e18Smrgfi 23405641e18Smrg 235f299d47fSmrgif test -z "$dir_arg"; then 2361a2dd139Smrg do_exit='(exit $ret); exit $ret' 2371a2dd139Smrg trap "ret=129; $do_exit" 1 2381a2dd139Smrg trap "ret=130; $do_exit" 2 2391a2dd139Smrg trap "ret=141; $do_exit" 13 2401a2dd139Smrg trap "ret=143; $do_exit" 15 241f299d47fSmrg 242f299d47fSmrg # Set umask so as not to create temps with too-generous modes. 243f299d47fSmrg # However, 'strip' requires both read and write access to temps. 244f299d47fSmrg case $mode in 245f299d47fSmrg # Optimize common cases. 246f299d47fSmrg *644) cp_umask=133;; 247f299d47fSmrg *755) cp_umask=22;; 248f299d47fSmrg 249f299d47fSmrg *[0-7]) 250f299d47fSmrg if test -z "$stripcmd"; then 25105641e18Smrg u_plus_rw= 252f299d47fSmrg else 25305641e18Smrg u_plus_rw='% 200' 254f299d47fSmrg fi 255f299d47fSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256f299d47fSmrg *) 257f299d47fSmrg if test -z "$stripcmd"; then 25805641e18Smrg u_plus_rw= 259f299d47fSmrg else 26005641e18Smrg u_plus_rw=,u+rw 261f299d47fSmrg fi 262f299d47fSmrg cp_umask=$mode$u_plus_rw;; 263f299d47fSmrg esac 264f299d47fSmrgfi 265f299d47fSmrg 266f299d47fSmrgfor src 267f299d47fSmrgdo 26805641e18Smrg # Protect names problematic for 'test' and other utilities. 269f299d47fSmrg case $src in 2701a2dd139Smrg -* | [=\(\)!]) src=./$src;; 271f299d47fSmrg esac 272f299d47fSmrg 273f299d47fSmrg if test -n "$dir_arg"; then 274f299d47fSmrg dst=$src 275f299d47fSmrg dstdir=$dst 276f299d47fSmrg test -d "$dstdir" 277f299d47fSmrg dstdir_status=$? 27898d75b17Smrg # Don't chown directories that already exist. 27998d75b17Smrg if test $dstdir_status = 0; then 28098d75b17Smrg chowncmd="" 28198d75b17Smrg fi 282f299d47fSmrg else 283f299d47fSmrg 284f299d47fSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285f299d47fSmrg # might cause directories to be created, which would be especially bad 286f299d47fSmrg # if $src (and thus $dsttmp) contains '*'. 287f299d47fSmrg if test ! -f "$src" && test ! -d "$src"; then 288f299d47fSmrg echo "$0: $src does not exist." >&2 289f299d47fSmrg exit 1 290f299d47fSmrg fi 291f299d47fSmrg 292f299d47fSmrg if test -z "$dst_arg"; then 293f299d47fSmrg echo "$0: no destination specified." >&2 294f299d47fSmrg exit 1 295f299d47fSmrg fi 296f299d47fSmrg dst=$dst_arg 297f299d47fSmrg 29898d75b17Smrg # If destination is a directory, append the input filename. 299f299d47fSmrg if test -d "$dst"; then 30005641e18Smrg if test "$is_target_a_directory" = never; then 30105641e18Smrg echo "$0: $dst_arg: Is a directory" >&2 30205641e18Smrg exit 1 303f299d47fSmrg fi 304f299d47fSmrg dstdir=$dst 30598d75b17Smrg dstbase=`basename "$src"` 30698d75b17Smrg case $dst in 30798d75b17Smrg */) dst=$dst$dstbase;; 30898d75b17Smrg *) dst=$dst/$dstbase;; 30998d75b17Smrg esac 310f299d47fSmrg dstdir_status=0 311f299d47fSmrg else 31205641e18Smrg dstdir=`dirname "$dst"` 313f299d47fSmrg test -d "$dstdir" 314f299d47fSmrg dstdir_status=$? 315f299d47fSmrg fi 316f299d47fSmrg fi 317f299d47fSmrg 31898d75b17Smrg case $dstdir in 31998d75b17Smrg */) dstdirslash=$dstdir;; 32098d75b17Smrg *) dstdirslash=$dstdir/;; 32198d75b17Smrg esac 32298d75b17Smrg 323f299d47fSmrg obsolete_mkdir_used=false 324f299d47fSmrg 325f299d47fSmrg if test $dstdir_status != 0; then 326f299d47fSmrg case $posix_mkdir in 327f299d47fSmrg '') 32805641e18Smrg # With -d, create the new directory with the user-specified mode. 32905641e18Smrg # Otherwise, rely on $mkdir_umask. 33005641e18Smrg if test -n "$dir_arg"; then 33105641e18Smrg mkdir_mode=-m$mode 33205641e18Smrg else 33305641e18Smrg mkdir_mode= 33405641e18Smrg fi 33505641e18Smrg 33605641e18Smrg posix_mkdir=false 33798d75b17Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 33898d75b17Smrg # here however when possible just to lower collision chance. 33998d75b17Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34098d75b17Smrg 34198d75b17Smrg trap ' 34298d75b17Smrg ret=$? 34398d75b17Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 34498d75b17Smrg exit $ret 34598d75b17Smrg ' 0 34698d75b17Smrg 34798d75b17Smrg # Because "mkdir -p" follows existing symlinks and we likely work 34898d75b17Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 34998d75b17Smrg # directory is successfully created first before we actually test 35098d75b17Smrg # 'mkdir -p'. 35198d75b17Smrg if (umask $mkdir_umask && 35298d75b17Smrg $mkdirprog $mkdir_mode "$tmpdir" && 35398d75b17Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 35498d75b17Smrg then 35598d75b17Smrg if test -z "$dir_arg" || { 35698d75b17Smrg # Check for POSIX incompatibilities with -m. 35798d75b17Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35898d75b17Smrg # other-writable bit of parent directory when it shouldn't. 35998d75b17Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 36098d75b17Smrg test_tmpdir="$tmpdir/a" 36198d75b17Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 36298d75b17Smrg case $ls_ld_tmpdir in 36398d75b17Smrg d????-?r-*) different_mode=700;; 36498d75b17Smrg d????-?--*) different_mode=755;; 36598d75b17Smrg *) false;; 36698d75b17Smrg esac && 36798d75b17Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 36898d75b17Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36998d75b17Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 37098d75b17Smrg } 37198d75b17Smrg } 37298d75b17Smrg then posix_mkdir=: 37398d75b17Smrg fi 37498d75b17Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 37598d75b17Smrg else 37698d75b17Smrg # Remove any dirs left behind by ancient mkdir implementations. 37798d75b17Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 37898d75b17Smrg fi 37998d75b17Smrg trap '' 0;; 380f299d47fSmrg esac 381f299d47fSmrg 382f299d47fSmrg if 383f299d47fSmrg $posix_mkdir && ( 38405641e18Smrg umask $mkdir_umask && 38505641e18Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386f299d47fSmrg ) 387f299d47fSmrg then : 388f299d47fSmrg else 389f299d47fSmrg 39098d75b17Smrg # mkdir does not conform to POSIX, 391f299d47fSmrg # or it failed possibly due to a race condition. Create the 392f299d47fSmrg # directory the slow way, step by step, checking for races as we go. 393f299d47fSmrg 394f299d47fSmrg case $dstdir in 39505641e18Smrg /*) prefix='/';; 39605641e18Smrg [-=\(\)!]*) prefix='./';; 39705641e18Smrg *) prefix='';; 398f299d47fSmrg esac 399f299d47fSmrg 400f299d47fSmrg oIFS=$IFS 401f299d47fSmrg IFS=/ 40205641e18Smrg set -f 403f299d47fSmrg set fnord $dstdir 404f299d47fSmrg shift 40505641e18Smrg set +f 406f299d47fSmrg IFS=$oIFS 407f299d47fSmrg 408f299d47fSmrg prefixes= 409f299d47fSmrg 410f299d47fSmrg for d 411f299d47fSmrg do 41205641e18Smrg test X"$d" = X && continue 41305641e18Smrg 41405641e18Smrg prefix=$prefix$d 41505641e18Smrg if test -d "$prefix"; then 41605641e18Smrg prefixes= 41705641e18Smrg else 41805641e18Smrg if $posix_mkdir; then 41998d75b17Smrg (umask $mkdir_umask && 42005641e18Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42105641e18Smrg # Don't fail if two instances are running concurrently. 42205641e18Smrg test -d "$prefix" || exit 1 42305641e18Smrg else 42405641e18Smrg case $prefix in 42505641e18Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42605641e18Smrg *) qprefix=$prefix;; 42705641e18Smrg esac 42805641e18Smrg prefixes="$prefixes '$qprefix'" 42905641e18Smrg fi 43005641e18Smrg fi 43105641e18Smrg prefix=$prefix/ 432f299d47fSmrg done 433f299d47fSmrg 434f299d47fSmrg if test -n "$prefixes"; then 43505641e18Smrg # Don't fail if two instances are running concurrently. 43605641e18Smrg (umask $mkdir_umask && 43705641e18Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 43805641e18Smrg test -d "$dstdir" || exit 1 43905641e18Smrg obsolete_mkdir_used=true 440f299d47fSmrg fi 441f299d47fSmrg fi 442f299d47fSmrg fi 443f299d47fSmrg 444f299d47fSmrg if test -n "$dir_arg"; then 445f299d47fSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446f299d47fSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447f299d47fSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448f299d47fSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449f299d47fSmrg else 450f299d47fSmrg 451f299d47fSmrg # Make a couple of temp file names in the proper directory. 45298d75b17Smrg dsttmp=${dstdirslash}_inst.$$_ 45398d75b17Smrg rmtmp=${dstdirslash}_rm.$$_ 454f299d47fSmrg 455f299d47fSmrg # Trap to clean up those temp files at exit. 456f299d47fSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457f299d47fSmrg 458f299d47fSmrg # Copy the file name to the temp name. 45998d75b17Smrg (umask $cp_umask && 46098d75b17Smrg { test -z "$stripcmd" || { 46198d75b17Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 46298d75b17Smrg # which would cause strip to fail. 46398d75b17Smrg if test -z "$doit"; then 46498d75b17Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 46598d75b17Smrg else 46698d75b17Smrg $doit touch "$dsttmp" 46798d75b17Smrg fi 46898d75b17Smrg } 46998d75b17Smrg } && 47098d75b17Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471f299d47fSmrg 472f299d47fSmrg # and set any options; do chmod last to preserve setuid bits. 473f299d47fSmrg # 474f299d47fSmrg # If any of these fail, we abort the whole thing. If we want to 475f299d47fSmrg # ignore errors from any of these, just make sure not to ignore 476f299d47fSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477f299d47fSmrg # 478f299d47fSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479f299d47fSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480f299d47fSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481f299d47fSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482f299d47fSmrg 483f299d47fSmrg # If -C, don't bother to copy if it wouldn't change the file. 484f299d47fSmrg if $copy_on_change && 48505641e18Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48605641e18Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48705641e18Smrg set -f && 488f299d47fSmrg set X $old && old=:$2:$4:$5:$6 && 489f299d47fSmrg set X $new && new=:$2:$4:$5:$6 && 49005641e18Smrg set +f && 491f299d47fSmrg test "$old" = "$new" && 492f299d47fSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493f299d47fSmrg then 494f299d47fSmrg rm -f "$dsttmp" 495f299d47fSmrg else 49698d75b17Smrg # If $backupsuffix is set, and the file being installed 49798d75b17Smrg # already exists, attempt a backup. Don't worry if it fails, 49898d75b17Smrg # e.g., if mv doesn't support -f. 49998d75b17Smrg if test -n "$backupsuffix" && test -f "$dst"; then 50098d75b17Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 50198d75b17Smrg fi 50298d75b17Smrg 503f299d47fSmrg # Rename the file to the real destination. 504f299d47fSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505f299d47fSmrg 506f299d47fSmrg # The rename failed, perhaps because mv can't rename something else 507f299d47fSmrg # to itself, or perhaps because mv is so ancient that it does not 508f299d47fSmrg # support -f. 509f299d47fSmrg { 51005641e18Smrg # Now remove or move aside any old file at destination location. 51105641e18Smrg # We try this two ways since rm can't unlink itself on some 51205641e18Smrg # systems and the destination file might be busy for other 51305641e18Smrg # reasons. In this case, the final cleanup might fail but the new 51405641e18Smrg # file should still install successfully. 51505641e18Smrg { 51605641e18Smrg test ! -f "$dst" || 51798d75b17Smrg $doit $rmcmd "$dst" 2>/dev/null || 51805641e18Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 51998d75b17Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 52005641e18Smrg } || 52105641e18Smrg { echo "$0: cannot unlink or rename $dst" >&2 52205641e18Smrg (exit 1); exit 1 52305641e18Smrg } 52405641e18Smrg } && 52505641e18Smrg 52605641e18Smrg # Now rename the file to the real destination. 52705641e18Smrg $doit $mvcmd "$dsttmp" "$dst" 528f299d47fSmrg } 529f299d47fSmrg fi || exit 1 530f299d47fSmrg 531f299d47fSmrg trap '' 0 532f299d47fSmrg fi 533f299d47fSmrgdone 534f299d47fSmrg 535f299d47fSmrg# Local variables: 53698d75b17Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537f299d47fSmrg# time-stamp-start: "scriptversion=" 538f299d47fSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 53998d75b17Smrg# time-stamp-time-zone: "UTC0" 540aa98702cSmrg# time-stamp-end: "; # UTC" 541f299d47fSmrg# End: 542