install-sh revision d21ab8bc
11f0ac6a5Smrg#!/bin/sh 21f0ac6a5Smrg# install - install a program, script, or datafile 31f0ac6a5Smrg 4d21ab8bcSmrgscriptversion=2020-11-14.01; # UTC 51f0ac6a5Smrg 61f0ac6a5Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 71f0ac6a5Smrg# later released in X11R6 (xc/config/util/install.sh) with the 81f0ac6a5Smrg# following copyright and license. 91f0ac6a5Smrg# 101f0ac6a5Smrg# Copyright (C) 1994 X Consortium 111f0ac6a5Smrg# 121f0ac6a5Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 131f0ac6a5Smrg# of this software and associated documentation files (the "Software"), to 141f0ac6a5Smrg# deal in the Software without restriction, including without limitation the 151f0ac6a5Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 161f0ac6a5Smrg# sell copies of the Software, and to permit persons to whom the Software is 171f0ac6a5Smrg# furnished to do so, subject to the following conditions: 181f0ac6a5Smrg# 191f0ac6a5Smrg# The above copyright notice and this permission notice shall be included in 201f0ac6a5Smrg# all copies or substantial portions of the Software. 211f0ac6a5Smrg# 221f0ac6a5Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 231f0ac6a5Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 241f0ac6a5Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 251f0ac6a5Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 261f0ac6a5Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 271f0ac6a5Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 281f0ac6a5Smrg# 291f0ac6a5Smrg# Except as contained in this notice, the name of the X Consortium shall not 301f0ac6a5Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 311f0ac6a5Smrg# ings in this Software without prior written authorization from the X Consor- 321f0ac6a5Smrg# tium. 331f0ac6a5Smrg# 341f0ac6a5Smrg# 351f0ac6a5Smrg# FSF changes to this file are in the public domain. 361f0ac6a5Smrg# 371f0ac6a5Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3889c04b6cSmrg# 'make' implicit rules from creating a file called install from it 391f0ac6a5Smrg# when there is no Makefile. 401f0ac6a5Smrg# 411f0ac6a5Smrg# This script is compatible with the BSD install script, but was written 421f0ac6a5Smrg# from scratch. 431f0ac6a5Smrg 44d21ab8bcSmrgtab=' ' 451f0ac6a5Smrgnl=' 461f0ac6a5Smrg' 47d21ab8bcSmrgIFS=" $tab$nl" 481f0ac6a5Smrg 49d21ab8bcSmrg# Set DOITPROG to "echo" to test this script. 501f0ac6a5Smrg 51e5410a46Smrgdoit=${DOITPROG-} 52d21ab8bcSmrgdoit_exec=${doit:-exec} 531f0ac6a5Smrg 541f0ac6a5Smrg# Put in absolute file names if you don't have them in your path; 551f0ac6a5Smrg# or use environment vars. 561f0ac6a5Smrg 57e5410a46Smrgchgrpprog=${CHGRPPROG-chgrp} 58e5410a46Smrgchmodprog=${CHMODPROG-chmod} 59e5410a46Smrgchownprog=${CHOWNPROG-chown} 60e5410a46Smrgcmpprog=${CMPPROG-cmp} 61e5410a46Smrgcpprog=${CPPROG-cp} 62e5410a46Smrgmkdirprog=${MKDIRPROG-mkdir} 63e5410a46Smrgmvprog=${MVPROG-mv} 64e5410a46Smrgrmprog=${RMPROG-rm} 65e5410a46Smrgstripprog=${STRIPPROG-strip} 66e5410a46Smrg 671f0ac6a5Smrgposix_mkdir= 681f0ac6a5Smrg 691f0ac6a5Smrg# Desired mode of installed file. 701f0ac6a5Smrgmode=0755 711f0ac6a5Smrg 72d21ab8bcSmrg# Create dirs (including intermediate dirs) using mode 755. 73d21ab8bcSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74d21ab8bcSmrgmkdir_umask=22 75d21ab8bcSmrg 76d21ab8bcSmrgbackupsuffix= 77e5410a46Smrgchgrpcmd= 781f0ac6a5Smrgchmodcmd=$chmodprog 791f0ac6a5Smrgchowncmd= 80e5410a46Smrgmvcmd=$mvprog 811f0ac6a5Smrgrmcmd="$rmprog -f" 82e5410a46Smrgstripcmd= 83e5410a46Smrg 841f0ac6a5Smrgsrc= 851f0ac6a5Smrgdst= 861f0ac6a5Smrgdir_arg= 87e5410a46Smrgdst_arg= 88e5410a46Smrg 89e5410a46Smrgcopy_on_change=false 90d21ab8bcSmrgis_target_a_directory=possibly 911f0ac6a5Smrg 92e5410a46Smrgusage="\ 93e5410a46SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 941f0ac6a5Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 951f0ac6a5Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 961f0ac6a5Smrg or: $0 [OPTION]... -d DIRECTORIES... 971f0ac6a5Smrg 981f0ac6a5SmrgIn the 1st form, copy SRCFILE to DSTFILE. 991f0ac6a5SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1001f0ac6a5SmrgIn the 4th, create DIRECTORIES. 1011f0ac6a5Smrg 1021f0ac6a5SmrgOptions: 103e5410a46Smrg --help display this help and exit. 104e5410a46Smrg --version display version info and exit. 105e5410a46Smrg 106e5410a46Smrg -c (ignored) 107d21ab8bcSmrg -C install only if different (preserve data modification time) 108e5410a46Smrg -d create directories instead of installing files. 109e5410a46Smrg -g GROUP $chgrpprog installed files to GROUP. 110e5410a46Smrg -m MODE $chmodprog installed files to MODE. 111e5410a46Smrg -o USER $chownprog installed files to USER. 112d21ab8bcSmrg -p pass -p to $cpprog. 113e5410a46Smrg -s $stripprog installed files. 114d21ab8bcSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115e5410a46Smrg -t DIRECTORY install into DIRECTORY. 116e5410a46Smrg -T report an error if DSTFILE is a directory. 1171f0ac6a5Smrg 1181f0ac6a5SmrgEnvironment variables override the default commands: 119e5410a46Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120e5410a46Smrg RMPROG STRIPPROG 121d21ab8bcSmrg 122d21ab8bcSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123d21ab8bcSmrgit's up to you to specify -f if you want it. 124d21ab8bcSmrg 125d21ab8bcSmrgIf -S is not specified, no backups are attempted. 126d21ab8bcSmrg 127d21ab8bcSmrgEmail bug reports to bug-automake@gnu.org. 128d21ab8bcSmrgAutomake home page: https://www.gnu.org/software/automake/ 1291f0ac6a5Smrg" 1301f0ac6a5Smrg 1311f0ac6a5Smrgwhile test $# -ne 0; do 1321f0ac6a5Smrg case $1 in 133e5410a46Smrg -c) ;; 134e5410a46Smrg 135e5410a46Smrg -C) copy_on_change=true;; 1361f0ac6a5Smrg 137e5410a46Smrg -d) dir_arg=true;; 1381f0ac6a5Smrg 1391f0ac6a5Smrg -g) chgrpcmd="$chgrpprog $2" 140d21ab8bcSmrg shift;; 1411f0ac6a5Smrg 1421f0ac6a5Smrg --help) echo "$usage"; exit $?;; 1431f0ac6a5Smrg 1441f0ac6a5Smrg -m) mode=$2 145d21ab8bcSmrg case $mode in 146d21ab8bcSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147d21ab8bcSmrg echo "$0: invalid mode: $mode" >&2 148d21ab8bcSmrg exit 1;; 149d21ab8bcSmrg esac 150d21ab8bcSmrg shift;; 1511f0ac6a5Smrg 1521f0ac6a5Smrg -o) chowncmd="$chownprog $2" 153d21ab8bcSmrg shift;; 154d21ab8bcSmrg 155d21ab8bcSmrg -p) cpprog="$cpprog -p";; 1561f0ac6a5Smrg 157e5410a46Smrg -s) stripcmd=$stripprog;; 1581f0ac6a5Smrg 159d21ab8bcSmrg -S) backupsuffix="$2" 160d21ab8bcSmrg shift;; 1611f0ac6a5Smrg 162d21ab8bcSmrg -t) 163d21ab8bcSmrg is_target_a_directory=always 164d21ab8bcSmrg dst_arg=$2 165d21ab8bcSmrg # Protect names problematic for 'test' and other utilities. 166d21ab8bcSmrg case $dst_arg in 167d21ab8bcSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168d21ab8bcSmrg esac 169d21ab8bcSmrg shift;; 170d21ab8bcSmrg 171d21ab8bcSmrg -T) is_target_a_directory=never;; 1721f0ac6a5Smrg 1731f0ac6a5Smrg --version) echo "$0 $scriptversion"; exit $?;; 1741f0ac6a5Smrg 175d21ab8bcSmrg --) shift 176d21ab8bcSmrg break;; 1771f0ac6a5Smrg 178d21ab8bcSmrg -*) echo "$0: invalid option: $1" >&2 179d21ab8bcSmrg exit 1;; 1801f0ac6a5Smrg 1811f0ac6a5Smrg *) break;; 1821f0ac6a5Smrg esac 183e5410a46Smrg shift 1841f0ac6a5Smrgdone 1851f0ac6a5Smrg 186d21ab8bcSmrg# We allow the use of options -d and -T together, by making -d 187d21ab8bcSmrg# take the precedence; this is for compatibility with GNU install. 188d21ab8bcSmrg 189d21ab8bcSmrgif test -n "$dir_arg"; then 190d21ab8bcSmrg if test -n "$dst_arg"; then 191d21ab8bcSmrg echo "$0: target directory not allowed when installing a directory." >&2 192d21ab8bcSmrg exit 1 193d21ab8bcSmrg fi 194d21ab8bcSmrgfi 195d21ab8bcSmrg 196e5410a46Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1971f0ac6a5Smrg # When -d is used, all remaining arguments are directories to create. 1981f0ac6a5Smrg # When -t is used, the destination is already specified. 1991f0ac6a5Smrg # Otherwise, the last argument is the destination. Remove it from $@. 2001f0ac6a5Smrg for arg 2011f0ac6a5Smrg do 202e5410a46Smrg if test -n "$dst_arg"; then 2031f0ac6a5Smrg # $@ is not empty: it contains at least $arg. 204e5410a46Smrg set fnord "$@" "$dst_arg" 2051f0ac6a5Smrg shift # fnord 2061f0ac6a5Smrg fi 2071f0ac6a5Smrg shift # arg 208e5410a46Smrg dst_arg=$arg 20989c04b6cSmrg # Protect names problematic for 'test' and other utilities. 21089c04b6cSmrg case $dst_arg in 21189c04b6cSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21289c04b6cSmrg esac 2131f0ac6a5Smrg done 2141f0ac6a5Smrgfi 2151f0ac6a5Smrg 2161f0ac6a5Smrgif test $# -eq 0; then 2171f0ac6a5Smrg if test -z "$dir_arg"; then 2181f0ac6a5Smrg echo "$0: no input file specified." >&2 2191f0ac6a5Smrg exit 1 2201f0ac6a5Smrg fi 22189c04b6cSmrg # It's OK to call 'install-sh -d' without argument. 2221f0ac6a5Smrg # This can happen when creating conditional directories. 2231f0ac6a5Smrg exit 0 2241f0ac6a5Smrgfi 2251f0ac6a5Smrg 226d21ab8bcSmrgif test -z "$dir_arg"; then 227d21ab8bcSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228d21ab8bcSmrg if test ! -d "$dst_arg"; then 229d21ab8bcSmrg echo "$0: $dst_arg: Is not a directory." >&2 230d21ab8bcSmrg exit 1 231d21ab8bcSmrg fi 232d21ab8bcSmrg fi 233d21ab8bcSmrgfi 234d21ab8bcSmrg 2351f0ac6a5Smrgif test -z "$dir_arg"; then 23689c04b6cSmrg do_exit='(exit $ret); exit $ret' 23789c04b6cSmrg trap "ret=129; $do_exit" 1 23889c04b6cSmrg trap "ret=130; $do_exit" 2 23989c04b6cSmrg trap "ret=141; $do_exit" 13 24089c04b6cSmrg trap "ret=143; $do_exit" 15 2411f0ac6a5Smrg 2421f0ac6a5Smrg # Set umask so as not to create temps with too-generous modes. 2431f0ac6a5Smrg # However, 'strip' requires both read and write access to temps. 2441f0ac6a5Smrg case $mode in 2451f0ac6a5Smrg # Optimize common cases. 2461f0ac6a5Smrg *644) cp_umask=133;; 2471f0ac6a5Smrg *755) cp_umask=22;; 2481f0ac6a5Smrg 2491f0ac6a5Smrg *[0-7]) 2501f0ac6a5Smrg if test -z "$stripcmd"; then 251d21ab8bcSmrg u_plus_rw= 2521f0ac6a5Smrg else 253d21ab8bcSmrg u_plus_rw='% 200' 2541f0ac6a5Smrg fi 2551f0ac6a5Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2561f0ac6a5Smrg *) 2571f0ac6a5Smrg if test -z "$stripcmd"; then 258d21ab8bcSmrg u_plus_rw= 2591f0ac6a5Smrg else 260d21ab8bcSmrg u_plus_rw=,u+rw 2611f0ac6a5Smrg fi 2621f0ac6a5Smrg cp_umask=$mode$u_plus_rw;; 2631f0ac6a5Smrg esac 2641f0ac6a5Smrgfi 2651f0ac6a5Smrg 2661f0ac6a5Smrgfor src 2671f0ac6a5Smrgdo 26889c04b6cSmrg # Protect names problematic for 'test' and other utilities. 2691f0ac6a5Smrg case $src in 27089c04b6cSmrg -* | [=\(\)!]) src=./$src;; 2711f0ac6a5Smrg esac 2721f0ac6a5Smrg 2731f0ac6a5Smrg if test -n "$dir_arg"; then 2741f0ac6a5Smrg dst=$src 2751f0ac6a5Smrg dstdir=$dst 2761f0ac6a5Smrg test -d "$dstdir" 2771f0ac6a5Smrg dstdir_status=$? 278d21ab8bcSmrg # Don't chown directories that already exist. 279d21ab8bcSmrg if test $dstdir_status = 0; then 280d21ab8bcSmrg chowncmd="" 281d21ab8bcSmrg fi 2821f0ac6a5Smrg else 2831f0ac6a5Smrg 2841f0ac6a5Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2851f0ac6a5Smrg # might cause directories to be created, which would be especially bad 2861f0ac6a5Smrg # if $src (and thus $dsttmp) contains '*'. 2871f0ac6a5Smrg if test ! -f "$src" && test ! -d "$src"; then 2881f0ac6a5Smrg echo "$0: $src does not exist." >&2 2891f0ac6a5Smrg exit 1 2901f0ac6a5Smrg fi 2911f0ac6a5Smrg 292e5410a46Smrg if test -z "$dst_arg"; then 2931f0ac6a5Smrg echo "$0: no destination specified." >&2 2941f0ac6a5Smrg exit 1 2951f0ac6a5Smrg fi 296e5410a46Smrg dst=$dst_arg 2971f0ac6a5Smrg 298d21ab8bcSmrg # If destination is a directory, append the input filename. 2991f0ac6a5Smrg if test -d "$dst"; then 300d21ab8bcSmrg if test "$is_target_a_directory" = never; then 301d21ab8bcSmrg echo "$0: $dst_arg: Is a directory" >&2 302d21ab8bcSmrg exit 1 3031f0ac6a5Smrg fi 3041f0ac6a5Smrg dstdir=$dst 305d21ab8bcSmrg dstbase=`basename "$src"` 306d21ab8bcSmrg case $dst in 307d21ab8bcSmrg */) dst=$dst$dstbase;; 308d21ab8bcSmrg *) dst=$dst/$dstbase;; 309d21ab8bcSmrg esac 3101f0ac6a5Smrg dstdir_status=0 3111f0ac6a5Smrg else 312d21ab8bcSmrg dstdir=`dirname "$dst"` 3131f0ac6a5Smrg test -d "$dstdir" 3141f0ac6a5Smrg dstdir_status=$? 3151f0ac6a5Smrg fi 3161f0ac6a5Smrg fi 3171f0ac6a5Smrg 318d21ab8bcSmrg case $dstdir in 319d21ab8bcSmrg */) dstdirslash=$dstdir;; 320d21ab8bcSmrg *) dstdirslash=$dstdir/;; 321d21ab8bcSmrg esac 322d21ab8bcSmrg 3231f0ac6a5Smrg obsolete_mkdir_used=false 3241f0ac6a5Smrg 3251f0ac6a5Smrg if test $dstdir_status != 0; then 3261f0ac6a5Smrg case $posix_mkdir in 3271f0ac6a5Smrg '') 328d21ab8bcSmrg # With -d, create the new directory with the user-specified mode. 329d21ab8bcSmrg # Otherwise, rely on $mkdir_umask. 330d21ab8bcSmrg if test -n "$dir_arg"; then 331d21ab8bcSmrg mkdir_mode=-m$mode 332d21ab8bcSmrg else 333d21ab8bcSmrg mkdir_mode= 334d21ab8bcSmrg fi 335d21ab8bcSmrg 336d21ab8bcSmrg posix_mkdir=false 337d21ab8bcSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 338d21ab8bcSmrg # here however when possible just to lower collision chance. 339d21ab8bcSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340d21ab8bcSmrg 341d21ab8bcSmrg trap ' 342d21ab8bcSmrg ret=$? 343d21ab8bcSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344d21ab8bcSmrg exit $ret 345d21ab8bcSmrg ' 0 346d21ab8bcSmrg 347d21ab8bcSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348d21ab8bcSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349d21ab8bcSmrg # directory is successfully created first before we actually test 350d21ab8bcSmrg # 'mkdir -p'. 351d21ab8bcSmrg if (umask $mkdir_umask && 352d21ab8bcSmrg $mkdirprog $mkdir_mode "$tmpdir" && 353d21ab8bcSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354d21ab8bcSmrg then 355d21ab8bcSmrg if test -z "$dir_arg" || { 356d21ab8bcSmrg # Check for POSIX incompatibilities with -m. 357d21ab8bcSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358d21ab8bcSmrg # other-writable bit of parent directory when it shouldn't. 359d21ab8bcSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360d21ab8bcSmrg test_tmpdir="$tmpdir/a" 361d21ab8bcSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362d21ab8bcSmrg case $ls_ld_tmpdir in 363d21ab8bcSmrg d????-?r-*) different_mode=700;; 364d21ab8bcSmrg d????-?--*) different_mode=755;; 365d21ab8bcSmrg *) false;; 366d21ab8bcSmrg esac && 367d21ab8bcSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368d21ab8bcSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369d21ab8bcSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370d21ab8bcSmrg } 371d21ab8bcSmrg } 372d21ab8bcSmrg then posix_mkdir=: 373d21ab8bcSmrg fi 374d21ab8bcSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3752fd96bc7Smrg else 376d21ab8bcSmrg # Remove any dirs left behind by ancient mkdir implementations. 377d21ab8bcSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3782fd96bc7Smrg fi 379d21ab8bcSmrg trap '' 0;; 3801f0ac6a5Smrg esac 3811f0ac6a5Smrg 3821f0ac6a5Smrg if 3831f0ac6a5Smrg $posix_mkdir && ( 384d21ab8bcSmrg umask $mkdir_umask && 385d21ab8bcSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3861f0ac6a5Smrg ) 3871f0ac6a5Smrg then : 3881f0ac6a5Smrg else 3891f0ac6a5Smrg 390d21ab8bcSmrg # mkdir does not conform to POSIX, 3911f0ac6a5Smrg # or it failed possibly due to a race condition. Create the 3921f0ac6a5Smrg # directory the slow way, step by step, checking for races as we go. 3931f0ac6a5Smrg 3941f0ac6a5Smrg case $dstdir in 395d21ab8bcSmrg /*) prefix='/';; 396d21ab8bcSmrg [-=\(\)!]*) prefix='./';; 397d21ab8bcSmrg *) prefix='';; 3981f0ac6a5Smrg esac 3991f0ac6a5Smrg 4001f0ac6a5Smrg oIFS=$IFS 4011f0ac6a5Smrg IFS=/ 402d21ab8bcSmrg set -f 4031f0ac6a5Smrg set fnord $dstdir 4041f0ac6a5Smrg shift 405d21ab8bcSmrg set +f 4061f0ac6a5Smrg IFS=$oIFS 4071f0ac6a5Smrg 4081f0ac6a5Smrg prefixes= 4091f0ac6a5Smrg 4101f0ac6a5Smrg for d 4111f0ac6a5Smrg do 412d21ab8bcSmrg test X"$d" = X && continue 413d21ab8bcSmrg 414d21ab8bcSmrg prefix=$prefix$d 415d21ab8bcSmrg if test -d "$prefix"; then 416d21ab8bcSmrg prefixes= 417d21ab8bcSmrg else 418d21ab8bcSmrg if $posix_mkdir; then 419d21ab8bcSmrg (umask $mkdir_umask && 420d21ab8bcSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421d21ab8bcSmrg # Don't fail if two instances are running concurrently. 422d21ab8bcSmrg test -d "$prefix" || exit 1 423d21ab8bcSmrg else 424d21ab8bcSmrg case $prefix in 425d21ab8bcSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426d21ab8bcSmrg *) qprefix=$prefix;; 427d21ab8bcSmrg esac 428d21ab8bcSmrg prefixes="$prefixes '$qprefix'" 429d21ab8bcSmrg fi 430d21ab8bcSmrg fi 431d21ab8bcSmrg prefix=$prefix/ 4321f0ac6a5Smrg done 4331f0ac6a5Smrg 4341f0ac6a5Smrg if test -n "$prefixes"; then 435d21ab8bcSmrg # Don't fail if two instances are running concurrently. 436d21ab8bcSmrg (umask $mkdir_umask && 437d21ab8bcSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 438d21ab8bcSmrg test -d "$dstdir" || exit 1 439d21ab8bcSmrg obsolete_mkdir_used=true 4401f0ac6a5Smrg fi 4411f0ac6a5Smrg fi 4421f0ac6a5Smrg fi 4431f0ac6a5Smrg 4441f0ac6a5Smrg if test -n "$dir_arg"; then 4451f0ac6a5Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4461f0ac6a5Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4471f0ac6a5Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4481f0ac6a5Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4491f0ac6a5Smrg else 4501f0ac6a5Smrg 4511f0ac6a5Smrg # Make a couple of temp file names in the proper directory. 452d21ab8bcSmrg dsttmp=${dstdirslash}_inst.$$_ 453d21ab8bcSmrg rmtmp=${dstdirslash}_rm.$$_ 4541f0ac6a5Smrg 4551f0ac6a5Smrg # Trap to clean up those temp files at exit. 4561f0ac6a5Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4571f0ac6a5Smrg 4581f0ac6a5Smrg # Copy the file name to the temp name. 459d21ab8bcSmrg (umask $cp_umask && 460d21ab8bcSmrg { test -z "$stripcmd" || { 461d21ab8bcSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462d21ab8bcSmrg # which would cause strip to fail. 463d21ab8bcSmrg if test -z "$doit"; then 464d21ab8bcSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 465d21ab8bcSmrg else 466d21ab8bcSmrg $doit touch "$dsttmp" 467d21ab8bcSmrg fi 468d21ab8bcSmrg } 469d21ab8bcSmrg } && 470d21ab8bcSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4711f0ac6a5Smrg 4721f0ac6a5Smrg # and set any options; do chmod last to preserve setuid bits. 4731f0ac6a5Smrg # 4741f0ac6a5Smrg # If any of these fail, we abort the whole thing. If we want to 4751f0ac6a5Smrg # ignore errors from any of these, just make sure not to ignore 4761f0ac6a5Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4771f0ac6a5Smrg # 478e5410a46Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479e5410a46Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480e5410a46Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481e5410a46Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482e5410a46Smrg 483e5410a46Smrg # If -C, don't bother to copy if it wouldn't change the file. 484e5410a46Smrg if $copy_on_change && 485d21ab8bcSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486d21ab8bcSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487d21ab8bcSmrg set -f && 488e5410a46Smrg set X $old && old=:$2:$4:$5:$6 && 489e5410a46Smrg set X $new && new=:$2:$4:$5:$6 && 490d21ab8bcSmrg set +f && 491e5410a46Smrg test "$old" = "$new" && 492e5410a46Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493e5410a46Smrg then 494e5410a46Smrg rm -f "$dsttmp" 495e5410a46Smrg else 496d21ab8bcSmrg # If $backupsuffix is set, and the file being installed 497d21ab8bcSmrg # already exists, attempt a backup. Don't worry if it fails, 498d21ab8bcSmrg # e.g., if mv doesn't support -f. 499d21ab8bcSmrg if test -n "$backupsuffix" && test -f "$dst"; then 500d21ab8bcSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501d21ab8bcSmrg fi 502d21ab8bcSmrg 503e5410a46Smrg # Rename the file to the real destination. 504e5410a46Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505e5410a46Smrg 506e5410a46Smrg # The rename failed, perhaps because mv can't rename something else 507e5410a46Smrg # to itself, or perhaps because mv is so ancient that it does not 508e5410a46Smrg # support -f. 509e5410a46Smrg { 510d21ab8bcSmrg # Now remove or move aside any old file at destination location. 511d21ab8bcSmrg # We try this two ways since rm can't unlink itself on some 512d21ab8bcSmrg # systems and the destination file might be busy for other 513d21ab8bcSmrg # reasons. In this case, the final cleanup might fail but the new 514d21ab8bcSmrg # file should still install successfully. 515d21ab8bcSmrg { 516d21ab8bcSmrg test ! -f "$dst" || 517d21ab8bcSmrg $doit $rmcmd "$dst" 2>/dev/null || 518d21ab8bcSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519d21ab8bcSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520d21ab8bcSmrg } || 521d21ab8bcSmrg { echo "$0: cannot unlink or rename $dst" >&2 522d21ab8bcSmrg (exit 1); exit 1 523d21ab8bcSmrg } 524d21ab8bcSmrg } && 525d21ab8bcSmrg 526d21ab8bcSmrg # Now rename the file to the real destination. 527d21ab8bcSmrg $doit $mvcmd "$dsttmp" "$dst" 528e5410a46Smrg } 529e5410a46Smrg fi || exit 1 5301f0ac6a5Smrg 5311f0ac6a5Smrg trap '' 0 5321f0ac6a5Smrg fi 5331f0ac6a5Smrgdone 5341f0ac6a5Smrg 5351f0ac6a5Smrg# Local variables: 536d21ab8bcSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5371f0ac6a5Smrg# time-stamp-start: "scriptversion=" 5381f0ac6a5Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 539d21ab8bcSmrg# time-stamp-time-zone: "UTC0" 540e5410a46Smrg# time-stamp-end: "; # UTC" 5411f0ac6a5Smrg# End: 542