install-sh revision c74b14bd
18b22bf3fSmrg#!/bin/sh 28b22bf3fSmrg# install - install a program, script, or datafile 38b22bf3fSmrg 4c74b14bdSmrgscriptversion=2013-12-25.23; # 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 2748b22bf3fSmrg # If destination is a directory, append the input filename; won't work 2758b22bf3fSmrg # if double slashes aren't ignored. 2768b22bf3fSmrg if test -d "$dst"; then 277c74b14bdSmrg if test "$is_target_a_directory" = never; then 278c74b14bdSmrg echo "$0: $dst_arg: Is a directory" >&2 279c74b14bdSmrg exit 1 2808b22bf3fSmrg fi 2818b22bf3fSmrg dstdir=$dst 2828b22bf3fSmrg dst=$dstdir/`basename "$src"` 2838b22bf3fSmrg dstdir_status=0 2848b22bf3fSmrg else 285c74b14bdSmrg dstdir=`dirname "$dst"` 2868b22bf3fSmrg test -d "$dstdir" 2878b22bf3fSmrg dstdir_status=$? 2888b22bf3fSmrg fi 2898b22bf3fSmrg fi 2908b22bf3fSmrg 2918b22bf3fSmrg obsolete_mkdir_used=false 2928b22bf3fSmrg 2938b22bf3fSmrg if test $dstdir_status != 0; then 2948b22bf3fSmrg case $posix_mkdir in 2958b22bf3fSmrg '') 296c74b14bdSmrg # Create intermediate dirs using mode 755 as modified by the umask. 297c74b14bdSmrg # This is like FreeBSD 'install' as of 1997-10-28. 298c74b14bdSmrg umask=`umask` 299c74b14bdSmrg case $stripcmd.$umask in 300c74b14bdSmrg # Optimize common cases. 301c74b14bdSmrg *[2367][2367]) mkdir_umask=$umask;; 302c74b14bdSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303c74b14bdSmrg 304c74b14bdSmrg *[0-7]) 305c74b14bdSmrg mkdir_umask=`expr $umask + 22 \ 306c74b14bdSmrg - $umask % 100 % 40 + $umask % 20 \ 307c74b14bdSmrg - $umask % 10 % 4 + $umask % 2 308c74b14bdSmrg `;; 309c74b14bdSmrg *) mkdir_umask=$umask,go-w;; 310c74b14bdSmrg esac 311c74b14bdSmrg 312c74b14bdSmrg # With -d, create the new directory with the user-specified mode. 313c74b14bdSmrg # Otherwise, rely on $mkdir_umask. 314c74b14bdSmrg if test -n "$dir_arg"; then 315c74b14bdSmrg mkdir_mode=-m$mode 316c74b14bdSmrg else 317c74b14bdSmrg mkdir_mode= 318c74b14bdSmrg fi 319c74b14bdSmrg 320c74b14bdSmrg posix_mkdir=false 321c74b14bdSmrg case $umask in 322c74b14bdSmrg *[123567][0-7][0-7]) 323c74b14bdSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324c74b14bdSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325c74b14bdSmrg ;; 326c74b14bdSmrg *) 327c74b14bdSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328c74b14bdSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329c74b14bdSmrg 330c74b14bdSmrg if (umask $mkdir_umask && 331c74b14bdSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332c74b14bdSmrg then 333c74b14bdSmrg if test -z "$dir_arg" || { 334c74b14bdSmrg # Check for POSIX incompatibilities with -m. 335c74b14bdSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336c74b14bdSmrg # other-writable bit of parent directory when it shouldn't. 337c74b14bdSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338c74b14bdSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339c74b14bdSmrg case $ls_ld_tmpdir in 340c74b14bdSmrg d????-?r-*) different_mode=700;; 341c74b14bdSmrg d????-?--*) different_mode=755;; 342c74b14bdSmrg *) false;; 343c74b14bdSmrg esac && 344c74b14bdSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345c74b14bdSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346c74b14bdSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347c74b14bdSmrg } 348c74b14bdSmrg } 349c74b14bdSmrg then posix_mkdir=: 350c74b14bdSmrg fi 351c74b14bdSmrg rmdir "$tmpdir/d" "$tmpdir" 352c74b14bdSmrg else 353c74b14bdSmrg # Remove any dirs left behind by ancient mkdir implementations. 354c74b14bdSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355c74b14bdSmrg fi 356c74b14bdSmrg trap '' 0;; 357c74b14bdSmrg esac;; 3588b22bf3fSmrg esac 3598b22bf3fSmrg 3608b22bf3fSmrg if 3618b22bf3fSmrg $posix_mkdir && ( 362c74b14bdSmrg umask $mkdir_umask && 363c74b14bdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3648b22bf3fSmrg ) 3658b22bf3fSmrg then : 3668b22bf3fSmrg else 3678b22bf3fSmrg 3688b22bf3fSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3698b22bf3fSmrg # or it failed possibly due to a race condition. Create the 3708b22bf3fSmrg # directory the slow way, step by step, checking for races as we go. 3718b22bf3fSmrg 3728b22bf3fSmrg case $dstdir in 373c74b14bdSmrg /*) prefix='/';; 374c74b14bdSmrg [-=\(\)!]*) prefix='./';; 375c74b14bdSmrg *) prefix='';; 3768b22bf3fSmrg esac 3778b22bf3fSmrg 3788b22bf3fSmrg oIFS=$IFS 3798b22bf3fSmrg IFS=/ 380c74b14bdSmrg set -f 3818b22bf3fSmrg set fnord $dstdir 3828b22bf3fSmrg shift 383c74b14bdSmrg set +f 3848b22bf3fSmrg IFS=$oIFS 3858b22bf3fSmrg 3868b22bf3fSmrg prefixes= 3878b22bf3fSmrg 3888b22bf3fSmrg for d 3898b22bf3fSmrg do 390c74b14bdSmrg test X"$d" = X && continue 391c74b14bdSmrg 392c74b14bdSmrg prefix=$prefix$d 393c74b14bdSmrg if test -d "$prefix"; then 394c74b14bdSmrg prefixes= 395c74b14bdSmrg else 396c74b14bdSmrg if $posix_mkdir; then 397c74b14bdSmrg (umask=$mkdir_umask && 398c74b14bdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399c74b14bdSmrg # Don't fail if two instances are running concurrently. 400c74b14bdSmrg test -d "$prefix" || exit 1 401c74b14bdSmrg else 402c74b14bdSmrg case $prefix in 403c74b14bdSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404c74b14bdSmrg *) qprefix=$prefix;; 405c74b14bdSmrg esac 406c74b14bdSmrg prefixes="$prefixes '$qprefix'" 407c74b14bdSmrg fi 408c74b14bdSmrg fi 409c74b14bdSmrg prefix=$prefix/ 4108b22bf3fSmrg done 4118b22bf3fSmrg 4128b22bf3fSmrg if test -n "$prefixes"; then 413c74b14bdSmrg # Don't fail if two instances are running concurrently. 414c74b14bdSmrg (umask $mkdir_umask && 415c74b14bdSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 416c74b14bdSmrg test -d "$dstdir" || exit 1 417c74b14bdSmrg obsolete_mkdir_used=true 4188b22bf3fSmrg fi 4198b22bf3fSmrg fi 4208b22bf3fSmrg fi 4218b22bf3fSmrg 4228b22bf3fSmrg if test -n "$dir_arg"; then 4238b22bf3fSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4248b22bf3fSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4258b22bf3fSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4268b22bf3fSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4278b22bf3fSmrg else 4288b22bf3fSmrg 4298b22bf3fSmrg # Make a couple of temp file names in the proper directory. 4308b22bf3fSmrg dsttmp=$dstdir/_inst.$$_ 4318b22bf3fSmrg rmtmp=$dstdir/_rm.$$_ 4328b22bf3fSmrg 4338b22bf3fSmrg # Trap to clean up those temp files at exit. 4348b22bf3fSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4358b22bf3fSmrg 4368b22bf3fSmrg # Copy the file name to the temp name. 4378b22bf3fSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4388b22bf3fSmrg 4398b22bf3fSmrg # and set any options; do chmod last to preserve setuid bits. 4408b22bf3fSmrg # 4418b22bf3fSmrg # If any of these fail, we abort the whole thing. If we want to 4428b22bf3fSmrg # ignore errors from any of these, just make sure not to ignore 4438b22bf3fSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4448b22bf3fSmrg # 44596a81b41Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 44696a81b41Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 44796a81b41Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 44896a81b41Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 44996a81b41Smrg 45096a81b41Smrg # If -C, don't bother to copy if it wouldn't change the file. 45196a81b41Smrg if $copy_on_change && 452c74b14bdSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453c74b14bdSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454c74b14bdSmrg set -f && 45596a81b41Smrg set X $old && old=:$2:$4:$5:$6 && 45696a81b41Smrg set X $new && new=:$2:$4:$5:$6 && 457c74b14bdSmrg set +f && 45896a81b41Smrg test "$old" = "$new" && 45996a81b41Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 46096a81b41Smrg then 46196a81b41Smrg rm -f "$dsttmp" 46296a81b41Smrg else 46396a81b41Smrg # Rename the file to the real destination. 46496a81b41Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 46596a81b41Smrg 46696a81b41Smrg # The rename failed, perhaps because mv can't rename something else 46796a81b41Smrg # to itself, or perhaps because mv is so ancient that it does not 46896a81b41Smrg # support -f. 46996a81b41Smrg { 470c74b14bdSmrg # Now remove or move aside any old file at destination location. 471c74b14bdSmrg # We try this two ways since rm can't unlink itself on some 472c74b14bdSmrg # systems and the destination file might be busy for other 473c74b14bdSmrg # reasons. In this case, the final cleanup might fail but the new 474c74b14bdSmrg # file should still install successfully. 475c74b14bdSmrg { 476c74b14bdSmrg test ! -f "$dst" || 477c74b14bdSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 478c74b14bdSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479c74b14bdSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480c74b14bdSmrg } || 481c74b14bdSmrg { echo "$0: cannot unlink or rename $dst" >&2 482c74b14bdSmrg (exit 1); exit 1 483c74b14bdSmrg } 484c74b14bdSmrg } && 485c74b14bdSmrg 486c74b14bdSmrg # Now rename the file to the real destination. 487c74b14bdSmrg $doit $mvcmd "$dsttmp" "$dst" 48896a81b41Smrg } 48996a81b41Smrg fi || exit 1 4908b22bf3fSmrg 4918b22bf3fSmrg trap '' 0 4928b22bf3fSmrg fi 4938b22bf3fSmrgdone 4948b22bf3fSmrg 4958b22bf3fSmrg# Local variables: 4968b22bf3fSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 4978b22bf3fSmrg# time-stamp-start: "scriptversion=" 4988b22bf3fSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 49996a81b41Smrg# time-stamp-time-zone: "UTC" 50096a81b41Smrg# time-stamp-end: "; # UTC" 5018b22bf3fSmrg# End: 502