1ef981d24Smrg#!/bin/sh 2ef981d24Smrg# install - install a program, script, or datafile 3ef981d24Smrg 4d5637ae9Smrgscriptversion=2020-11-14.01; # UTC 5ef981d24Smrg 6ef981d24Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7ef981d24Smrg# later released in X11R6 (xc/config/util/install.sh) with the 8ef981d24Smrg# following copyright and license. 9ef981d24Smrg# 10ef981d24Smrg# Copyright (C) 1994 X Consortium 11ef981d24Smrg# 12ef981d24Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13ef981d24Smrg# of this software and associated documentation files (the "Software"), to 14ef981d24Smrg# deal in the Software without restriction, including without limitation the 15ef981d24Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16ef981d24Smrg# sell copies of the Software, and to permit persons to whom the Software is 17ef981d24Smrg# furnished to do so, subject to the following conditions: 18ef981d24Smrg# 19ef981d24Smrg# The above copyright notice and this permission notice shall be included in 20ef981d24Smrg# all copies or substantial portions of the Software. 21ef981d24Smrg# 22ef981d24Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23ef981d24Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24ef981d24Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25ef981d24Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26ef981d24Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27ef981d24Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28ef981d24Smrg# 29ef981d24Smrg# Except as contained in this notice, the name of the X Consortium shall not 30ef981d24Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 31ef981d24Smrg# ings in this Software without prior written authorization from the X Consor- 32ef981d24Smrg# tium. 33ef981d24Smrg# 34ef981d24Smrg# 35ef981d24Smrg# FSF changes to this file are in the public domain. 36ef981d24Smrg# 37ef981d24Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38b312a94cSmrg# 'make' implicit rules from creating a file called install from it 39ef981d24Smrg# when there is no Makefile. 40ef981d24Smrg# 41ef981d24Smrg# This script is compatible with the BSD install script, but was written 42ef981d24Smrg# from scratch. 43ef981d24Smrg 44b312a94cSmrgtab=' ' 45ef981d24Smrgnl=' 46ef981d24Smrg' 47b312a94cSmrgIFS=" $tab$nl" 48ef981d24Smrg 49b312a94cSmrg# Set DOITPROG to "echo" to test this script. 50ef981d24Smrg 5165eef222Smrgdoit=${DOITPROG-} 52b312a94cSmrgdoit_exec=${doit:-exec} 53ef981d24Smrg 54ef981d24Smrg# Put in absolute file names if you don't have them in your path; 55ef981d24Smrg# or use environment vars. 56ef981d24Smrg 5765eef222Smrgchgrpprog=${CHGRPPROG-chgrp} 5865eef222Smrgchmodprog=${CHMODPROG-chmod} 5965eef222Smrgchownprog=${CHOWNPROG-chown} 6065eef222Smrgcmpprog=${CMPPROG-cmp} 6165eef222Smrgcpprog=${CPPROG-cp} 6265eef222Smrgmkdirprog=${MKDIRPROG-mkdir} 6365eef222Smrgmvprog=${MVPROG-mv} 6465eef222Smrgrmprog=${RMPROG-rm} 6565eef222Smrgstripprog=${STRIPPROG-strip} 6665eef222Smrg 67ef981d24Smrgposix_mkdir= 68ef981d24Smrg 69ef981d24Smrg# Desired mode of installed file. 70ef981d24Smrgmode=0755 71ef981d24Smrg 72d5637ae9Smrg# Create dirs (including intermediate dirs) using mode 755. 73d5637ae9Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74d5637ae9Smrgmkdir_umask=22 75d5637ae9Smrg 76d5637ae9Smrgbackupsuffix= 7765eef222Smrgchgrpcmd= 78ef981d24Smrgchmodcmd=$chmodprog 79ef981d24Smrgchowncmd= 8065eef222Smrgmvcmd=$mvprog 81ef981d24Smrgrmcmd="$rmprog -f" 8265eef222Smrgstripcmd= 8365eef222Smrg 84ef981d24Smrgsrc= 85ef981d24Smrgdst= 86ef981d24Smrgdir_arg= 8765eef222Smrgdst_arg= 8865eef222Smrg 8965eef222Smrgcopy_on_change=false 90b312a94cSmrgis_target_a_directory=possibly 91ef981d24Smrg 9265eef222Smrgusage="\ 9365eef222SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94ef981d24Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95ef981d24Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96ef981d24Smrg or: $0 [OPTION]... -d DIRECTORIES... 97ef981d24Smrg 98ef981d24SmrgIn the 1st form, copy SRCFILE to DSTFILE. 99ef981d24SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100ef981d24SmrgIn the 4th, create DIRECTORIES. 101ef981d24Smrg 102ef981d24SmrgOptions: 10365eef222Smrg --help display this help and exit. 10465eef222Smrg --version display version info and exit. 10565eef222Smrg 10665eef222Smrg -c (ignored) 107d5637ae9Smrg -C install only if different (preserve data modification time) 10865eef222Smrg -d create directories instead of installing files. 10965eef222Smrg -g GROUP $chgrpprog installed files to GROUP. 11065eef222Smrg -m MODE $chmodprog installed files to MODE. 11165eef222Smrg -o USER $chownprog installed files to USER. 112d5637ae9Smrg -p pass -p to $cpprog. 11365eef222Smrg -s $stripprog installed files. 114d5637ae9Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 11565eef222Smrg -t DIRECTORY install into DIRECTORY. 11665eef222Smrg -T report an error if DSTFILE is a directory. 117ef981d24Smrg 118ef981d24SmrgEnvironment variables override the default commands: 11965eef222Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 12065eef222Smrg RMPROG STRIPPROG 121d5637ae9Smrg 122d5637ae9SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123d5637ae9Smrgit's up to you to specify -f if you want it. 124d5637ae9Smrg 125d5637ae9SmrgIf -S is not specified, no backups are attempted. 126d5637ae9Smrg 127d5637ae9SmrgEmail bug reports to bug-automake@gnu.org. 128d5637ae9SmrgAutomake home page: https://www.gnu.org/software/automake/ 129ef981d24Smrg" 130ef981d24Smrg 131ef981d24Smrgwhile test $# -ne 0; do 132ef981d24Smrg case $1 in 13365eef222Smrg -c) ;; 13465eef222Smrg 13565eef222Smrg -C) copy_on_change=true;; 136ef981d24Smrg 13765eef222Smrg -d) dir_arg=true;; 138ef981d24Smrg 139ef981d24Smrg -g) chgrpcmd="$chgrpprog $2" 140b312a94cSmrg shift;; 141ef981d24Smrg 142ef981d24Smrg --help) echo "$usage"; exit $?;; 143ef981d24Smrg 144ef981d24Smrg -m) mode=$2 145b312a94cSmrg case $mode in 146b312a94cSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147b312a94cSmrg echo "$0: invalid mode: $mode" >&2 148b312a94cSmrg exit 1;; 149b312a94cSmrg esac 150b312a94cSmrg shift;; 151ef981d24Smrg 152ef981d24Smrg -o) chowncmd="$chownprog $2" 153b312a94cSmrg shift;; 154ef981d24Smrg 155d5637ae9Smrg -p) cpprog="$cpprog -p";; 156d5637ae9Smrg 15765eef222Smrg -s) stripcmd=$stripprog;; 158ef981d24Smrg 159d5637ae9Smrg -S) backupsuffix="$2" 160d5637ae9Smrg shift;; 161d5637ae9Smrg 162b312a94cSmrg -t) 163b312a94cSmrg is_target_a_directory=always 164b312a94cSmrg dst_arg=$2 165b312a94cSmrg # Protect names problematic for 'test' and other utilities. 166b312a94cSmrg case $dst_arg in 167b312a94cSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168b312a94cSmrg esac 169b312a94cSmrg shift;; 170ef981d24Smrg 171b312a94cSmrg -T) is_target_a_directory=never;; 172ef981d24Smrg 173ef981d24Smrg --version) echo "$0 $scriptversion"; exit $?;; 174ef981d24Smrg 175b312a94cSmrg --) shift 176b312a94cSmrg break;; 177ef981d24Smrg 178b312a94cSmrg -*) echo "$0: invalid option: $1" >&2 179b312a94cSmrg exit 1;; 180ef981d24Smrg 181ef981d24Smrg *) break;; 182ef981d24Smrg esac 18365eef222Smrg shift 184ef981d24Smrgdone 185ef981d24Smrg 186b312a94cSmrg# We allow the use of options -d and -T together, by making -d 187b312a94cSmrg# take the precedence; this is for compatibility with GNU install. 188b312a94cSmrg 189b312a94cSmrgif test -n "$dir_arg"; then 190b312a94cSmrg if test -n "$dst_arg"; then 191b312a94cSmrg echo "$0: target directory not allowed when installing a directory." >&2 192b312a94cSmrg exit 1 193b312a94cSmrg fi 194b312a94cSmrgfi 195b312a94cSmrg 19665eef222Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197ef981d24Smrg # When -d is used, all remaining arguments are directories to create. 198ef981d24Smrg # When -t is used, the destination is already specified. 199ef981d24Smrg # Otherwise, the last argument is the destination. Remove it from $@. 200ef981d24Smrg for arg 201ef981d24Smrg do 20265eef222Smrg if test -n "$dst_arg"; then 203ef981d24Smrg # $@ is not empty: it contains at least $arg. 20465eef222Smrg set fnord "$@" "$dst_arg" 205ef981d24Smrg shift # fnord 206ef981d24Smrg fi 207ef981d24Smrg shift # arg 20865eef222Smrg dst_arg=$arg 209b312a94cSmrg # Protect names problematic for 'test' and other utilities. 210b312a94cSmrg case $dst_arg in 211b312a94cSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212b312a94cSmrg esac 213ef981d24Smrg done 214ef981d24Smrgfi 215ef981d24Smrg 216ef981d24Smrgif test $# -eq 0; then 217ef981d24Smrg if test -z "$dir_arg"; then 218ef981d24Smrg echo "$0: no input file specified." >&2 219ef981d24Smrg exit 1 220ef981d24Smrg fi 221b312a94cSmrg # It's OK to call 'install-sh -d' without argument. 222ef981d24Smrg # This can happen when creating conditional directories. 223ef981d24Smrg exit 0 224ef981d24Smrgfi 225ef981d24Smrg 226ef981d24Smrgif test -z "$dir_arg"; then 227b312a94cSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228b312a94cSmrg if test ! -d "$dst_arg"; then 229b312a94cSmrg echo "$0: $dst_arg: Is not a directory." >&2 230b312a94cSmrg exit 1 231b312a94cSmrg fi 232b312a94cSmrg fi 233b312a94cSmrgfi 234b312a94cSmrg 235b312a94cSmrgif test -z "$dir_arg"; then 236b312a94cSmrg do_exit='(exit $ret); exit $ret' 237b312a94cSmrg trap "ret=129; $do_exit" 1 238b312a94cSmrg trap "ret=130; $do_exit" 2 239b312a94cSmrg trap "ret=141; $do_exit" 13 240b312a94cSmrg trap "ret=143; $do_exit" 15 241ef981d24Smrg 242ef981d24Smrg # Set umask so as not to create temps with too-generous modes. 243ef981d24Smrg # However, 'strip' requires both read and write access to temps. 244ef981d24Smrg case $mode in 245ef981d24Smrg # Optimize common cases. 246ef981d24Smrg *644) cp_umask=133;; 247ef981d24Smrg *755) cp_umask=22;; 248ef981d24Smrg 249ef981d24Smrg *[0-7]) 250ef981d24Smrg if test -z "$stripcmd"; then 251b312a94cSmrg u_plus_rw= 252ef981d24Smrg else 253b312a94cSmrg u_plus_rw='% 200' 254ef981d24Smrg fi 255ef981d24Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256ef981d24Smrg *) 257ef981d24Smrg if test -z "$stripcmd"; then 258b312a94cSmrg u_plus_rw= 259ef981d24Smrg else 260b312a94cSmrg u_plus_rw=,u+rw 261ef981d24Smrg fi 262ef981d24Smrg cp_umask=$mode$u_plus_rw;; 263ef981d24Smrg esac 264ef981d24Smrgfi 265ef981d24Smrg 266ef981d24Smrgfor src 267ef981d24Smrgdo 268b312a94cSmrg # Protect names problematic for 'test' and other utilities. 269ef981d24Smrg case $src in 270b312a94cSmrg -* | [=\(\)!]) src=./$src;; 271ef981d24Smrg esac 272ef981d24Smrg 273ef981d24Smrg if test -n "$dir_arg"; then 274ef981d24Smrg dst=$src 275ef981d24Smrg dstdir=$dst 276ef981d24Smrg test -d "$dstdir" 277ef981d24Smrg dstdir_status=$? 278d5637ae9Smrg # Don't chown directories that already exist. 279d5637ae9Smrg if test $dstdir_status = 0; then 280d5637ae9Smrg chowncmd="" 281d5637ae9Smrg fi 282ef981d24Smrg else 283ef981d24Smrg 284ef981d24Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285ef981d24Smrg # might cause directories to be created, which would be especially bad 286ef981d24Smrg # if $src (and thus $dsttmp) contains '*'. 287ef981d24Smrg if test ! -f "$src" && test ! -d "$src"; then 288ef981d24Smrg echo "$0: $src does not exist." >&2 289ef981d24Smrg exit 1 290ef981d24Smrg fi 291ef981d24Smrg 29265eef222Smrg if test -z "$dst_arg"; then 293ef981d24Smrg echo "$0: no destination specified." >&2 294ef981d24Smrg exit 1 295ef981d24Smrg fi 29665eef222Smrg dst=$dst_arg 297ef981d24Smrg 298d5637ae9Smrg # If destination is a directory, append the input filename. 299ef981d24Smrg if test -d "$dst"; then 300b312a94cSmrg if test "$is_target_a_directory" = never; then 301b312a94cSmrg echo "$0: $dst_arg: Is a directory" >&2 302b312a94cSmrg exit 1 303ef981d24Smrg fi 304ef981d24Smrg dstdir=$dst 305d5637ae9Smrg dstbase=`basename "$src"` 306d5637ae9Smrg case $dst in 307d5637ae9Smrg */) dst=$dst$dstbase;; 308d5637ae9Smrg *) dst=$dst/$dstbase;; 309d5637ae9Smrg esac 310ef981d24Smrg dstdir_status=0 311ef981d24Smrg else 312b312a94cSmrg dstdir=`dirname "$dst"` 313ef981d24Smrg test -d "$dstdir" 314ef981d24Smrg dstdir_status=$? 315ef981d24Smrg fi 316ef981d24Smrg fi 317ef981d24Smrg 318d5637ae9Smrg case $dstdir in 319d5637ae9Smrg */) dstdirslash=$dstdir;; 320d5637ae9Smrg *) dstdirslash=$dstdir/;; 321d5637ae9Smrg esac 322d5637ae9Smrg 323ef981d24Smrg obsolete_mkdir_used=false 324ef981d24Smrg 325ef981d24Smrg if test $dstdir_status != 0; then 326ef981d24Smrg case $posix_mkdir in 327ef981d24Smrg '') 328b312a94cSmrg # With -d, create the new directory with the user-specified mode. 329b312a94cSmrg # Otherwise, rely on $mkdir_umask. 330b312a94cSmrg if test -n "$dir_arg"; then 331b312a94cSmrg mkdir_mode=-m$mode 332b312a94cSmrg else 333b312a94cSmrg mkdir_mode= 334b312a94cSmrg fi 335b312a94cSmrg 336b312a94cSmrg posix_mkdir=false 337d5637ae9Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 338d5637ae9Smrg # here however when possible just to lower collision chance. 339d5637ae9Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340d5637ae9Smrg 341d5637ae9Smrg trap ' 342d5637ae9Smrg ret=$? 343d5637ae9Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344d5637ae9Smrg exit $ret 345d5637ae9Smrg ' 0 346d5637ae9Smrg 347d5637ae9Smrg # Because "mkdir -p" follows existing symlinks and we likely work 348d5637ae9Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349d5637ae9Smrg # directory is successfully created first before we actually test 350d5637ae9Smrg # 'mkdir -p'. 351d5637ae9Smrg if (umask $mkdir_umask && 352d5637ae9Smrg $mkdirprog $mkdir_mode "$tmpdir" && 353d5637ae9Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354d5637ae9Smrg then 355d5637ae9Smrg if test -z "$dir_arg" || { 356d5637ae9Smrg # Check for POSIX incompatibilities with -m. 357d5637ae9Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358d5637ae9Smrg # other-writable bit of parent directory when it shouldn't. 359d5637ae9Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360d5637ae9Smrg test_tmpdir="$tmpdir/a" 361d5637ae9Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362d5637ae9Smrg case $ls_ld_tmpdir in 363d5637ae9Smrg d????-?r-*) different_mode=700;; 364d5637ae9Smrg d????-?--*) different_mode=755;; 365d5637ae9Smrg *) false;; 366d5637ae9Smrg esac && 367d5637ae9Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368d5637ae9Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369d5637ae9Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370d5637ae9Smrg } 371d5637ae9Smrg } 372d5637ae9Smrg then posix_mkdir=: 373d5637ae9Smrg fi 374d5637ae9Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375d5637ae9Smrg else 376d5637ae9Smrg # Remove any dirs left behind by ancient mkdir implementations. 377d5637ae9Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378d5637ae9Smrg fi 379d5637ae9Smrg trap '' 0;; 380ef981d24Smrg esac 381ef981d24Smrg 382ef981d24Smrg if 383ef981d24Smrg $posix_mkdir && ( 384b312a94cSmrg umask $mkdir_umask && 385b312a94cSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386ef981d24Smrg ) 387ef981d24Smrg then : 388ef981d24Smrg else 389ef981d24Smrg 390d5637ae9Smrg # mkdir does not conform to POSIX, 391ef981d24Smrg # or it failed possibly due to a race condition. Create the 392ef981d24Smrg # directory the slow way, step by step, checking for races as we go. 393ef981d24Smrg 394ef981d24Smrg case $dstdir in 395b312a94cSmrg /*) prefix='/';; 396b312a94cSmrg [-=\(\)!]*) prefix='./';; 397b312a94cSmrg *) prefix='';; 398ef981d24Smrg esac 399ef981d24Smrg 400ef981d24Smrg oIFS=$IFS 401ef981d24Smrg IFS=/ 402b312a94cSmrg set -f 403ef981d24Smrg set fnord $dstdir 404ef981d24Smrg shift 405b312a94cSmrg set +f 406ef981d24Smrg IFS=$oIFS 407ef981d24Smrg 408ef981d24Smrg prefixes= 409ef981d24Smrg 410ef981d24Smrg for d 411ef981d24Smrg do 412b312a94cSmrg test X"$d" = X && continue 413b312a94cSmrg 414b312a94cSmrg prefix=$prefix$d 415b312a94cSmrg if test -d "$prefix"; then 416b312a94cSmrg prefixes= 417b312a94cSmrg else 418b312a94cSmrg if $posix_mkdir; then 419d5637ae9Smrg (umask $mkdir_umask && 420b312a94cSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421b312a94cSmrg # Don't fail if two instances are running concurrently. 422b312a94cSmrg test -d "$prefix" || exit 1 423b312a94cSmrg else 424b312a94cSmrg case $prefix in 425b312a94cSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426b312a94cSmrg *) qprefix=$prefix;; 427b312a94cSmrg esac 428b312a94cSmrg prefixes="$prefixes '$qprefix'" 429b312a94cSmrg fi 430b312a94cSmrg fi 431b312a94cSmrg prefix=$prefix/ 432ef981d24Smrg done 433ef981d24Smrg 434ef981d24Smrg if test -n "$prefixes"; then 435b312a94cSmrg # Don't fail if two instances are running concurrently. 436b312a94cSmrg (umask $mkdir_umask && 437b312a94cSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 438b312a94cSmrg test -d "$dstdir" || exit 1 439b312a94cSmrg obsolete_mkdir_used=true 440ef981d24Smrg fi 441ef981d24Smrg fi 442ef981d24Smrg fi 443ef981d24Smrg 444ef981d24Smrg if test -n "$dir_arg"; then 445ef981d24Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446ef981d24Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447ef981d24Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448ef981d24Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449ef981d24Smrg else 450ef981d24Smrg 451ef981d24Smrg # Make a couple of temp file names in the proper directory. 452d5637ae9Smrg dsttmp=${dstdirslash}_inst.$$_ 453d5637ae9Smrg rmtmp=${dstdirslash}_rm.$$_ 454ef981d24Smrg 455ef981d24Smrg # Trap to clean up those temp files at exit. 456ef981d24Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457ef981d24Smrg 458ef981d24Smrg # Copy the file name to the temp name. 459d5637ae9Smrg (umask $cp_umask && 460d5637ae9Smrg { test -z "$stripcmd" || { 461d5637ae9Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462d5637ae9Smrg # which would cause strip to fail. 463d5637ae9Smrg if test -z "$doit"; then 464d5637ae9Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 465d5637ae9Smrg else 466d5637ae9Smrg $doit touch "$dsttmp" 467d5637ae9Smrg fi 468d5637ae9Smrg } 469d5637ae9Smrg } && 470d5637ae9Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471ef981d24Smrg 472ef981d24Smrg # and set any options; do chmod last to preserve setuid bits. 473ef981d24Smrg # 474ef981d24Smrg # If any of these fail, we abort the whole thing. If we want to 475ef981d24Smrg # ignore errors from any of these, just make sure not to ignore 476ef981d24Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477ef981d24Smrg # 47865eef222Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 47965eef222Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 48065eef222Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 48165eef222Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 48265eef222Smrg 48365eef222Smrg # If -C, don't bother to copy if it wouldn't change the file. 48465eef222Smrg if $copy_on_change && 485b312a94cSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486b312a94cSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487b312a94cSmrg set -f && 48865eef222Smrg set X $old && old=:$2:$4:$5:$6 && 48965eef222Smrg set X $new && new=:$2:$4:$5:$6 && 490b312a94cSmrg set +f && 49165eef222Smrg test "$old" = "$new" && 49265eef222Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 49365eef222Smrg then 49465eef222Smrg rm -f "$dsttmp" 49565eef222Smrg else 496d5637ae9Smrg # If $backupsuffix is set, and the file being installed 497d5637ae9Smrg # already exists, attempt a backup. Don't worry if it fails, 498d5637ae9Smrg # e.g., if mv doesn't support -f. 499d5637ae9Smrg if test -n "$backupsuffix" && test -f "$dst"; then 500d5637ae9Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501d5637ae9Smrg fi 502d5637ae9Smrg 50365eef222Smrg # Rename the file to the real destination. 50465eef222Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 50565eef222Smrg 50665eef222Smrg # The rename failed, perhaps because mv can't rename something else 50765eef222Smrg # to itself, or perhaps because mv is so ancient that it does not 50865eef222Smrg # support -f. 50965eef222Smrg { 510b312a94cSmrg # Now remove or move aside any old file at destination location. 511b312a94cSmrg # We try this two ways since rm can't unlink itself on some 512b312a94cSmrg # systems and the destination file might be busy for other 513b312a94cSmrg # reasons. In this case, the final cleanup might fail but the new 514b312a94cSmrg # file should still install successfully. 515b312a94cSmrg { 516b312a94cSmrg test ! -f "$dst" || 517d5637ae9Smrg $doit $rmcmd "$dst" 2>/dev/null || 518b312a94cSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519d5637ae9Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520b312a94cSmrg } || 521b312a94cSmrg { echo "$0: cannot unlink or rename $dst" >&2 522b312a94cSmrg (exit 1); exit 1 523b312a94cSmrg } 524b312a94cSmrg } && 525b312a94cSmrg 526b312a94cSmrg # Now rename the file to the real destination. 527b312a94cSmrg $doit $mvcmd "$dsttmp" "$dst" 52865eef222Smrg } 52965eef222Smrg fi || exit 1 530ef981d24Smrg 531ef981d24Smrg trap '' 0 532ef981d24Smrg fi 533ef981d24Smrgdone 534ef981d24Smrg 535ef981d24Smrg# Local variables: 536d5637ae9Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537ef981d24Smrg# time-stamp-start: "scriptversion=" 538ef981d24Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539b312a94cSmrg# time-stamp-time-zone: "UTC0" 54056957a04Smrg# time-stamp-end: "; # UTC" 541ef981d24Smrg# End: 542