install-sh revision e32e2dab
16ea72052Smrg#!/bin/sh 26ea72052Smrg# install - install a program, script, or datafile 3168023feSmrg 4e32e2dabSmrgscriptversion=2024-06-19.01; # UTC 5168023feSmrg 66ea72052Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 76ea72052Smrg# later released in X11R6 (xc/config/util/install.sh) with the 86ea72052Smrg# following copyright and license. 96ea72052Smrg# 106ea72052Smrg# Copyright (C) 1994 X Consortium 116ea72052Smrg# 126ea72052Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 136ea72052Smrg# of this software and associated documentation files (the "Software"), to 146ea72052Smrg# deal in the Software without restriction, including without limitation the 156ea72052Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 166ea72052Smrg# sell copies of the Software, and to permit persons to whom the Software is 176ea72052Smrg# furnished to do so, subject to the following conditions: 186ea72052Smrg# 196ea72052Smrg# The above copyright notice and this permission notice shall be included in 206ea72052Smrg# all copies or substantial portions of the Software. 216ea72052Smrg# 226ea72052Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 236ea72052Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 246ea72052Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 256ea72052Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 266ea72052Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 276ea72052Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 286ea72052Smrg# 296ea72052Smrg# Except as contained in this notice, the name of the X Consortium shall not 306ea72052Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 316ea72052Smrg# ings in this Software without prior written authorization from the X Consor- 326ea72052Smrg# tium. 336ea72052Smrg# 346ea72052Smrg# 356ea72052Smrg# FSF changes to this file are in the public domain. 366ea72052Smrg# 376ea72052Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38b0c24a08Smrg# 'make' implicit rules from creating a file called install from it 396ea72052Smrg# when there is no Makefile. 406ea72052Smrg# 416ea72052Smrg# This script is compatible with the BSD install script, but was written 42168023feSmrg# from scratch. 436ea72052Smrg 44b0c24a08Smrgtab=' ' 45168023feSmrgnl=' 46168023feSmrg' 47b0c24a08SmrgIFS=" $tab$nl" 486ea72052Smrg 49b0c24a08Smrg# Set DOITPROG to "echo" to test this script. 506ea72052Smrg 51168023feSmrgdoit=${DOITPROG-} 52b0c24a08Smrgdoit_exec=${doit:-exec} 536ea72052Smrg 54168023feSmrg# Put in absolute file names if you don't have them in your path; 55168023feSmrg# or use environment vars. 56168023feSmrg 57168023feSmrgchgrpprog=${CHGRPPROG-chgrp} 58168023feSmrgchmodprog=${CHMODPROG-chmod} 59168023feSmrgchownprog=${CHOWNPROG-chown} 60168023feSmrgcmpprog=${CMPPROG-cmp} 61168023feSmrgcpprog=${CPPROG-cp} 62168023feSmrgmkdirprog=${MKDIRPROG-mkdir} 63168023feSmrgmvprog=${MVPROG-mv} 64168023feSmrgrmprog=${RMPROG-rm} 65168023feSmrgstripprog=${STRIPPROG-strip} 66168023feSmrg 67168023feSmrgposix_mkdir= 68168023feSmrg 69168023feSmrg# Desired mode of installed file. 70168023feSmrgmode=0755 71168023feSmrg 72f3e6ffc5Smrg# Create dirs (including intermediate dirs) using mode 755. 73f3e6ffc5Smrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74f3e6ffc5Smrgmkdir_umask=22 75f3e6ffc5Smrg 76f3e6ffc5Smrgbackupsuffix= 77168023feSmrgchgrpcmd= 78168023feSmrgchmodcmd=$chmodprog 79168023feSmrgchowncmd= 80168023feSmrgmvcmd=$mvprog 81168023feSmrgrmcmd="$rmprog -f" 82168023feSmrgstripcmd= 836ea72052Smrg 84168023feSmrgsrc= 85168023feSmrgdst= 86168023feSmrgdir_arg= 87168023feSmrgdst_arg= 886ea72052Smrg 89168023feSmrgcopy_on_change=false 90b0c24a08Smrgis_target_a_directory=possibly 916ea72052Smrg 92168023feSmrgusage="\ 93168023feSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94168023feSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95168023feSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96168023feSmrg or: $0 [OPTION]... -d DIRECTORIES... 976ea72052Smrg 98168023feSmrgIn the 1st form, copy SRCFILE to DSTFILE. 99168023feSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100168023feSmrgIn the 4th, create DIRECTORIES. 1016ea72052Smrg 102168023feSmrgOptions: 103168023feSmrg --help display this help and exit. 104168023feSmrg --version display version info and exit. 1056ea72052Smrg 106168023feSmrg -c (ignored) 107f3e6ffc5Smrg -C install only if different (preserve data modification time) 108168023feSmrg -d create directories instead of installing files. 109168023feSmrg -g GROUP $chgrpprog installed files to GROUP. 110168023feSmrg -m MODE $chmodprog installed files to MODE. 111168023feSmrg -o USER $chownprog installed files to USER. 112f3e6ffc5Smrg -p pass -p to $cpprog. 113168023feSmrg -s $stripprog installed files. 114f3e6ffc5Smrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115168023feSmrg -t DIRECTORY install into DIRECTORY. 116168023feSmrg -T report an error if DSTFILE is a directory. 1176ea72052Smrg 118168023feSmrgEnvironment variables override the default commands: 119168023feSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120168023feSmrg RMPROG STRIPPROG 121f3e6ffc5Smrg 122f3e6ffc5SmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123f3e6ffc5Smrgit's up to you to specify -f if you want it. 124f3e6ffc5Smrg 125f3e6ffc5SmrgIf -S is not specified, no backups are attempted. 126f3e6ffc5Smrg 127e32e2dabSmrgReport bugs to <bug-automake@gnu.org>. 128e32e2dabSmrgGNU Automake home page: <https://www.gnu.org/software/automake/>. 129e32e2dabSmrgGeneral help using GNU software: <https://www.gnu.org/gethelp/>." 1306ea72052Smrg 131168023feSmrgwhile test $# -ne 0; do 132168023feSmrg case $1 in 133168023feSmrg -c) ;; 1346ea72052Smrg 135168023feSmrg -C) copy_on_change=true;; 1366ea72052Smrg 137168023feSmrg -d) dir_arg=true;; 1386ea72052Smrg 139168023feSmrg -g) chgrpcmd="$chgrpprog $2" 140b0c24a08Smrg shift;; 1416ea72052Smrg 142168023feSmrg --help) echo "$usage"; exit $?;; 1436ea72052Smrg 144168023feSmrg -m) mode=$2 145b0c24a08Smrg case $mode in 146b0c24a08Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147b0c24a08Smrg echo "$0: invalid mode: $mode" >&2 148b0c24a08Smrg exit 1;; 149b0c24a08Smrg esac 150b0c24a08Smrg shift;; 1516ea72052Smrg 152168023feSmrg -o) chowncmd="$chownprog $2" 153b0c24a08Smrg shift;; 1546ea72052Smrg 155f3e6ffc5Smrg -p) cpprog="$cpprog -p";; 156f3e6ffc5Smrg 157168023feSmrg -s) stripcmd=$stripprog;; 1586ea72052Smrg 159f3e6ffc5Smrg -S) backupsuffix="$2" 160f3e6ffc5Smrg shift;; 161f3e6ffc5Smrg 162b0c24a08Smrg -t) 163b0c24a08Smrg is_target_a_directory=always 164b0c24a08Smrg dst_arg=$2 165b0c24a08Smrg # Protect names problematic for 'test' and other utilities. 166b0c24a08Smrg case $dst_arg in 167b0c24a08Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168b0c24a08Smrg esac 169b0c24a08Smrg shift;; 1706ea72052Smrg 171b0c24a08Smrg -T) is_target_a_directory=never;; 1726ea72052Smrg 173e32e2dabSmrg --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;; 1746ea72052Smrg 175b0c24a08Smrg --) shift 176b0c24a08Smrg break;; 1776ea72052Smrg 178b0c24a08Smrg -*) echo "$0: invalid option: $1" >&2 179b0c24a08Smrg exit 1;; 1806ea72052Smrg 181168023feSmrg *) break;; 182168023feSmrg esac 183168023feSmrg shift 184168023feSmrgdone 1856ea72052Smrg 186b0c24a08Smrg# We allow the use of options -d and -T together, by making -d 187b0c24a08Smrg# take the precedence; this is for compatibility with GNU install. 188b0c24a08Smrg 189b0c24a08Smrgif test -n "$dir_arg"; then 190b0c24a08Smrg if test -n "$dst_arg"; then 191b0c24a08Smrg echo "$0: target directory not allowed when installing a directory." >&2 192b0c24a08Smrg exit 1 193b0c24a08Smrg fi 194b0c24a08Smrgfi 195b0c24a08Smrg 196168023feSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197168023feSmrg # When -d is used, all remaining arguments are directories to create. 198168023feSmrg # When -t is used, the destination is already specified. 199168023feSmrg # Otherwise, the last argument is the destination. Remove it from $@. 200168023feSmrg for arg 201168023feSmrg do 202168023feSmrg if test -n "$dst_arg"; then 203168023feSmrg # $@ is not empty: it contains at least $arg. 204168023feSmrg set fnord "$@" "$dst_arg" 205168023feSmrg shift # fnord 206168023feSmrg fi 207168023feSmrg shift # arg 208168023feSmrg dst_arg=$arg 209b0c24a08Smrg # Protect names problematic for 'test' and other utilities. 210b0c24a08Smrg case $dst_arg in 211b0c24a08Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212b0c24a08Smrg esac 213168023feSmrg done 214168023feSmrgfi 2156ea72052Smrg 216168023feSmrgif test $# -eq 0; then 217168023feSmrg if test -z "$dir_arg"; then 218168023feSmrg echo "$0: no input file specified." >&2 219168023feSmrg exit 1 220168023feSmrg fi 221b0c24a08Smrg # It's OK to call 'install-sh -d' without argument. 222168023feSmrg # This can happen when creating conditional directories. 223168023feSmrg exit 0 224168023feSmrgfi 2256ea72052Smrg 226168023feSmrgif test -z "$dir_arg"; then 227b0c24a08Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228b0c24a08Smrg if test ! -d "$dst_arg"; then 229b0c24a08Smrg echo "$0: $dst_arg: Is not a directory." >&2 230b0c24a08Smrg exit 1 231b0c24a08Smrg fi 232b0c24a08Smrg fi 233b0c24a08Smrgfi 234b0c24a08Smrg 235b0c24a08Smrgif test -z "$dir_arg"; then 236b0c24a08Smrg do_exit='(exit $ret); exit $ret' 237b0c24a08Smrg trap "ret=129; $do_exit" 1 238b0c24a08Smrg trap "ret=130; $do_exit" 2 239b0c24a08Smrg trap "ret=141; $do_exit" 13 240b0c24a08Smrg trap "ret=143; $do_exit" 15 241168023feSmrg 242168023feSmrg # Set umask so as not to create temps with too-generous modes. 243168023feSmrg # However, 'strip' requires both read and write access to temps. 244168023feSmrg case $mode in 245168023feSmrg # Optimize common cases. 246168023feSmrg *644) cp_umask=133;; 247168023feSmrg *755) cp_umask=22;; 248168023feSmrg 249168023feSmrg *[0-7]) 250168023feSmrg if test -z "$stripcmd"; then 251b0c24a08Smrg u_plus_rw= 252168023feSmrg else 253b0c24a08Smrg u_plus_rw='% 200' 254168023feSmrg fi 255168023feSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256168023feSmrg *) 257168023feSmrg if test -z "$stripcmd"; then 258b0c24a08Smrg u_plus_rw= 259168023feSmrg else 260b0c24a08Smrg u_plus_rw=,u+rw 261168023feSmrg fi 262168023feSmrg cp_umask=$mode$u_plus_rw;; 263168023feSmrg esac 264168023feSmrgfi 2656ea72052Smrg 266168023feSmrgfor src 267168023feSmrgdo 268b0c24a08Smrg # Protect names problematic for 'test' and other utilities. 269168023feSmrg case $src in 270b0c24a08Smrg -* | [=\(\)!]) src=./$src;; 271168023feSmrg esac 272168023feSmrg 273168023feSmrg if test -n "$dir_arg"; then 274168023feSmrg dst=$src 275168023feSmrg dstdir=$dst 276168023feSmrg test -d "$dstdir" 277168023feSmrg dstdir_status=$? 278f3e6ffc5Smrg # Don't chown directories that already exist. 279f3e6ffc5Smrg if test $dstdir_status = 0; then 280f3e6ffc5Smrg chowncmd="" 281f3e6ffc5Smrg fi 282168023feSmrg else 283168023feSmrg 284168023feSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285168023feSmrg # might cause directories to be created, which would be especially bad 286168023feSmrg # if $src (and thus $dsttmp) contains '*'. 287168023feSmrg if test ! -f "$src" && test ! -d "$src"; then 288168023feSmrg echo "$0: $src does not exist." >&2 289168023feSmrg exit 1 290168023feSmrg fi 291168023feSmrg 292168023feSmrg if test -z "$dst_arg"; then 293168023feSmrg echo "$0: no destination specified." >&2 294168023feSmrg exit 1 295168023feSmrg fi 296168023feSmrg dst=$dst_arg 2976ea72052Smrg 298f3e6ffc5Smrg # If destination is a directory, append the input filename. 299168023feSmrg if test -d "$dst"; then 300b0c24a08Smrg if test "$is_target_a_directory" = never; then 301b0c24a08Smrg echo "$0: $dst_arg: Is a directory" >&2 302b0c24a08Smrg exit 1 303168023feSmrg fi 304168023feSmrg dstdir=$dst 305f3e6ffc5Smrg dstbase=`basename "$src"` 306f3e6ffc5Smrg case $dst in 307f3e6ffc5Smrg */) dst=$dst$dstbase;; 308f3e6ffc5Smrg *) dst=$dst/$dstbase;; 309f3e6ffc5Smrg esac 310168023feSmrg dstdir_status=0 311168023feSmrg else 312b0c24a08Smrg dstdir=`dirname "$dst"` 313168023feSmrg test -d "$dstdir" 314168023feSmrg dstdir_status=$? 315168023feSmrg fi 316168023feSmrg fi 317168023feSmrg 318f3e6ffc5Smrg case $dstdir in 319f3e6ffc5Smrg */) dstdirslash=$dstdir;; 320f3e6ffc5Smrg *) dstdirslash=$dstdir/;; 321f3e6ffc5Smrg esac 322f3e6ffc5Smrg 323168023feSmrg obsolete_mkdir_used=false 324168023feSmrg 325168023feSmrg if test $dstdir_status != 0; then 326168023feSmrg case $posix_mkdir in 327168023feSmrg '') 328b0c24a08Smrg # With -d, create the new directory with the user-specified mode. 329b0c24a08Smrg # Otherwise, rely on $mkdir_umask. 330b0c24a08Smrg if test -n "$dir_arg"; then 331b0c24a08Smrg mkdir_mode=-m$mode 332b0c24a08Smrg else 333b0c24a08Smrg mkdir_mode= 334b0c24a08Smrg fi 335b0c24a08Smrg 336b0c24a08Smrg posix_mkdir=false 337f3e6ffc5Smrg # The $RANDOM variable is not portable (e.g., dash). Use it 338f3e6ffc5Smrg # here however when possible just to lower collision chance. 339f3e6ffc5Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340f3e6ffc5Smrg 341f3e6ffc5Smrg trap ' 342f3e6ffc5Smrg ret=$? 343f3e6ffc5Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344f3e6ffc5Smrg exit $ret 345f3e6ffc5Smrg ' 0 346f3e6ffc5Smrg 347f3e6ffc5Smrg # Because "mkdir -p" follows existing symlinks and we likely work 348e32e2dabSmrg # directly in world-writable /tmp, make sure that the '$tmpdir' 349f3e6ffc5Smrg # directory is successfully created first before we actually test 350f3e6ffc5Smrg # 'mkdir -p'. 351f3e6ffc5Smrg if (umask $mkdir_umask && 352f3e6ffc5Smrg $mkdirprog $mkdir_mode "$tmpdir" && 353f3e6ffc5Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354f3e6ffc5Smrg then 355f3e6ffc5Smrg if test -z "$dir_arg" || { 356e32e2dabSmrg # Check for POSIX incompatibility with -m. 357f3e6ffc5Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358f3e6ffc5Smrg # other-writable bit of parent directory when it shouldn't. 359f3e6ffc5Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360f3e6ffc5Smrg test_tmpdir="$tmpdir/a" 361f3e6ffc5Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362f3e6ffc5Smrg case $ls_ld_tmpdir in 363f3e6ffc5Smrg d????-?r-*) different_mode=700;; 364f3e6ffc5Smrg d????-?--*) different_mode=755;; 365f3e6ffc5Smrg *) false;; 366f3e6ffc5Smrg esac && 367f3e6ffc5Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368f3e6ffc5Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369f3e6ffc5Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370f3e6ffc5Smrg } 371f3e6ffc5Smrg } 372f3e6ffc5Smrg then posix_mkdir=: 373f3e6ffc5Smrg fi 374f3e6ffc5Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375f3e6ffc5Smrg else 376f3e6ffc5Smrg # Remove any dirs left behind by ancient mkdir implementations. 377f3e6ffc5Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378f3e6ffc5Smrg fi 379f3e6ffc5Smrg trap '' 0;; 380168023feSmrg esac 3816ea72052Smrg 382168023feSmrg if 383168023feSmrg $posix_mkdir && ( 384b0c24a08Smrg umask $mkdir_umask && 385b0c24a08Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386168023feSmrg ) 387168023feSmrg then : 388168023feSmrg else 389168023feSmrg 390f3e6ffc5Smrg # mkdir does not conform to POSIX, 391168023feSmrg # or it failed possibly due to a race condition. Create the 392168023feSmrg # directory the slow way, step by step, checking for races as we go. 393168023feSmrg 394168023feSmrg case $dstdir in 395b0c24a08Smrg /*) prefix='/';; 396b0c24a08Smrg [-=\(\)!]*) prefix='./';; 397b0c24a08Smrg *) prefix='';; 398168023feSmrg esac 399168023feSmrg 400168023feSmrg oIFS=$IFS 401168023feSmrg IFS=/ 402b0c24a08Smrg set -f 403168023feSmrg set fnord $dstdir 404168023feSmrg shift 405b0c24a08Smrg set +f 406168023feSmrg IFS=$oIFS 407168023feSmrg 408168023feSmrg prefixes= 409168023feSmrg 410168023feSmrg for d 411168023feSmrg do 412b0c24a08Smrg test X"$d" = X && continue 413b0c24a08Smrg 414b0c24a08Smrg prefix=$prefix$d 415b0c24a08Smrg if test -d "$prefix"; then 416b0c24a08Smrg prefixes= 417b0c24a08Smrg else 418b0c24a08Smrg if $posix_mkdir; then 419f3e6ffc5Smrg (umask $mkdir_umask && 420b0c24a08Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421b0c24a08Smrg # Don't fail if two instances are running concurrently. 422b0c24a08Smrg test -d "$prefix" || exit 1 423b0c24a08Smrg else 424b0c24a08Smrg case $prefix in 425b0c24a08Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426b0c24a08Smrg *) qprefix=$prefix;; 427b0c24a08Smrg esac 428b0c24a08Smrg prefixes="$prefixes '$qprefix'" 429b0c24a08Smrg fi 430b0c24a08Smrg fi 431b0c24a08Smrg prefix=$prefix/ 432168023feSmrg done 433168023feSmrg 434168023feSmrg if test -n "$prefixes"; then 435b0c24a08Smrg # Don't fail if two instances are running concurrently. 436b0c24a08Smrg (umask $mkdir_umask && 437b0c24a08Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 438b0c24a08Smrg test -d "$dstdir" || exit 1 439b0c24a08Smrg obsolete_mkdir_used=true 440168023feSmrg fi 441168023feSmrg fi 442168023feSmrg fi 443168023feSmrg 444168023feSmrg if test -n "$dir_arg"; then 445168023feSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446168023feSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447168023feSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448168023feSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449168023feSmrg else 450168023feSmrg 451168023feSmrg # Make a couple of temp file names in the proper directory. 452f3e6ffc5Smrg dsttmp=${dstdirslash}_inst.$$_ 453f3e6ffc5Smrg rmtmp=${dstdirslash}_rm.$$_ 454168023feSmrg 455168023feSmrg # Trap to clean up those temp files at exit. 456168023feSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457168023feSmrg 458168023feSmrg # Copy the file name to the temp name. 459f3e6ffc5Smrg (umask $cp_umask && 460f3e6ffc5Smrg { test -z "$stripcmd" || { 461f3e6ffc5Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462f3e6ffc5Smrg # which would cause strip to fail. 463f3e6ffc5Smrg if test -z "$doit"; then 464f3e6ffc5Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 465f3e6ffc5Smrg else 466f3e6ffc5Smrg $doit touch "$dsttmp" 467f3e6ffc5Smrg fi 468f3e6ffc5Smrg } 469f3e6ffc5Smrg } && 470f3e6ffc5Smrg $doit_exec $cpprog "$src" "$dsttmp") && 471168023feSmrg 472168023feSmrg # and set any options; do chmod last to preserve setuid bits. 473168023feSmrg # 474168023feSmrg # If any of these fail, we abort the whole thing. If we want to 475168023feSmrg # ignore errors from any of these, just make sure not to ignore 476168023feSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477168023feSmrg # 478168023feSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479168023feSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480168023feSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481168023feSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482168023feSmrg 483168023feSmrg # If -C, don't bother to copy if it wouldn't change the file. 484168023feSmrg if $copy_on_change && 485b0c24a08Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486b0c24a08Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487b0c24a08Smrg set -f && 488168023feSmrg set X $old && old=:$2:$4:$5:$6 && 489168023feSmrg set X $new && new=:$2:$4:$5:$6 && 490b0c24a08Smrg set +f && 491168023feSmrg test "$old" = "$new" && 492168023feSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493168023feSmrg then 494168023feSmrg rm -f "$dsttmp" 495168023feSmrg else 496f3e6ffc5Smrg # If $backupsuffix is set, and the file being installed 497f3e6ffc5Smrg # already exists, attempt a backup. Don't worry if it fails, 498f3e6ffc5Smrg # e.g., if mv doesn't support -f. 499f3e6ffc5Smrg if test -n "$backupsuffix" && test -f "$dst"; then 500f3e6ffc5Smrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501f3e6ffc5Smrg fi 502f3e6ffc5Smrg 503168023feSmrg # Rename the file to the real destination. 504168023feSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505168023feSmrg 506168023feSmrg # The rename failed, perhaps because mv can't rename something else 507168023feSmrg # to itself, or perhaps because mv is so ancient that it does not 508168023feSmrg # support -f. 509168023feSmrg { 510b0c24a08Smrg # Now remove or move aside any old file at destination location. 511b0c24a08Smrg # We try this two ways since rm can't unlink itself on some 512b0c24a08Smrg # systems and the destination file might be busy for other 513b0c24a08Smrg # reasons. In this case, the final cleanup might fail but the new 514b0c24a08Smrg # file should still install successfully. 515b0c24a08Smrg { 516b0c24a08Smrg test ! -f "$dst" || 517f3e6ffc5Smrg $doit $rmcmd "$dst" 2>/dev/null || 518b0c24a08Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519f3e6ffc5Smrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520b0c24a08Smrg } || 521b0c24a08Smrg { echo "$0: cannot unlink or rename $dst" >&2 522b0c24a08Smrg (exit 1); exit 1 523b0c24a08Smrg } 524b0c24a08Smrg } && 525b0c24a08Smrg 526b0c24a08Smrg # Now rename the file to the real destination. 527b0c24a08Smrg $doit $mvcmd "$dsttmp" "$dst" 528168023feSmrg } 529168023feSmrg fi || exit 1 530168023feSmrg 531168023feSmrg trap '' 0 532168023feSmrg fi 533168023feSmrgdone 5346ea72052Smrg 535168023feSmrg# Local variables: 536f3e6ffc5Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 537168023feSmrg# time-stamp-start: "scriptversion=" 538168023feSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539f3e6ffc5Smrg# time-stamp-time-zone: "UTC0" 540168023feSmrg# time-stamp-end: "; # UTC" 541168023feSmrg# End: 542