install-sh revision 9e1184fe
18b22bf3fSmrg#!/bin/sh 28b22bf3fSmrg# install - install a program, script, or datafile 38b22bf3fSmrg 49e1184feSmrgscriptversion=2018-03-11.20; # UTC 58b22bf3fSmrg 68b22bf3fSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 78b22bf3fSmrg# later released in X11R6 (xc/config/util/install.sh) with the 88b22bf3fSmrg# following copyright and license. 98b22bf3fSmrg# 108b22bf3fSmrg# Copyright (C) 1994 X Consortium 118b22bf3fSmrg# 128b22bf3fSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 138b22bf3fSmrg# of this software and associated documentation files (the "Software"), to 148b22bf3fSmrg# deal in the Software without restriction, including without limitation the 158b22bf3fSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 168b22bf3fSmrg# sell copies of the Software, and to permit persons to whom the Software is 178b22bf3fSmrg# furnished to do so, subject to the following conditions: 188b22bf3fSmrg# 198b22bf3fSmrg# The above copyright notice and this permission notice shall be included in 208b22bf3fSmrg# all copies or substantial portions of the Software. 218b22bf3fSmrg# 228b22bf3fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 238b22bf3fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 248b22bf3fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 258b22bf3fSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 268b22bf3fSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 278b22bf3fSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 288b22bf3fSmrg# 298b22bf3fSmrg# Except as contained in this notice, the name of the X Consortium shall not 308b22bf3fSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 318b22bf3fSmrg# ings in this Software without prior written authorization from the X Consor- 328b22bf3fSmrg# tium. 338b22bf3fSmrg# 348b22bf3fSmrg# 358b22bf3fSmrg# FSF changes to this file are in the public domain. 368b22bf3fSmrg# 378b22bf3fSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38f126e068Smrg# 'make' implicit rules from creating a file called install from it 398b22bf3fSmrg# when there is no Makefile. 408b22bf3fSmrg# 418b22bf3fSmrg# This script is compatible with the BSD install script, but was written 428b22bf3fSmrg# from scratch. 438b22bf3fSmrg 44c74b14bdSmrgtab=' ' 458b22bf3fSmrgnl=' 468b22bf3fSmrg' 47c74b14bdSmrgIFS=" $tab$nl" 488b22bf3fSmrg 49c74b14bdSmrg# Set DOITPROG to "echo" to test this script. 508b22bf3fSmrg 5196a81b41Smrgdoit=${DOITPROG-} 52c74b14bdSmrgdoit_exec=${doit:-exec} 538b22bf3fSmrg 548b22bf3fSmrg# Put in absolute file names if you don't have them in your path; 558b22bf3fSmrg# or use environment vars. 568b22bf3fSmrg 5796a81b41Smrgchgrpprog=${CHGRPPROG-chgrp} 5896a81b41Smrgchmodprog=${CHMODPROG-chmod} 5996a81b41Smrgchownprog=${CHOWNPROG-chown} 6096a81b41Smrgcmpprog=${CMPPROG-cmp} 6196a81b41Smrgcpprog=${CPPROG-cp} 6296a81b41Smrgmkdirprog=${MKDIRPROG-mkdir} 6396a81b41Smrgmvprog=${MVPROG-mv} 6496a81b41Smrgrmprog=${RMPROG-rm} 6596a81b41Smrgstripprog=${STRIPPROG-strip} 6696a81b41Smrg 678b22bf3fSmrgposix_mkdir= 688b22bf3fSmrg 698b22bf3fSmrg# Desired mode of installed file. 708b22bf3fSmrgmode=0755 718b22bf3fSmrg 7296a81b41Smrgchgrpcmd= 738b22bf3fSmrgchmodcmd=$chmodprog 748b22bf3fSmrgchowncmd= 7596a81b41Smrgmvcmd=$mvprog 768b22bf3fSmrgrmcmd="$rmprog -f" 7796a81b41Smrgstripcmd= 7896a81b41Smrg 798b22bf3fSmrgsrc= 808b22bf3fSmrgdst= 818b22bf3fSmrgdir_arg= 8296a81b41Smrgdst_arg= 8396a81b41Smrg 8496a81b41Smrgcopy_on_change=false 85c74b14bdSmrgis_target_a_directory=possibly 868b22bf3fSmrg 8796a81b41Smrgusage="\ 8896a81b41SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 898b22bf3fSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 908b22bf3fSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 918b22bf3fSmrg or: $0 [OPTION]... -d DIRECTORIES... 928b22bf3fSmrg 938b22bf3fSmrgIn the 1st form, copy SRCFILE to DSTFILE. 948b22bf3fSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 958b22bf3fSmrgIn the 4th, create DIRECTORIES. 968b22bf3fSmrg 978b22bf3fSmrgOptions: 9896a81b41Smrg --help display this help and exit. 9996a81b41Smrg --version display version info and exit. 10096a81b41Smrg 10196a81b41Smrg -c (ignored) 10296a81b41Smrg -C install only if different (preserve the last data modification time) 10396a81b41Smrg -d create directories instead of installing files. 10496a81b41Smrg -g GROUP $chgrpprog installed files to GROUP. 10596a81b41Smrg -m MODE $chmodprog installed files to MODE. 10696a81b41Smrg -o USER $chownprog installed files to USER. 10796a81b41Smrg -s $stripprog installed files. 10896a81b41Smrg -t DIRECTORY install into DIRECTORY. 10996a81b41Smrg -T report an error if DSTFILE is a directory. 1108b22bf3fSmrg 1118b22bf3fSmrgEnvironment variables override the default commands: 11296a81b41Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11396a81b41Smrg RMPROG STRIPPROG 1148b22bf3fSmrg" 1158b22bf3fSmrg 1168b22bf3fSmrgwhile test $# -ne 0; do 1178b22bf3fSmrg case $1 in 11896a81b41Smrg -c) ;; 11996a81b41Smrg 12096a81b41Smrg -C) copy_on_change=true;; 1218b22bf3fSmrg 12296a81b41Smrg -d) dir_arg=true;; 1238b22bf3fSmrg 1248b22bf3fSmrg -g) chgrpcmd="$chgrpprog $2" 125c74b14bdSmrg shift;; 1268b22bf3fSmrg 1278b22bf3fSmrg --help) echo "$usage"; exit $?;; 1288b22bf3fSmrg 1298b22bf3fSmrg -m) mode=$2 130c74b14bdSmrg case $mode in 131c74b14bdSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132c74b14bdSmrg echo "$0: invalid mode: $mode" >&2 133c74b14bdSmrg exit 1;; 134c74b14bdSmrg esac 135c74b14bdSmrg shift;; 1368b22bf3fSmrg 1378b22bf3fSmrg -o) chowncmd="$chownprog $2" 138c74b14bdSmrg shift;; 1398b22bf3fSmrg 14096a81b41Smrg -s) stripcmd=$stripprog;; 1418b22bf3fSmrg 142c74b14bdSmrg -t) 143c74b14bdSmrg is_target_a_directory=always 144c74b14bdSmrg dst_arg=$2 145c74b14bdSmrg # Protect names problematic for 'test' and other utilities. 146c74b14bdSmrg case $dst_arg in 147c74b14bdSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148c74b14bdSmrg esac 149c74b14bdSmrg shift;; 1508b22bf3fSmrg 151c74b14bdSmrg -T) is_target_a_directory=never;; 1528b22bf3fSmrg 1538b22bf3fSmrg --version) echo "$0 $scriptversion"; exit $?;; 1548b22bf3fSmrg 155c74b14bdSmrg --) shift 156c74b14bdSmrg break;; 1578b22bf3fSmrg 158c74b14bdSmrg -*) echo "$0: invalid option: $1" >&2 159c74b14bdSmrg exit 1;; 1608b22bf3fSmrg 1618b22bf3fSmrg *) break;; 1628b22bf3fSmrg esac 16396a81b41Smrg shift 1648b22bf3fSmrgdone 1658b22bf3fSmrg 166c74b14bdSmrg# We allow the use of options -d and -T together, by making -d 167c74b14bdSmrg# take the precedence; this is for compatibility with GNU install. 168c74b14bdSmrg 169c74b14bdSmrgif test -n "$dir_arg"; then 170c74b14bdSmrg if test -n "$dst_arg"; then 171c74b14bdSmrg echo "$0: target directory not allowed when installing a directory." >&2 172c74b14bdSmrg exit 1 173c74b14bdSmrg fi 174c74b14bdSmrgfi 175c74b14bdSmrg 17696a81b41Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1778b22bf3fSmrg # When -d is used, all remaining arguments are directories to create. 1788b22bf3fSmrg # When -t is used, the destination is already specified. 1798b22bf3fSmrg # Otherwise, the last argument is the destination. Remove it from $@. 1808b22bf3fSmrg for arg 1818b22bf3fSmrg do 18296a81b41Smrg if test -n "$dst_arg"; then 1838b22bf3fSmrg # $@ is not empty: it contains at least $arg. 18496a81b41Smrg set fnord "$@" "$dst_arg" 1858b22bf3fSmrg shift # fnord 1868b22bf3fSmrg fi 1878b22bf3fSmrg shift # arg 18896a81b41Smrg dst_arg=$arg 189f126e068Smrg # Protect names problematic for 'test' and other utilities. 190f126e068Smrg case $dst_arg in 191f126e068Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192f126e068Smrg esac 1938b22bf3fSmrg done 1948b22bf3fSmrgfi 1958b22bf3fSmrg 1968b22bf3fSmrgif test $# -eq 0; then 1978b22bf3fSmrg if test -z "$dir_arg"; then 1988b22bf3fSmrg echo "$0: no input file specified." >&2 1998b22bf3fSmrg exit 1 2008b22bf3fSmrg fi 201f126e068Smrg # It's OK to call 'install-sh -d' without argument. 2028b22bf3fSmrg # This can happen when creating conditional directories. 2038b22bf3fSmrg exit 0 2048b22bf3fSmrgfi 2058b22bf3fSmrg 206c74b14bdSmrgif test -z "$dir_arg"; then 207c74b14bdSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208c74b14bdSmrg if test ! -d "$dst_arg"; then 209c74b14bdSmrg echo "$0: $dst_arg: Is not a directory." >&2 210c74b14bdSmrg exit 1 211c74b14bdSmrg fi 212c74b14bdSmrg fi 213c74b14bdSmrgfi 214c74b14bdSmrg 2158b22bf3fSmrgif test -z "$dir_arg"; then 216f126e068Smrg do_exit='(exit $ret); exit $ret' 217f126e068Smrg trap "ret=129; $do_exit" 1 218f126e068Smrg trap "ret=130; $do_exit" 2 219f126e068Smrg trap "ret=141; $do_exit" 13 220f126e068Smrg trap "ret=143; $do_exit" 15 2218b22bf3fSmrg 2228b22bf3fSmrg # Set umask so as not to create temps with too-generous modes. 2238b22bf3fSmrg # However, 'strip' requires both read and write access to temps. 2248b22bf3fSmrg case $mode in 2258b22bf3fSmrg # Optimize common cases. 2268b22bf3fSmrg *644) cp_umask=133;; 2278b22bf3fSmrg *755) cp_umask=22;; 2288b22bf3fSmrg 2298b22bf3fSmrg *[0-7]) 2308b22bf3fSmrg if test -z "$stripcmd"; then 231c74b14bdSmrg u_plus_rw= 2328b22bf3fSmrg else 233c74b14bdSmrg u_plus_rw='% 200' 2348b22bf3fSmrg fi 2358b22bf3fSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2368b22bf3fSmrg *) 2378b22bf3fSmrg if test -z "$stripcmd"; then 238c74b14bdSmrg u_plus_rw= 2398b22bf3fSmrg else 240c74b14bdSmrg u_plus_rw=,u+rw 2418b22bf3fSmrg fi 2428b22bf3fSmrg cp_umask=$mode$u_plus_rw;; 2438b22bf3fSmrg esac 2448b22bf3fSmrgfi 2458b22bf3fSmrg 2468b22bf3fSmrgfor src 2478b22bf3fSmrgdo 248f126e068Smrg # Protect names problematic for 'test' and other utilities. 2498b22bf3fSmrg case $src in 250f126e068Smrg -* | [=\(\)!]) src=./$src;; 2518b22bf3fSmrg esac 2528b22bf3fSmrg 2538b22bf3fSmrg if test -n "$dir_arg"; then 2548b22bf3fSmrg dst=$src 2558b22bf3fSmrg dstdir=$dst 2568b22bf3fSmrg test -d "$dstdir" 2578b22bf3fSmrg dstdir_status=$? 2588b22bf3fSmrg else 2598b22bf3fSmrg 2608b22bf3fSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2618b22bf3fSmrg # might cause directories to be created, which would be especially bad 2628b22bf3fSmrg # if $src (and thus $dsttmp) contains '*'. 2638b22bf3fSmrg if test ! -f "$src" && test ! -d "$src"; then 2648b22bf3fSmrg echo "$0: $src does not exist." >&2 2658b22bf3fSmrg exit 1 2668b22bf3fSmrg fi 2678b22bf3fSmrg 26896a81b41Smrg if test -z "$dst_arg"; then 2698b22bf3fSmrg echo "$0: no destination specified." >&2 2708b22bf3fSmrg exit 1 2718b22bf3fSmrg fi 27296a81b41Smrg dst=$dst_arg 2738b22bf3fSmrg 2749e1184feSmrg # If destination is a directory, append the input filename. 2758b22bf3fSmrg if test -d "$dst"; then 276c74b14bdSmrg if test "$is_target_a_directory" = never; then 277c74b14bdSmrg echo "$0: $dst_arg: Is a directory" >&2 278c74b14bdSmrg exit 1 2798b22bf3fSmrg fi 2808b22bf3fSmrg dstdir=$dst 2819e1184feSmrg dstbase=`basename "$src"` 2829e1184feSmrg case $dst in 2839e1184feSmrg */) dst=$dst$dstbase;; 2849e1184feSmrg *) dst=$dst/$dstbase;; 2859e1184feSmrg esac 2868b22bf3fSmrg dstdir_status=0 2878b22bf3fSmrg else 288c74b14bdSmrg dstdir=`dirname "$dst"` 2898b22bf3fSmrg test -d "$dstdir" 2908b22bf3fSmrg dstdir_status=$? 2918b22bf3fSmrg fi 2928b22bf3fSmrg fi 2938b22bf3fSmrg 2949e1184feSmrg case $dstdir in 2959e1184feSmrg */) dstdirslash=$dstdir;; 2969e1184feSmrg *) dstdirslash=$dstdir/;; 2979e1184feSmrg esac 2989e1184feSmrg 2998b22bf3fSmrg obsolete_mkdir_used=false 3008b22bf3fSmrg 3018b22bf3fSmrg if test $dstdir_status != 0; then 3028b22bf3fSmrg case $posix_mkdir in 3038b22bf3fSmrg '') 304c74b14bdSmrg # Create intermediate dirs using mode 755 as modified by the umask. 305c74b14bdSmrg # This is like FreeBSD 'install' as of 1997-10-28. 306c74b14bdSmrg umask=`umask` 307c74b14bdSmrg case $stripcmd.$umask in 308c74b14bdSmrg # Optimize common cases. 309c74b14bdSmrg *[2367][2367]) mkdir_umask=$umask;; 310c74b14bdSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 311c74b14bdSmrg 312c74b14bdSmrg *[0-7]) 313c74b14bdSmrg mkdir_umask=`expr $umask + 22 \ 314c74b14bdSmrg - $umask % 100 % 40 + $umask % 20 \ 315c74b14bdSmrg - $umask % 10 % 4 + $umask % 2 316c74b14bdSmrg `;; 317c74b14bdSmrg *) mkdir_umask=$umask,go-w;; 318c74b14bdSmrg esac 319c74b14bdSmrg 320c74b14bdSmrg # With -d, create the new directory with the user-specified mode. 321c74b14bdSmrg # Otherwise, rely on $mkdir_umask. 322c74b14bdSmrg if test -n "$dir_arg"; then 323c74b14bdSmrg mkdir_mode=-m$mode 324c74b14bdSmrg else 325c74b14bdSmrg mkdir_mode= 326c74b14bdSmrg fi 327c74b14bdSmrg 328c74b14bdSmrg posix_mkdir=false 329c74b14bdSmrg case $umask in 330c74b14bdSmrg *[123567][0-7][0-7]) 331c74b14bdSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 332c74b14bdSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333c74b14bdSmrg ;; 334c74b14bdSmrg *) 3359e1184feSmrg # Note that $RANDOM variable is not portable (e.g. dash); Use it 3369e1184feSmrg # here however when possible just to lower collision chance. 337c74b14bdSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 338c74b14bdSmrg 3399e1184feSmrg trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 3409e1184feSmrg 3419e1184feSmrg # Because "mkdir -p" follows existing symlinks and we likely work 3429e1184feSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 3439e1184feSmrg # directory is successfully created first before we actually test 3449e1184feSmrg # 'mkdir -p' feature. 345c74b14bdSmrg if (umask $mkdir_umask && 3469e1184feSmrg $mkdirprog $mkdir_mode "$tmpdir" && 3479e1184feSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 348c74b14bdSmrg then 349c74b14bdSmrg if test -z "$dir_arg" || { 350c74b14bdSmrg # Check for POSIX incompatibilities with -m. 351c74b14bdSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 352c74b14bdSmrg # other-writable bit of parent directory when it shouldn't. 353c74b14bdSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3549e1184feSmrg test_tmpdir="$tmpdir/a" 3559e1184feSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 356c74b14bdSmrg case $ls_ld_tmpdir in 357c74b14bdSmrg d????-?r-*) different_mode=700;; 358c74b14bdSmrg d????-?--*) different_mode=755;; 359c74b14bdSmrg *) false;; 360c74b14bdSmrg esac && 3619e1184feSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 3629e1184feSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 363c74b14bdSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 364c74b14bdSmrg } 365c74b14bdSmrg } 366c74b14bdSmrg then posix_mkdir=: 367c74b14bdSmrg fi 3689e1184feSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 369c74b14bdSmrg else 370c74b14bdSmrg # Remove any dirs left behind by ancient mkdir implementations. 3719e1184feSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 372c74b14bdSmrg fi 373c74b14bdSmrg trap '' 0;; 374c74b14bdSmrg esac;; 3758b22bf3fSmrg esac 3768b22bf3fSmrg 3778b22bf3fSmrg if 3788b22bf3fSmrg $posix_mkdir && ( 379c74b14bdSmrg umask $mkdir_umask && 380c74b14bdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3818b22bf3fSmrg ) 3828b22bf3fSmrg then : 3838b22bf3fSmrg else 3848b22bf3fSmrg 3858b22bf3fSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3868b22bf3fSmrg # or it failed possibly due to a race condition. Create the 3878b22bf3fSmrg # directory the slow way, step by step, checking for races as we go. 3888b22bf3fSmrg 3898b22bf3fSmrg case $dstdir in 390c74b14bdSmrg /*) prefix='/';; 391c74b14bdSmrg [-=\(\)!]*) prefix='./';; 392c74b14bdSmrg *) prefix='';; 3938b22bf3fSmrg esac 3948b22bf3fSmrg 3958b22bf3fSmrg oIFS=$IFS 3968b22bf3fSmrg IFS=/ 397c74b14bdSmrg set -f 3988b22bf3fSmrg set fnord $dstdir 3998b22bf3fSmrg shift 400c74b14bdSmrg set +f 4018b22bf3fSmrg IFS=$oIFS 4028b22bf3fSmrg 4038b22bf3fSmrg prefixes= 4048b22bf3fSmrg 4058b22bf3fSmrg for d 4068b22bf3fSmrg do 407c74b14bdSmrg test X"$d" = X && continue 408c74b14bdSmrg 409c74b14bdSmrg prefix=$prefix$d 410c74b14bdSmrg if test -d "$prefix"; then 411c74b14bdSmrg prefixes= 412c74b14bdSmrg else 413c74b14bdSmrg if $posix_mkdir; then 414c74b14bdSmrg (umask=$mkdir_umask && 415c74b14bdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416c74b14bdSmrg # Don't fail if two instances are running concurrently. 417c74b14bdSmrg test -d "$prefix" || exit 1 418c74b14bdSmrg else 419c74b14bdSmrg case $prefix in 420c74b14bdSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421c74b14bdSmrg *) qprefix=$prefix;; 422c74b14bdSmrg esac 423c74b14bdSmrg prefixes="$prefixes '$qprefix'" 424c74b14bdSmrg fi 425c74b14bdSmrg fi 426c74b14bdSmrg prefix=$prefix/ 4278b22bf3fSmrg done 4288b22bf3fSmrg 4298b22bf3fSmrg if test -n "$prefixes"; then 430c74b14bdSmrg # Don't fail if two instances are running concurrently. 431c74b14bdSmrg (umask $mkdir_umask && 432c74b14bdSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 433c74b14bdSmrg test -d "$dstdir" || exit 1 434c74b14bdSmrg obsolete_mkdir_used=true 4358b22bf3fSmrg fi 4368b22bf3fSmrg fi 4378b22bf3fSmrg fi 4388b22bf3fSmrg 4398b22bf3fSmrg if test -n "$dir_arg"; then 4408b22bf3fSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4418b22bf3fSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4428b22bf3fSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4438b22bf3fSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4448b22bf3fSmrg else 4458b22bf3fSmrg 4468b22bf3fSmrg # Make a couple of temp file names in the proper directory. 4479e1184feSmrg dsttmp=${dstdirslash}_inst.$$_ 4489e1184feSmrg rmtmp=${dstdirslash}_rm.$$_ 4498b22bf3fSmrg 4508b22bf3fSmrg # Trap to clean up those temp files at exit. 4518b22bf3fSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4528b22bf3fSmrg 4538b22bf3fSmrg # Copy the file name to the temp name. 4548b22bf3fSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4558b22bf3fSmrg 4568b22bf3fSmrg # and set any options; do chmod last to preserve setuid bits. 4578b22bf3fSmrg # 4588b22bf3fSmrg # If any of these fail, we abort the whole thing. If we want to 4598b22bf3fSmrg # ignore errors from any of these, just make sure not to ignore 4608b22bf3fSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4618b22bf3fSmrg # 46296a81b41Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 46396a81b41Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 46496a81b41Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 46596a81b41Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 46696a81b41Smrg 46796a81b41Smrg # If -C, don't bother to copy if it wouldn't change the file. 46896a81b41Smrg if $copy_on_change && 469c74b14bdSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 470c74b14bdSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 471c74b14bdSmrg set -f && 47296a81b41Smrg set X $old && old=:$2:$4:$5:$6 && 47396a81b41Smrg set X $new && new=:$2:$4:$5:$6 && 474c74b14bdSmrg set +f && 47596a81b41Smrg test "$old" = "$new" && 47696a81b41Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 47796a81b41Smrg then 47896a81b41Smrg rm -f "$dsttmp" 47996a81b41Smrg else 48096a81b41Smrg # Rename the file to the real destination. 48196a81b41Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 48296a81b41Smrg 48396a81b41Smrg # The rename failed, perhaps because mv can't rename something else 48496a81b41Smrg # to itself, or perhaps because mv is so ancient that it does not 48596a81b41Smrg # support -f. 48696a81b41Smrg { 487c74b14bdSmrg # Now remove or move aside any old file at destination location. 488c74b14bdSmrg # We try this two ways since rm can't unlink itself on some 489c74b14bdSmrg # systems and the destination file might be busy for other 490c74b14bdSmrg # reasons. In this case, the final cleanup might fail but the new 491c74b14bdSmrg # file should still install successfully. 492c74b14bdSmrg { 493c74b14bdSmrg test ! -f "$dst" || 494c74b14bdSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 495c74b14bdSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 496c74b14bdSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 497c74b14bdSmrg } || 498c74b14bdSmrg { echo "$0: cannot unlink or rename $dst" >&2 499c74b14bdSmrg (exit 1); exit 1 500c74b14bdSmrg } 501c74b14bdSmrg } && 502c74b14bdSmrg 503c74b14bdSmrg # Now rename the file to the real destination. 504c74b14bdSmrg $doit $mvcmd "$dsttmp" "$dst" 50596a81b41Smrg } 50696a81b41Smrg fi || exit 1 5078b22bf3fSmrg 5088b22bf3fSmrg trap '' 0 5098b22bf3fSmrg fi 5108b22bf3fSmrgdone 5118b22bf3fSmrg 5128b22bf3fSmrg# Local variables: 5139e1184feSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5148b22bf3fSmrg# time-stamp-start: "scriptversion=" 5158b22bf3fSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5169e1184feSmrg# time-stamp-time-zone: "UTC0" 51796a81b41Smrg# time-stamp-end: "; # UTC" 5188b22bf3fSmrg# End: 519