install-sh revision f9c28e31
1fc89c0fbSmrg#!/bin/sh 2fc89c0fbSmrg# install - install a program, script, or datafile 3fc89c0fbSmrg 4f9c28e31Smrgscriptversion=2018-03-11.20; # UTC 5fc89c0fbSmrg 6fc89c0fbSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7fc89c0fbSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8fc89c0fbSmrg# following copyright and license. 9fc89c0fbSmrg# 10fc89c0fbSmrg# Copyright (C) 1994 X Consortium 11fc89c0fbSmrg# 12fc89c0fbSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13fc89c0fbSmrg# of this software and associated documentation files (the "Software"), to 14fc89c0fbSmrg# deal in the Software without restriction, including without limitation the 15fc89c0fbSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16fc89c0fbSmrg# sell copies of the Software, and to permit persons to whom the Software is 17fc89c0fbSmrg# furnished to do so, subject to the following conditions: 18fc89c0fbSmrg# 19fc89c0fbSmrg# The above copyright notice and this permission notice shall be included in 20fc89c0fbSmrg# all copies or substantial portions of the Software. 21fc89c0fbSmrg# 22fc89c0fbSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23fc89c0fbSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24fc89c0fbSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25fc89c0fbSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26fc89c0fbSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27fc89c0fbSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28fc89c0fbSmrg# 29fc89c0fbSmrg# Except as contained in this notice, the name of the X Consortium shall not 30fc89c0fbSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31fc89c0fbSmrg# ings in this Software without prior written authorization from the X Consor- 32fc89c0fbSmrg# tium. 33fc89c0fbSmrg# 34fc89c0fbSmrg# 35fc89c0fbSmrg# FSF changes to this file are in the public domain. 36fc89c0fbSmrg# 37fc89c0fbSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38576bbdfcSmrg# 'make' implicit rules from creating a file called install from it 39fc89c0fbSmrg# when there is no Makefile. 40fc89c0fbSmrg# 41fc89c0fbSmrg# This script is compatible with the BSD install script, but was written 42fc89c0fbSmrg# from scratch. 43fc89c0fbSmrg 4481676fe2Smrgtab=' ' 45fc89c0fbSmrgnl=' 46fc89c0fbSmrg' 4781676fe2SmrgIFS=" $tab$nl" 48fc89c0fbSmrg 4981676fe2Smrg# Set DOITPROG to "echo" to test this script. 50fc89c0fbSmrg 5191ec45ceSmrgdoit=${DOITPROG-} 5281676fe2Smrgdoit_exec=${doit:-exec} 53fc89c0fbSmrg 54fc89c0fbSmrg# Put in absolute file names if you don't have them in your path; 55fc89c0fbSmrg# or use environment vars. 56fc89c0fbSmrg 5791ec45ceSmrgchgrpprog=${CHGRPPROG-chgrp} 5891ec45ceSmrgchmodprog=${CHMODPROG-chmod} 5991ec45ceSmrgchownprog=${CHOWNPROG-chown} 6091ec45ceSmrgcmpprog=${CMPPROG-cmp} 6191ec45ceSmrgcpprog=${CPPROG-cp} 6291ec45ceSmrgmkdirprog=${MKDIRPROG-mkdir} 6391ec45ceSmrgmvprog=${MVPROG-mv} 6491ec45ceSmrgrmprog=${RMPROG-rm} 6591ec45ceSmrgstripprog=${STRIPPROG-strip} 6691ec45ceSmrg 67fc89c0fbSmrgposix_mkdir= 68fc89c0fbSmrg 69fc89c0fbSmrg# Desired mode of installed file. 70fc89c0fbSmrgmode=0755 71fc89c0fbSmrg 7291ec45ceSmrgchgrpcmd= 73fc89c0fbSmrgchmodcmd=$chmodprog 74fc89c0fbSmrgchowncmd= 7591ec45ceSmrgmvcmd=$mvprog 76fc89c0fbSmrgrmcmd="$rmprog -f" 7791ec45ceSmrgstripcmd= 7891ec45ceSmrg 79fc89c0fbSmrgsrc= 80fc89c0fbSmrgdst= 81fc89c0fbSmrgdir_arg= 8291ec45ceSmrgdst_arg= 8391ec45ceSmrg 8491ec45ceSmrgcopy_on_change=false 8581676fe2Smrgis_target_a_directory=possibly 86fc89c0fbSmrg 8791ec45ceSmrgusage="\ 8891ec45ceSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89fc89c0fbSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90fc89c0fbSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91fc89c0fbSmrg or: $0 [OPTION]... -d DIRECTORIES... 92fc89c0fbSmrg 93fc89c0fbSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94fc89c0fbSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95fc89c0fbSmrgIn the 4th, create DIRECTORIES. 96fc89c0fbSmrg 97fc89c0fbSmrgOptions: 9891ec45ceSmrg --help display this help and exit. 9991ec45ceSmrg --version display version info and exit. 10091ec45ceSmrg 10191ec45ceSmrg -c (ignored) 10291ec45ceSmrg -C install only if different (preserve the last data modification time) 10391ec45ceSmrg -d create directories instead of installing files. 10491ec45ceSmrg -g GROUP $chgrpprog installed files to GROUP. 10591ec45ceSmrg -m MODE $chmodprog installed files to MODE. 10691ec45ceSmrg -o USER $chownprog installed files to USER. 10791ec45ceSmrg -s $stripprog installed files. 10891ec45ceSmrg -t DIRECTORY install into DIRECTORY. 10991ec45ceSmrg -T report an error if DSTFILE is a directory. 110fc89c0fbSmrg 111fc89c0fbSmrgEnvironment variables override the default commands: 11291ec45ceSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11391ec45ceSmrg RMPROG STRIPPROG 114fc89c0fbSmrg" 115fc89c0fbSmrg 116fc89c0fbSmrgwhile test $# -ne 0; do 117fc89c0fbSmrg case $1 in 11891ec45ceSmrg -c) ;; 11991ec45ceSmrg 12091ec45ceSmrg -C) copy_on_change=true;; 121fc89c0fbSmrg 12291ec45ceSmrg -d) dir_arg=true;; 123fc89c0fbSmrg 124fc89c0fbSmrg -g) chgrpcmd="$chgrpprog $2" 12581676fe2Smrg shift;; 126fc89c0fbSmrg 127fc89c0fbSmrg --help) echo "$usage"; exit $?;; 128fc89c0fbSmrg 129fc89c0fbSmrg -m) mode=$2 13081676fe2Smrg case $mode in 13181676fe2Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 13281676fe2Smrg echo "$0: invalid mode: $mode" >&2 13381676fe2Smrg exit 1;; 13481676fe2Smrg esac 13581676fe2Smrg shift;; 136fc89c0fbSmrg 137fc89c0fbSmrg -o) chowncmd="$chownprog $2" 13881676fe2Smrg shift;; 139fc89c0fbSmrg 14091ec45ceSmrg -s) stripcmd=$stripprog;; 141fc89c0fbSmrg 14281676fe2Smrg -t) 14381676fe2Smrg is_target_a_directory=always 14481676fe2Smrg dst_arg=$2 14581676fe2Smrg # Protect names problematic for 'test' and other utilities. 14681676fe2Smrg case $dst_arg in 14781676fe2Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 14881676fe2Smrg esac 14981676fe2Smrg shift;; 150fc89c0fbSmrg 15181676fe2Smrg -T) is_target_a_directory=never;; 152fc89c0fbSmrg 153fc89c0fbSmrg --version) echo "$0 $scriptversion"; exit $?;; 154fc89c0fbSmrg 15581676fe2Smrg --) shift 15681676fe2Smrg break;; 157fc89c0fbSmrg 15881676fe2Smrg -*) echo "$0: invalid option: $1" >&2 15981676fe2Smrg exit 1;; 160fc89c0fbSmrg 161fc89c0fbSmrg *) break;; 162fc89c0fbSmrg esac 16391ec45ceSmrg shift 164fc89c0fbSmrgdone 165fc89c0fbSmrg 16681676fe2Smrg# We allow the use of options -d and -T together, by making -d 16781676fe2Smrg# take the precedence; this is for compatibility with GNU install. 16881676fe2Smrg 16981676fe2Smrgif test -n "$dir_arg"; then 17081676fe2Smrg if test -n "$dst_arg"; then 17181676fe2Smrg echo "$0: target directory not allowed when installing a directory." >&2 17281676fe2Smrg exit 1 17381676fe2Smrg fi 17481676fe2Smrgfi 17581676fe2Smrg 17691ec45ceSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177fc89c0fbSmrg # When -d is used, all remaining arguments are directories to create. 178fc89c0fbSmrg # When -t is used, the destination is already specified. 179fc89c0fbSmrg # Otherwise, the last argument is the destination. Remove it from $@. 180fc89c0fbSmrg for arg 181fc89c0fbSmrg do 18291ec45ceSmrg if test -n "$dst_arg"; then 183fc89c0fbSmrg # $@ is not empty: it contains at least $arg. 18491ec45ceSmrg set fnord "$@" "$dst_arg" 185fc89c0fbSmrg shift # fnord 186fc89c0fbSmrg fi 187fc89c0fbSmrg shift # arg 18891ec45ceSmrg dst_arg=$arg 189576bbdfcSmrg # Protect names problematic for 'test' and other utilities. 190576bbdfcSmrg case $dst_arg in 191576bbdfcSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192576bbdfcSmrg esac 193fc89c0fbSmrg done 194fc89c0fbSmrgfi 195fc89c0fbSmrg 196fc89c0fbSmrgif test $# -eq 0; then 197fc89c0fbSmrg if test -z "$dir_arg"; then 198fc89c0fbSmrg echo "$0: no input file specified." >&2 199fc89c0fbSmrg exit 1 200fc89c0fbSmrg fi 201576bbdfcSmrg # It's OK to call 'install-sh -d' without argument. 202fc89c0fbSmrg # This can happen when creating conditional directories. 203fc89c0fbSmrg exit 0 204fc89c0fbSmrgfi 205fc89c0fbSmrg 20681676fe2Smrgif test -z "$dir_arg"; then 20781676fe2Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 20881676fe2Smrg if test ! -d "$dst_arg"; then 20981676fe2Smrg echo "$0: $dst_arg: Is not a directory." >&2 21081676fe2Smrg exit 1 21181676fe2Smrg fi 21281676fe2Smrg fi 21381676fe2Smrgfi 21481676fe2Smrg 215fc89c0fbSmrgif test -z "$dir_arg"; then 216576bbdfcSmrg do_exit='(exit $ret); exit $ret' 217576bbdfcSmrg trap "ret=129; $do_exit" 1 218576bbdfcSmrg trap "ret=130; $do_exit" 2 219576bbdfcSmrg trap "ret=141; $do_exit" 13 220576bbdfcSmrg trap "ret=143; $do_exit" 15 221fc89c0fbSmrg 222fc89c0fbSmrg # Set umask so as not to create temps with too-generous modes. 223fc89c0fbSmrg # However, 'strip' requires both read and write access to temps. 224fc89c0fbSmrg case $mode in 225fc89c0fbSmrg # Optimize common cases. 226fc89c0fbSmrg *644) cp_umask=133;; 227fc89c0fbSmrg *755) cp_umask=22;; 228fc89c0fbSmrg 229fc89c0fbSmrg *[0-7]) 230fc89c0fbSmrg if test -z "$stripcmd"; then 23181676fe2Smrg u_plus_rw= 232fc89c0fbSmrg else 23381676fe2Smrg u_plus_rw='% 200' 234fc89c0fbSmrg fi 235fc89c0fbSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236fc89c0fbSmrg *) 237fc89c0fbSmrg if test -z "$stripcmd"; then 23881676fe2Smrg u_plus_rw= 239fc89c0fbSmrg else 24081676fe2Smrg u_plus_rw=,u+rw 241fc89c0fbSmrg fi 242fc89c0fbSmrg cp_umask=$mode$u_plus_rw;; 243fc89c0fbSmrg esac 244fc89c0fbSmrgfi 245fc89c0fbSmrg 246fc89c0fbSmrgfor src 247fc89c0fbSmrgdo 248576bbdfcSmrg # Protect names problematic for 'test' and other utilities. 249fc89c0fbSmrg case $src in 250576bbdfcSmrg -* | [=\(\)!]) src=./$src;; 251fc89c0fbSmrg esac 252fc89c0fbSmrg 253fc89c0fbSmrg if test -n "$dir_arg"; then 254fc89c0fbSmrg dst=$src 255fc89c0fbSmrg dstdir=$dst 256fc89c0fbSmrg test -d "$dstdir" 257fc89c0fbSmrg dstdir_status=$? 258fc89c0fbSmrg else 259fc89c0fbSmrg 260fc89c0fbSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261fc89c0fbSmrg # might cause directories to be created, which would be especially bad 262fc89c0fbSmrg # if $src (and thus $dsttmp) contains '*'. 263fc89c0fbSmrg if test ! -f "$src" && test ! -d "$src"; then 264fc89c0fbSmrg echo "$0: $src does not exist." >&2 265fc89c0fbSmrg exit 1 266fc89c0fbSmrg fi 267fc89c0fbSmrg 26891ec45ceSmrg if test -z "$dst_arg"; then 269fc89c0fbSmrg echo "$0: no destination specified." >&2 270fc89c0fbSmrg exit 1 271fc89c0fbSmrg fi 27291ec45ceSmrg dst=$dst_arg 273fc89c0fbSmrg 274f9c28e31Smrg # If destination is a directory, append the input filename. 275fc89c0fbSmrg if test -d "$dst"; then 27681676fe2Smrg if test "$is_target_a_directory" = never; then 27781676fe2Smrg echo "$0: $dst_arg: Is a directory" >&2 27881676fe2Smrg exit 1 279fc89c0fbSmrg fi 280fc89c0fbSmrg dstdir=$dst 281f9c28e31Smrg dstbase=`basename "$src"` 282f9c28e31Smrg case $dst in 283f9c28e31Smrg */) dst=$dst$dstbase;; 284f9c28e31Smrg *) dst=$dst/$dstbase;; 285f9c28e31Smrg esac 286fc89c0fbSmrg dstdir_status=0 287fc89c0fbSmrg else 28881676fe2Smrg dstdir=`dirname "$dst"` 289fc89c0fbSmrg test -d "$dstdir" 290fc89c0fbSmrg dstdir_status=$? 291fc89c0fbSmrg fi 292fc89c0fbSmrg fi 293fc89c0fbSmrg 294f9c28e31Smrg case $dstdir in 295f9c28e31Smrg */) dstdirslash=$dstdir;; 296f9c28e31Smrg *) dstdirslash=$dstdir/;; 297f9c28e31Smrg esac 298f9c28e31Smrg 299fc89c0fbSmrg obsolete_mkdir_used=false 300fc89c0fbSmrg 301fc89c0fbSmrg if test $dstdir_status != 0; then 302fc89c0fbSmrg case $posix_mkdir in 303fc89c0fbSmrg '') 30481676fe2Smrg # Create intermediate dirs using mode 755 as modified by the umask. 30581676fe2Smrg # This is like FreeBSD 'install' as of 1997-10-28. 30681676fe2Smrg umask=`umask` 30781676fe2Smrg case $stripcmd.$umask in 30881676fe2Smrg # Optimize common cases. 30981676fe2Smrg *[2367][2367]) mkdir_umask=$umask;; 31081676fe2Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 31181676fe2Smrg 31281676fe2Smrg *[0-7]) 31381676fe2Smrg mkdir_umask=`expr $umask + 22 \ 31481676fe2Smrg - $umask % 100 % 40 + $umask % 20 \ 31581676fe2Smrg - $umask % 10 % 4 + $umask % 2 31681676fe2Smrg `;; 31781676fe2Smrg *) mkdir_umask=$umask,go-w;; 31881676fe2Smrg esac 31981676fe2Smrg 32081676fe2Smrg # With -d, create the new directory with the user-specified mode. 32181676fe2Smrg # Otherwise, rely on $mkdir_umask. 32281676fe2Smrg if test -n "$dir_arg"; then 32381676fe2Smrg mkdir_mode=-m$mode 32481676fe2Smrg else 32581676fe2Smrg mkdir_mode= 32681676fe2Smrg fi 32781676fe2Smrg 32881676fe2Smrg posix_mkdir=false 32981676fe2Smrg case $umask in 33081676fe2Smrg *[123567][0-7][0-7]) 33181676fe2Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 33281676fe2Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 33381676fe2Smrg ;; 33481676fe2Smrg *) 335f9c28e31Smrg # Note that $RANDOM variable is not portable (e.g. dash); Use it 336f9c28e31Smrg # here however when possible just to lower collision chance. 33781676fe2Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 33881676fe2Smrg 339f9c28e31Smrg trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 340f9c28e31Smrg 341f9c28e31Smrg # Because "mkdir -p" follows existing symlinks and we likely work 342f9c28e31Smrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 343f9c28e31Smrg # directory is successfully created first before we actually test 344f9c28e31Smrg # 'mkdir -p' feature. 34581676fe2Smrg if (umask $mkdir_umask && 346f9c28e31Smrg $mkdirprog $mkdir_mode "$tmpdir" && 347f9c28e31Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 34881676fe2Smrg then 34981676fe2Smrg if test -z "$dir_arg" || { 35081676fe2Smrg # Check for POSIX incompatibilities with -m. 35181676fe2Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35281676fe2Smrg # other-writable bit of parent directory when it shouldn't. 35381676fe2Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 354f9c28e31Smrg test_tmpdir="$tmpdir/a" 355f9c28e31Smrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 35681676fe2Smrg case $ls_ld_tmpdir in 35781676fe2Smrg d????-?r-*) different_mode=700;; 35881676fe2Smrg d????-?--*) different_mode=755;; 35981676fe2Smrg *) false;; 36081676fe2Smrg esac && 361f9c28e31Smrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 362f9c28e31Smrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 36381676fe2Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 36481676fe2Smrg } 36581676fe2Smrg } 36681676fe2Smrg then posix_mkdir=: 36781676fe2Smrg fi 368f9c28e31Smrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 36981676fe2Smrg else 37081676fe2Smrg # Remove any dirs left behind by ancient mkdir implementations. 371f9c28e31Smrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 37281676fe2Smrg fi 37381676fe2Smrg trap '' 0;; 37481676fe2Smrg esac;; 375fc89c0fbSmrg esac 376fc89c0fbSmrg 377fc89c0fbSmrg if 378fc89c0fbSmrg $posix_mkdir && ( 37981676fe2Smrg umask $mkdir_umask && 38081676fe2Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 381fc89c0fbSmrg ) 382fc89c0fbSmrg then : 383fc89c0fbSmrg else 384fc89c0fbSmrg 385fc89c0fbSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 386fc89c0fbSmrg # or it failed possibly due to a race condition. Create the 387fc89c0fbSmrg # directory the slow way, step by step, checking for races as we go. 388fc89c0fbSmrg 389fc89c0fbSmrg case $dstdir in 39081676fe2Smrg /*) prefix='/';; 39181676fe2Smrg [-=\(\)!]*) prefix='./';; 39281676fe2Smrg *) prefix='';; 393fc89c0fbSmrg esac 394fc89c0fbSmrg 395fc89c0fbSmrg oIFS=$IFS 396fc89c0fbSmrg IFS=/ 39781676fe2Smrg set -f 398fc89c0fbSmrg set fnord $dstdir 399fc89c0fbSmrg shift 40081676fe2Smrg set +f 401fc89c0fbSmrg IFS=$oIFS 402fc89c0fbSmrg 403fc89c0fbSmrg prefixes= 404fc89c0fbSmrg 405fc89c0fbSmrg for d 406fc89c0fbSmrg do 40781676fe2Smrg test X"$d" = X && continue 40881676fe2Smrg 40981676fe2Smrg prefix=$prefix$d 41081676fe2Smrg if test -d "$prefix"; then 41181676fe2Smrg prefixes= 41281676fe2Smrg else 41381676fe2Smrg if $posix_mkdir; then 41481676fe2Smrg (umask=$mkdir_umask && 41581676fe2Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 41681676fe2Smrg # Don't fail if two instances are running concurrently. 41781676fe2Smrg test -d "$prefix" || exit 1 41881676fe2Smrg else 41981676fe2Smrg case $prefix in 42081676fe2Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42181676fe2Smrg *) qprefix=$prefix;; 42281676fe2Smrg esac 42381676fe2Smrg prefixes="$prefixes '$qprefix'" 42481676fe2Smrg fi 42581676fe2Smrg fi 42681676fe2Smrg prefix=$prefix/ 427fc89c0fbSmrg done 428fc89c0fbSmrg 429fc89c0fbSmrg if test -n "$prefixes"; then 43081676fe2Smrg # Don't fail if two instances are running concurrently. 43181676fe2Smrg (umask $mkdir_umask && 43281676fe2Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 43381676fe2Smrg test -d "$dstdir" || exit 1 43481676fe2Smrg obsolete_mkdir_used=true 435fc89c0fbSmrg fi 436fc89c0fbSmrg fi 437fc89c0fbSmrg fi 438fc89c0fbSmrg 439fc89c0fbSmrg if test -n "$dir_arg"; then 440fc89c0fbSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441fc89c0fbSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442fc89c0fbSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443fc89c0fbSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 444fc89c0fbSmrg else 445fc89c0fbSmrg 446fc89c0fbSmrg # Make a couple of temp file names in the proper directory. 447f9c28e31Smrg dsttmp=${dstdirslash}_inst.$$_ 448f9c28e31Smrg rmtmp=${dstdirslash}_rm.$$_ 449fc89c0fbSmrg 450fc89c0fbSmrg # Trap to clean up those temp files at exit. 451fc89c0fbSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 452fc89c0fbSmrg 453fc89c0fbSmrg # Copy the file name to the temp name. 454f9c28e31Smrg (umask $cp_umask && 455f9c28e31Smrg { test -z "$stripcmd" || { 456f9c28e31Smrg # Create $dsttmp read-write so that cp doesn't create it read-only, 457f9c28e31Smrg # which would cause strip to fail. 458f9c28e31Smrg if test -z "$doit"; then 459f9c28e31Smrg : >"$dsttmp" # No need to fork-exec 'touch'. 460f9c28e31Smrg else 461f9c28e31Smrg $doit touch "$dsttmp" 462f9c28e31Smrg fi 463f9c28e31Smrg } 464f9c28e31Smrg } && 465f9c28e31Smrg $doit_exec $cpprog "$src" "$dsttmp") && 466fc89c0fbSmrg 467fc89c0fbSmrg # and set any options; do chmod last to preserve setuid bits. 468fc89c0fbSmrg # 469fc89c0fbSmrg # If any of these fail, we abort the whole thing. If we want to 470fc89c0fbSmrg # ignore errors from any of these, just make sure not to ignore 471fc89c0fbSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 472fc89c0fbSmrg # 47391ec45ceSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 47491ec45ceSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 47591ec45ceSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 47691ec45ceSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 47791ec45ceSmrg 47891ec45ceSmrg # If -C, don't bother to copy if it wouldn't change the file. 47991ec45ceSmrg if $copy_on_change && 48081676fe2Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 48181676fe2Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 48281676fe2Smrg set -f && 48391ec45ceSmrg set X $old && old=:$2:$4:$5:$6 && 48491ec45ceSmrg set X $new && new=:$2:$4:$5:$6 && 48581676fe2Smrg set +f && 48691ec45ceSmrg test "$old" = "$new" && 48791ec45ceSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 48891ec45ceSmrg then 48991ec45ceSmrg rm -f "$dsttmp" 49091ec45ceSmrg else 49191ec45ceSmrg # Rename the file to the real destination. 49291ec45ceSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 49391ec45ceSmrg 49491ec45ceSmrg # The rename failed, perhaps because mv can't rename something else 49591ec45ceSmrg # to itself, or perhaps because mv is so ancient that it does not 49691ec45ceSmrg # support -f. 49791ec45ceSmrg { 49881676fe2Smrg # Now remove or move aside any old file at destination location. 49981676fe2Smrg # We try this two ways since rm can't unlink itself on some 50081676fe2Smrg # systems and the destination file might be busy for other 50181676fe2Smrg # reasons. In this case, the final cleanup might fail but the new 50281676fe2Smrg # file should still install successfully. 50381676fe2Smrg { 50481676fe2Smrg test ! -f "$dst" || 50581676fe2Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 50681676fe2Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 50781676fe2Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 50881676fe2Smrg } || 50981676fe2Smrg { echo "$0: cannot unlink or rename $dst" >&2 51081676fe2Smrg (exit 1); exit 1 51181676fe2Smrg } 51281676fe2Smrg } && 51381676fe2Smrg 51481676fe2Smrg # Now rename the file to the real destination. 51581676fe2Smrg $doit $mvcmd "$dsttmp" "$dst" 51691ec45ceSmrg } 51791ec45ceSmrg fi || exit 1 518fc89c0fbSmrg 519fc89c0fbSmrg trap '' 0 520fc89c0fbSmrg fi 521fc89c0fbSmrgdone 522fc89c0fbSmrg 523fc89c0fbSmrg# Local variables: 524f9c28e31Smrg# eval: (add-hook 'before-save-hook 'time-stamp) 525fc89c0fbSmrg# time-stamp-start: "scriptversion=" 526fc89c0fbSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 527f9c28e31Smrg# time-stamp-time-zone: "UTC0" 52891ec45ceSmrg# time-stamp-end: "; # UTC" 529fc89c0fbSmrg# End: 530