1ff559fabSmrg#!/bin/sh 2ff559fabSmrg# install - install a program, script, or datafile 3ff559fabSmrg 4515ec619Smrgscriptversion=2020-11-14.01; # UTC 5ff559fabSmrg 6ff559fabSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7ff559fabSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8ff559fabSmrg# following copyright and license. 9ff559fabSmrg# 10ff559fabSmrg# Copyright (C) 1994 X Consortium 11ff559fabSmrg# 12ff559fabSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13ff559fabSmrg# of this software and associated documentation files (the "Software"), to 14ff559fabSmrg# deal in the Software without restriction, including without limitation the 15ff559fabSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16ff559fabSmrg# sell copies of the Software, and to permit persons to whom the Software is 17ff559fabSmrg# furnished to do so, subject to the following conditions: 18ff559fabSmrg# 19ff559fabSmrg# The above copyright notice and this permission notice shall be included in 20ff559fabSmrg# all copies or substantial portions of the Software. 21ff559fabSmrg# 22ff559fabSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23ff559fabSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24ff559fabSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25ff559fabSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26ff559fabSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27ff559fabSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28ff559fabSmrg# 29ff559fabSmrg# Except as contained in this notice, the name of the X Consortium shall not 30ff559fabSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31ff559fabSmrg# ings in this Software without prior written authorization from the X Consor- 32ff559fabSmrg# tium. 33ff559fabSmrg# 34ff559fabSmrg# 35ff559fabSmrg# FSF changes to this file are in the public domain. 36ff559fabSmrg# 37ff559fabSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38fc544a13Smrg# 'make' implicit rules from creating a file called install from it 39ff559fabSmrg# when there is no Makefile. 40ff559fabSmrg# 41ff559fabSmrg# This script is compatible with the BSD install script, but was written 427a3b38f7Smrg# from scratch. 437a3b38f7Smrg 44fc544a13Smrgtab=' ' 457a3b38f7Smrgnl=' 467a3b38f7Smrg' 47fc544a13SmrgIFS=" $tab$nl" 48ff559fabSmrg 49fc544a13Smrg# Set DOITPROG to "echo" to test this script. 50ff559fabSmrg 517a3b38f7Smrgdoit=${DOITPROG-} 52fc544a13Smrgdoit_exec=${doit:-exec} 53ff559fabSmrg 547a3b38f7Smrg# Put in absolute file names if you don't have them in your path; 557a3b38f7Smrg# or use environment vars. 567a3b38f7Smrg 577a3b38f7Smrgchgrpprog=${CHGRPPROG-chgrp} 587a3b38f7Smrgchmodprog=${CHMODPROG-chmod} 597a3b38f7Smrgchownprog=${CHOWNPROG-chown} 607a3b38f7Smrgcmpprog=${CMPPROG-cmp} 617a3b38f7Smrgcpprog=${CPPROG-cp} 627a3b38f7Smrgmkdirprog=${MKDIRPROG-mkdir} 637a3b38f7Smrgmvprog=${MVPROG-mv} 647a3b38f7Smrgrmprog=${RMPROG-rm} 657a3b38f7Smrgstripprog=${STRIPPROG-strip} 667a3b38f7Smrg 677a3b38f7Smrgposix_mkdir= 687a3b38f7Smrg 697a3b38f7Smrg# Desired mode of installed file. 707a3b38f7Smrgmode=0755 71ff559fabSmrg 72515ec619Smrg# Create dirs (including intermediate dirs) using mode 755. 73515ec619Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74515ec619Smrgmkdir_umask=22 75515ec619Smrg 76515ec619Smrgbackupsuffix= 77ff559fabSmrgchgrpcmd= 787a3b38f7Smrgchmodcmd=$chmodprog 797a3b38f7Smrgchowncmd= 807a3b38f7Smrgmvcmd=$mvprog 81ff559fabSmrgrmcmd="$rmprog -f" 827a3b38f7Smrgstripcmd= 837a3b38f7Smrg 84ff559fabSmrgsrc= 85ff559fabSmrgdst= 86ff559fabSmrgdir_arg= 877a3b38f7Smrgdst_arg= 887a3b38f7Smrg 897a3b38f7Smrgcopy_on_change=false 90fc544a13Smrgis_target_a_directory=possibly 91ff559fabSmrg 927a3b38f7Smrgusage="\ 937a3b38f7SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94ff559fabSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95ff559fabSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96ff559fabSmrg or: $0 [OPTION]... -d DIRECTORIES... 97ff559fabSmrg 98ff559fabSmrgIn the 1st form, copy SRCFILE to DSTFILE. 99ff559fabSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100ff559fabSmrgIn the 4th, create DIRECTORIES. 101ff559fabSmrg 102ff559fabSmrgOptions: 1037a3b38f7Smrg --help display this help and exit. 1047a3b38f7Smrg --version display version info and exit. 1057a3b38f7Smrg 1067a3b38f7Smrg -c (ignored) 107515ec619Smrg -C install only if different (preserve data modification time) 1087a3b38f7Smrg -d create directories instead of installing files. 1097a3b38f7Smrg -g GROUP $chgrpprog installed files to GROUP. 1107a3b38f7Smrg -m MODE $chmodprog installed files to MODE. 1117a3b38f7Smrg -o USER $chownprog installed files to USER. 112515ec619Smrg -p pass -p to $cpprog. 1137a3b38f7Smrg -s $stripprog installed files. 114515ec619Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 1157a3b38f7Smrg -t DIRECTORY install into DIRECTORY. 1167a3b38f7Smrg -T report an error if DSTFILE is a directory. 117ff559fabSmrg 118ff559fabSmrgEnvironment variables override the default commands: 1197a3b38f7Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1207a3b38f7Smrg RMPROG STRIPPROG 121515ec619Smrg 122515ec619SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123515ec619Smrgit's up to you to specify -f if you want it. 124515ec619Smrg 125515ec619SmrgIf -S is not specified, no backups are attempted. 126515ec619Smrg 127515ec619SmrgEmail bug reports to bug-automake@gnu.org. 128515ec619SmrgAutomake home page: https://www.gnu.org/software/automake/ 129ff559fabSmrg" 130ff559fabSmrg 1317a3b38f7Smrgwhile test $# -ne 0; do 132ff559fabSmrg case $1 in 1337a3b38f7Smrg -c) ;; 1347a3b38f7Smrg 1357a3b38f7Smrg -C) copy_on_change=true;; 136ff559fabSmrg 1377a3b38f7Smrg -d) dir_arg=true;; 138ff559fabSmrg 139ff559fabSmrg -g) chgrpcmd="$chgrpprog $2" 140fc544a13Smrg shift;; 141ff559fabSmrg 142ff559fabSmrg --help) echo "$usage"; exit $?;; 143ff559fabSmrg 1447a3b38f7Smrg -m) mode=$2 145fc544a13Smrg case $mode in 146fc544a13Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147fc544a13Smrg echo "$0: invalid mode: $mode" >&2 148fc544a13Smrg exit 1;; 149fc544a13Smrg esac 150fc544a13Smrg shift;; 151ff559fabSmrg 152ff559fabSmrg -o) chowncmd="$chownprog $2" 153fc544a13Smrg shift;; 154ff559fabSmrg 155515ec619Smrg -p) cpprog="$cpprog -p";; 156515ec619Smrg 1577a3b38f7Smrg -s) stripcmd=$stripprog;; 158ff559fabSmrg 159515ec619Smrg -S) backupsuffix="$2" 160515ec619Smrg shift;; 161515ec619Smrg 162fc544a13Smrg -t) 163fc544a13Smrg is_target_a_directory=always 164fc544a13Smrg dst_arg=$2 165fc544a13Smrg # Protect names problematic for 'test' and other utilities. 166fc544a13Smrg case $dst_arg in 167fc544a13Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168fc544a13Smrg esac 169fc544a13Smrg shift;; 170ff559fabSmrg 171fc544a13Smrg -T) is_target_a_directory=never;; 172ff559fabSmrg 173ff559fabSmrg --version) echo "$0 $scriptversion"; exit $?;; 174ff559fabSmrg 175fc544a13Smrg --) shift 176fc544a13Smrg break;; 1777a3b38f7Smrg 178fc544a13Smrg -*) echo "$0: invalid option: $1" >&2 179fc544a13Smrg exit 1;; 1807a3b38f7Smrg 1817a3b38f7Smrg *) break;; 182ff559fabSmrg esac 1837a3b38f7Smrg shift 184ff559fabSmrgdone 185ff559fabSmrg 186fc544a13Smrg# We allow the use of options -d and -T together, by making -d 187fc544a13Smrg# take the precedence; this is for compatibility with GNU install. 188fc544a13Smrg 189fc544a13Smrgif test -n "$dir_arg"; then 190fc544a13Smrg if test -n "$dst_arg"; then 191fc544a13Smrg echo "$0: target directory not allowed when installing a directory." >&2 192fc544a13Smrg exit 1 193fc544a13Smrg fi 194fc544a13Smrgfi 195fc544a13Smrg 1967a3b38f7Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1977a3b38f7Smrg # When -d is used, all remaining arguments are directories to create. 1987a3b38f7Smrg # When -t is used, the destination is already specified. 1997a3b38f7Smrg # Otherwise, the last argument is the destination. Remove it from $@. 2007a3b38f7Smrg for arg 2017a3b38f7Smrg do 2027a3b38f7Smrg if test -n "$dst_arg"; then 2037a3b38f7Smrg # $@ is not empty: it contains at least $arg. 2047a3b38f7Smrg set fnord "$@" "$dst_arg" 2057a3b38f7Smrg shift # fnord 2067a3b38f7Smrg fi 2077a3b38f7Smrg shift # arg 2087a3b38f7Smrg dst_arg=$arg 209fc544a13Smrg # Protect names problematic for 'test' and other utilities. 210fc544a13Smrg case $dst_arg in 211fc544a13Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212fc544a13Smrg esac 2137a3b38f7Smrg done 2147a3b38f7Smrgfi 2157a3b38f7Smrg 2167a3b38f7Smrgif test $# -eq 0; then 217ff559fabSmrg if test -z "$dir_arg"; then 218ff559fabSmrg echo "$0: no input file specified." >&2 219ff559fabSmrg exit 1 220ff559fabSmrg fi 221fc544a13Smrg # It's OK to call 'install-sh -d' without argument. 222ff559fabSmrg # This can happen when creating conditional directories. 223ff559fabSmrg exit 0 224ff559fabSmrgfi 225ff559fabSmrg 2267a3b38f7Smrgif test -z "$dir_arg"; then 227fc544a13Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228fc544a13Smrg if test ! -d "$dst_arg"; then 229fc544a13Smrg echo "$0: $dst_arg: Is not a directory." >&2 230fc544a13Smrg exit 1 231fc544a13Smrg fi 232fc544a13Smrg fi 233fc544a13Smrgfi 234fc544a13Smrg 235fc544a13Smrgif test -z "$dir_arg"; then 236fc544a13Smrg do_exit='(exit $ret); exit $ret' 237fc544a13Smrg trap "ret=129; $do_exit" 1 238fc544a13Smrg trap "ret=130; $do_exit" 2 239fc544a13Smrg trap "ret=141; $do_exit" 13 240fc544a13Smrg trap "ret=143; $do_exit" 15 2417a3b38f7Smrg 2427a3b38f7Smrg # Set umask so as not to create temps with too-generous modes. 2437a3b38f7Smrg # However, 'strip' requires both read and write access to temps. 2447a3b38f7Smrg case $mode in 2457a3b38f7Smrg # Optimize common cases. 2467a3b38f7Smrg *644) cp_umask=133;; 2477a3b38f7Smrg *755) cp_umask=22;; 2487a3b38f7Smrg 2497a3b38f7Smrg *[0-7]) 2507a3b38f7Smrg if test -z "$stripcmd"; then 251fc544a13Smrg u_plus_rw= 2527a3b38f7Smrg else 253fc544a13Smrg u_plus_rw='% 200' 2547a3b38f7Smrg fi 2557a3b38f7Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2567a3b38f7Smrg *) 2577a3b38f7Smrg if test -z "$stripcmd"; then 258fc544a13Smrg u_plus_rw= 2597a3b38f7Smrg else 260fc544a13Smrg u_plus_rw=,u+rw 2617a3b38f7Smrg fi 2627a3b38f7Smrg cp_umask=$mode$u_plus_rw;; 2637a3b38f7Smrg esac 2647a3b38f7Smrgfi 2657a3b38f7Smrg 266ff559fabSmrgfor src 267ff559fabSmrgdo 268fc544a13Smrg # Protect names problematic for 'test' and other utilities. 269ff559fabSmrg case $src in 270fc544a13Smrg -* | [=\(\)!]) src=./$src;; 271ff559fabSmrg esac 272ff559fabSmrg 273ff559fabSmrg if test -n "$dir_arg"; then 274ff559fabSmrg dst=$src 2757a3b38f7Smrg dstdir=$dst 2767a3b38f7Smrg test -d "$dstdir" 2777a3b38f7Smrg dstdir_status=$? 278515ec619Smrg # Don't chown directories that already exist. 279515ec619Smrg if test $dstdir_status = 0; then 280515ec619Smrg chowncmd="" 281515ec619Smrg fi 282ff559fabSmrg else 2837a3b38f7Smrg 284ff559fabSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285ff559fabSmrg # might cause directories to be created, which would be especially bad 286ff559fabSmrg # if $src (and thus $dsttmp) contains '*'. 287ff559fabSmrg if test ! -f "$src" && test ! -d "$src"; then 288ff559fabSmrg echo "$0: $src does not exist." >&2 289ff559fabSmrg exit 1 290ff559fabSmrg fi 291ff559fabSmrg 2927a3b38f7Smrg if test -z "$dst_arg"; then 293ff559fabSmrg echo "$0: no destination specified." >&2 294ff559fabSmrg exit 1 295ff559fabSmrg fi 2967a3b38f7Smrg dst=$dst_arg 297ff559fabSmrg 298515ec619Smrg # If destination is a directory, append the input filename. 299ff559fabSmrg if test -d "$dst"; then 300fc544a13Smrg if test "$is_target_a_directory" = never; then 301fc544a13Smrg echo "$0: $dst_arg: Is a directory" >&2 302fc544a13Smrg exit 1 303ff559fabSmrg fi 3047a3b38f7Smrg dstdir=$dst 305515ec619Smrg dstbase=`basename "$src"` 306515ec619Smrg case $dst in 307515ec619Smrg */) dst=$dst$dstbase;; 308515ec619Smrg *) dst=$dst/$dstbase;; 309515ec619Smrg esac 3107a3b38f7Smrg dstdir_status=0 3117a3b38f7Smrg else 312fc544a13Smrg dstdir=`dirname "$dst"` 3137a3b38f7Smrg test -d "$dstdir" 3147a3b38f7Smrg dstdir_status=$? 315ff559fabSmrg fi 316ff559fabSmrg fi 317ff559fabSmrg 318515ec619Smrg case $dstdir in 319515ec619Smrg */) dstdirslash=$dstdir;; 320515ec619Smrg *) dstdirslash=$dstdir/;; 321515ec619Smrg esac 322515ec619Smrg 3237a3b38f7Smrg obsolete_mkdir_used=false 3247a3b38f7Smrg 3257a3b38f7Smrg if test $dstdir_status != 0; then 3267a3b38f7Smrg case $posix_mkdir in 3277a3b38f7Smrg '') 328fc544a13Smrg # With -d, create the new directory with the user-specified mode. 329fc544a13Smrg # Otherwise, rely on $mkdir_umask. 330fc544a13Smrg if test -n "$dir_arg"; then 331fc544a13Smrg mkdir_mode=-m$mode 332fc544a13Smrg else 333fc544a13Smrg mkdir_mode= 334fc544a13Smrg fi 335fc544a13Smrg 336fc544a13Smrg posix_mkdir=false 337515ec619Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 338515ec619Smrg # here however when possible just to lower collision chance. 339515ec619Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340515ec619Smrg 341515ec619Smrg trap ' 342515ec619Smrg ret=$? 343515ec619Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344515ec619Smrg exit $ret 345515ec619Smrg ' 0 346515ec619Smrg 347515ec619Smrg # Because "mkdir -p" follows existing symlinks and we likely work 348515ec619Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349515ec619Smrg # directory is successfully created first before we actually test 350515ec619Smrg # 'mkdir -p'. 351515ec619Smrg if (umask $mkdir_umask && 352515ec619Smrg $mkdirprog $mkdir_mode "$tmpdir" && 353515ec619Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354515ec619Smrg then 355515ec619Smrg if test -z "$dir_arg" || { 356515ec619Smrg # Check for POSIX incompatibilities with -m. 357515ec619Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358515ec619Smrg # other-writable bit of parent directory when it shouldn't. 359515ec619Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360515ec619Smrg test_tmpdir="$tmpdir/a" 361515ec619Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362515ec619Smrg case $ls_ld_tmpdir in 363515ec619Smrg d????-?r-*) different_mode=700;; 364515ec619Smrg d????-?--*) different_mode=755;; 365515ec619Smrg *) false;; 366515ec619Smrg esac && 367515ec619Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368515ec619Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369515ec619Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370515ec619Smrg } 371515ec619Smrg } 372515ec619Smrg then posix_mkdir=: 373515ec619Smrg fi 374515ec619Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375515ec619Smrg else 376515ec619Smrg # Remove any dirs left behind by ancient mkdir implementations. 377515ec619Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378515ec619Smrg fi 379515ec619Smrg trap '' 0;; 3807a3b38f7Smrg esac 381ff559fabSmrg 3827a3b38f7Smrg if 3837a3b38f7Smrg $posix_mkdir && ( 384fc544a13Smrg umask $mkdir_umask && 385fc544a13Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3867a3b38f7Smrg ) 3877a3b38f7Smrg then : 3887a3b38f7Smrg else 389ff559fabSmrg 390515ec619Smrg # mkdir does not conform to POSIX, 3917a3b38f7Smrg # or it failed possibly due to a race condition. Create the 3927a3b38f7Smrg # directory the slow way, step by step, checking for races as we go. 393ff559fabSmrg 3947a3b38f7Smrg case $dstdir in 395fc544a13Smrg /*) prefix='/';; 396fc544a13Smrg [-=\(\)!]*) prefix='./';; 397fc544a13Smrg *) prefix='';; 3987a3b38f7Smrg esac 399ff559fabSmrg 4007a3b38f7Smrg oIFS=$IFS 4017a3b38f7Smrg IFS=/ 402fc544a13Smrg set -f 4037a3b38f7Smrg set fnord $dstdir 404ff559fabSmrg shift 405fc544a13Smrg set +f 4067a3b38f7Smrg IFS=$oIFS 4077a3b38f7Smrg 4087a3b38f7Smrg prefixes= 4097a3b38f7Smrg 4107a3b38f7Smrg for d 4117a3b38f7Smrg do 412fc544a13Smrg test X"$d" = X && continue 413fc544a13Smrg 414fc544a13Smrg prefix=$prefix$d 415fc544a13Smrg if test -d "$prefix"; then 416fc544a13Smrg prefixes= 417fc544a13Smrg else 418fc544a13Smrg if $posix_mkdir; then 419515ec619Smrg (umask $mkdir_umask && 420fc544a13Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421fc544a13Smrg # Don't fail if two instances are running concurrently. 422fc544a13Smrg test -d "$prefix" || exit 1 423fc544a13Smrg else 424fc544a13Smrg case $prefix in 425fc544a13Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426fc544a13Smrg *) qprefix=$prefix;; 427fc544a13Smrg esac 428fc544a13Smrg prefixes="$prefixes '$qprefix'" 429fc544a13Smrg fi 430fc544a13Smrg fi 431fc544a13Smrg prefix=$prefix/ 4327a3b38f7Smrg done 4337a3b38f7Smrg 4347a3b38f7Smrg if test -n "$prefixes"; then 435fc544a13Smrg # Don't fail if two instances are running concurrently. 436fc544a13Smrg (umask $mkdir_umask && 437fc544a13Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 438fc544a13Smrg test -d "$dstdir" || exit 1 439fc544a13Smrg obsolete_mkdir_used=true 440ff559fabSmrg fi 4417a3b38f7Smrg fi 442ff559fabSmrg fi 443ff559fabSmrg 444ff559fabSmrg if test -n "$dir_arg"; then 4457a3b38f7Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4467a3b38f7Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4477a3b38f7Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4487a3b38f7Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449ff559fabSmrg else 450ff559fabSmrg 451ff559fabSmrg # Make a couple of temp file names in the proper directory. 452515ec619Smrg dsttmp=${dstdirslash}_inst.$$_ 453515ec619Smrg rmtmp=${dstdirslash}_rm.$$_ 454ff559fabSmrg 455ff559fabSmrg # Trap to clean up those temp files at exit. 456ff559fabSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457ff559fabSmrg 458ff559fabSmrg # Copy the file name to the temp name. 459515ec619Smrg (umask $cp_umask && 460515ec619Smrg { test -z "$stripcmd" || { 461515ec619Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462515ec619Smrg # which would cause strip to fail. 463515ec619Smrg if test -z "$doit"; then 464515ec619Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 465515ec619Smrg else 466515ec619Smrg $doit touch "$dsttmp" 467515ec619Smrg fi 468515ec619Smrg } 469515ec619Smrg } && 470515ec619Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471ff559fabSmrg 472ff559fabSmrg # and set any options; do chmod last to preserve setuid bits. 473ff559fabSmrg # 474ff559fabSmrg # If any of these fail, we abort the whole thing. If we want to 475ff559fabSmrg # ignore errors from any of these, just make sure not to ignore 476ff559fabSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477ff559fabSmrg # 4787a3b38f7Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4797a3b38f7Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4807a3b38f7Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4817a3b38f7Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4827a3b38f7Smrg 4837a3b38f7Smrg # If -C, don't bother to copy if it wouldn't change the file. 4847a3b38f7Smrg if $copy_on_change && 485fc544a13Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486fc544a13Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487fc544a13Smrg set -f && 4887a3b38f7Smrg set X $old && old=:$2:$4:$5:$6 && 4897a3b38f7Smrg set X $new && new=:$2:$4:$5:$6 && 490fc544a13Smrg set +f && 4917a3b38f7Smrg test "$old" = "$new" && 4927a3b38f7Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4937a3b38f7Smrg then 4947a3b38f7Smrg rm -f "$dsttmp" 4957a3b38f7Smrg else 496515ec619Smrg # If $backupsuffix is set, and the file being installed 497515ec619Smrg # already exists, attempt a backup. Don't worry if it fails, 498515ec619Smrg # e.g., if mv doesn't support -f. 499515ec619Smrg if test -n "$backupsuffix" && test -f "$dst"; then 500515ec619Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501515ec619Smrg fi 502515ec619Smrg 5037a3b38f7Smrg # Rename the file to the real destination. 5047a3b38f7Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 5057a3b38f7Smrg 5067a3b38f7Smrg # The rename failed, perhaps because mv can't rename something else 5077a3b38f7Smrg # to itself, or perhaps because mv is so ancient that it does not 5087a3b38f7Smrg # support -f. 5097a3b38f7Smrg { 510fc544a13Smrg # Now remove or move aside any old file at destination location. 511fc544a13Smrg # We try this two ways since rm can't unlink itself on some 512fc544a13Smrg # systems and the destination file might be busy for other 513fc544a13Smrg # reasons. In this case, the final cleanup might fail but the new 514fc544a13Smrg # file should still install successfully. 515fc544a13Smrg { 516fc544a13Smrg test ! -f "$dst" || 517515ec619Smrg $doit $rmcmd "$dst" 2>/dev/null || 518fc544a13Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519515ec619Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520fc544a13Smrg } || 521fc544a13Smrg { echo "$0: cannot unlink or rename $dst" >&2 522fc544a13Smrg (exit 1); exit 1 523fc544a13Smrg } 524fc544a13Smrg } && 525fc544a13Smrg 526fc544a13Smrg # Now rename the file to the real destination. 527fc544a13Smrg $doit $mvcmd "$dsttmp" "$dst" 5287a3b38f7Smrg } 5297a3b38f7Smrg fi || exit 1 5307a3b38f7Smrg 5317a3b38f7Smrg trap '' 0 5327a3b38f7Smrg fi 533ff559fabSmrgdone 534ff559fabSmrg 535ff559fabSmrg# Local variables: 536515ec619Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537ff559fabSmrg# time-stamp-start: "scriptversion=" 538ff559fabSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539515ec619Smrg# time-stamp-time-zone: "UTC0" 54044dda7b2Smrg# time-stamp-end: "; # UTC" 541ff559fabSmrg# End: 542