install-sh revision 585aa3f7
1fdb3d228Smrg#!/bin/sh 2fdb3d228Smrg# install - install a program, script, or datafile 39b41ff1aSmrg 4585aa3f7Smrgscriptversion=2013-12-25.23; # UTC 59b41ff1aSmrg 6fdb3d228Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7fdb3d228Smrg# later released in X11R6 (xc/config/util/install.sh) with the 8fdb3d228Smrg# following copyright and license. 9fdb3d228Smrg# 10fdb3d228Smrg# Copyright (C) 1994 X Consortium 11fdb3d228Smrg# 12fdb3d228Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13fdb3d228Smrg# of this software and associated documentation files (the "Software"), to 14fdb3d228Smrg# deal in the Software without restriction, including without limitation the 15fdb3d228Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16fdb3d228Smrg# sell copies of the Software, and to permit persons to whom the Software is 17fdb3d228Smrg# furnished to do so, subject to the following conditions: 18fdb3d228Smrg# 19fdb3d228Smrg# The above copyright notice and this permission notice shall be included in 20fdb3d228Smrg# all copies or substantial portions of the Software. 21fdb3d228Smrg# 22fdb3d228Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23fdb3d228Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24fdb3d228Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25fdb3d228Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26fdb3d228Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27fdb3d228Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28fdb3d228Smrg# 29fdb3d228Smrg# Except as contained in this notice, the name of the X Consortium shall not 30fdb3d228Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 31fdb3d228Smrg# ings in this Software without prior written authorization from the X Consor- 32fdb3d228Smrg# tium. 33fdb3d228Smrg# 34fdb3d228Smrg# 35fdb3d228Smrg# FSF changes to this file are in the public domain. 36fdb3d228Smrg# 37fdb3d228Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38585aa3f7Smrg# 'make' implicit rules from creating a file called install from it 39fdb3d228Smrg# when there is no Makefile. 40fdb3d228Smrg# 41fdb3d228Smrg# This script is compatible with the BSD install script, but was written 429b41ff1aSmrg# from scratch. 43fdb3d228Smrg 44585aa3f7Smrgtab=' ' 459b41ff1aSmrgnl=' 469b41ff1aSmrg' 47585aa3f7SmrgIFS=" $tab$nl" 48fdb3d228Smrg 49585aa3f7Smrg# Set DOITPROG to "echo" to test this script. 50fdb3d228Smrg 519b41ff1aSmrgdoit=${DOITPROG-} 52585aa3f7Smrgdoit_exec=${doit:-exec} 53fdb3d228Smrg 549b41ff1aSmrg# Put in absolute file names if you don't have them in your path; 559b41ff1aSmrg# or use environment vars. 569b41ff1aSmrg 579b41ff1aSmrgchgrpprog=${CHGRPPROG-chgrp} 589b41ff1aSmrgchmodprog=${CHMODPROG-chmod} 599b41ff1aSmrgchownprog=${CHOWNPROG-chown} 609b41ff1aSmrgcmpprog=${CMPPROG-cmp} 619b41ff1aSmrgcpprog=${CPPROG-cp} 629b41ff1aSmrgmkdirprog=${MKDIRPROG-mkdir} 639b41ff1aSmrgmvprog=${MVPROG-mv} 649b41ff1aSmrgrmprog=${RMPROG-rm} 659b41ff1aSmrgstripprog=${STRIPPROG-strip} 669b41ff1aSmrg 679b41ff1aSmrgposix_mkdir= 689b41ff1aSmrg 699b41ff1aSmrg# Desired mode of installed file. 709b41ff1aSmrgmode=0755 719b41ff1aSmrg 729b41ff1aSmrgchgrpcmd= 739b41ff1aSmrgchmodcmd=$chmodprog 749b41ff1aSmrgchowncmd= 759b41ff1aSmrgmvcmd=$mvprog 769b41ff1aSmrgrmcmd="$rmprog -f" 779b41ff1aSmrgstripcmd= 78fdb3d228Smrg 799b41ff1aSmrgsrc= 809b41ff1aSmrgdst= 819b41ff1aSmrgdir_arg= 829b41ff1aSmrgdst_arg= 83fdb3d228Smrg 849b41ff1aSmrgcopy_on_change=false 85585aa3f7Smrgis_target_a_directory=possibly 86fdb3d228Smrg 879b41ff1aSmrgusage="\ 889b41ff1aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 899b41ff1aSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 909b41ff1aSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 919b41ff1aSmrg or: $0 [OPTION]... -d DIRECTORIES... 92fdb3d228Smrg 939b41ff1aSmrgIn the 1st form, copy SRCFILE to DSTFILE. 949b41ff1aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 959b41ff1aSmrgIn the 4th, create DIRECTORIES. 96fdb3d228Smrg 979b41ff1aSmrgOptions: 989b41ff1aSmrg --help display this help and exit. 999b41ff1aSmrg --version display version info and exit. 100fdb3d228Smrg 1019b41ff1aSmrg -c (ignored) 1029b41ff1aSmrg -C install only if different (preserve the last data modification time) 1039b41ff1aSmrg -d create directories instead of installing files. 1049b41ff1aSmrg -g GROUP $chgrpprog installed files to GROUP. 1059b41ff1aSmrg -m MODE $chmodprog installed files to MODE. 1069b41ff1aSmrg -o USER $chownprog installed files to USER. 1079b41ff1aSmrg -s $stripprog installed files. 1089b41ff1aSmrg -t DIRECTORY install into DIRECTORY. 1099b41ff1aSmrg -T report an error if DSTFILE is a directory. 110fdb3d228Smrg 1119b41ff1aSmrgEnvironment variables override the default commands: 1129b41ff1aSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1139b41ff1aSmrg RMPROG STRIPPROG 1149b41ff1aSmrg" 115fdb3d228Smrg 1169b41ff1aSmrgwhile test $# -ne 0; do 1179b41ff1aSmrg case $1 in 1189b41ff1aSmrg -c) ;; 119fdb3d228Smrg 1209b41ff1aSmrg -C) copy_on_change=true;; 121fdb3d228Smrg 1229b41ff1aSmrg -d) dir_arg=true;; 123fdb3d228Smrg 1249b41ff1aSmrg -g) chgrpcmd="$chgrpprog $2" 125585aa3f7Smrg shift;; 126fdb3d228Smrg 1279b41ff1aSmrg --help) echo "$usage"; exit $?;; 128fdb3d228Smrg 1299b41ff1aSmrg -m) mode=$2 130585aa3f7Smrg case $mode in 131585aa3f7Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132585aa3f7Smrg echo "$0: invalid mode: $mode" >&2 133585aa3f7Smrg exit 1;; 134585aa3f7Smrg esac 135585aa3f7Smrg shift;; 136fdb3d228Smrg 1379b41ff1aSmrg -o) chowncmd="$chownprog $2" 138585aa3f7Smrg shift;; 139fdb3d228Smrg 1409b41ff1aSmrg -s) stripcmd=$stripprog;; 141fdb3d228Smrg 142585aa3f7Smrg -t) 143585aa3f7Smrg is_target_a_directory=always 144585aa3f7Smrg dst_arg=$2 145585aa3f7Smrg # Protect names problematic for 'test' and other utilities. 146585aa3f7Smrg case $dst_arg in 147585aa3f7Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148585aa3f7Smrg esac 149585aa3f7Smrg shift;; 150fdb3d228Smrg 151585aa3f7Smrg -T) is_target_a_directory=never;; 152fdb3d228Smrg 1539b41ff1aSmrg --version) echo "$0 $scriptversion"; exit $?;; 154fdb3d228Smrg 155585aa3f7Smrg --) shift 156585aa3f7Smrg break;; 157fdb3d228Smrg 158585aa3f7Smrg -*) echo "$0: invalid option: $1" >&2 159585aa3f7Smrg exit 1;; 160fdb3d228Smrg 1619b41ff1aSmrg *) break;; 1629b41ff1aSmrg esac 1639b41ff1aSmrg shift 1649b41ff1aSmrgdone 165fdb3d228Smrg 166585aa3f7Smrg# We allow the use of options -d and -T together, by making -d 167585aa3f7Smrg# take the precedence; this is for compatibility with GNU install. 168585aa3f7Smrg 169585aa3f7Smrgif test -n "$dir_arg"; then 170585aa3f7Smrg if test -n "$dst_arg"; then 171585aa3f7Smrg echo "$0: target directory not allowed when installing a directory." >&2 172585aa3f7Smrg exit 1 173585aa3f7Smrg fi 174585aa3f7Smrgfi 175585aa3f7Smrg 1769b41ff1aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1779b41ff1aSmrg # When -d is used, all remaining arguments are directories to create. 1789b41ff1aSmrg # When -t is used, the destination is already specified. 1799b41ff1aSmrg # Otherwise, the last argument is the destination. Remove it from $@. 1809b41ff1aSmrg for arg 1819b41ff1aSmrg do 1829b41ff1aSmrg if test -n "$dst_arg"; then 1839b41ff1aSmrg # $@ is not empty: it contains at least $arg. 1849b41ff1aSmrg set fnord "$@" "$dst_arg" 1859b41ff1aSmrg shift # fnord 1869b41ff1aSmrg fi 1879b41ff1aSmrg shift # arg 1889b41ff1aSmrg dst_arg=$arg 189585aa3f7Smrg # Protect names problematic for 'test' and other utilities. 1907d575c90Smrg case $dst_arg in 1917d575c90Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1927d575c90Smrg esac 1939b41ff1aSmrg done 1949b41ff1aSmrgfi 195fdb3d228Smrg 1969b41ff1aSmrgif test $# -eq 0; then 1979b41ff1aSmrg if test -z "$dir_arg"; then 1989b41ff1aSmrg echo "$0: no input file specified." >&2 1999b41ff1aSmrg exit 1 2009b41ff1aSmrg fi 201585aa3f7Smrg # It's OK to call 'install-sh -d' without argument. 2029b41ff1aSmrg # This can happen when creating conditional directories. 2039b41ff1aSmrg exit 0 2049b41ff1aSmrgfi 205fdb3d228Smrg 206585aa3f7Smrgif test -z "$dir_arg"; then 207585aa3f7Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208585aa3f7Smrg if test ! -d "$dst_arg"; then 209585aa3f7Smrg echo "$0: $dst_arg: Is not a directory." >&2 210585aa3f7Smrg exit 1 211585aa3f7Smrg fi 212585aa3f7Smrg fi 213585aa3f7Smrgfi 214585aa3f7Smrg 2159b41ff1aSmrgif test -z "$dir_arg"; then 2167d575c90Smrg do_exit='(exit $ret); exit $ret' 2177d575c90Smrg trap "ret=129; $do_exit" 1 2187d575c90Smrg trap "ret=130; $do_exit" 2 2197d575c90Smrg trap "ret=141; $do_exit" 13 2207d575c90Smrg trap "ret=143; $do_exit" 15 2219b41ff1aSmrg 2229b41ff1aSmrg # Set umask so as not to create temps with too-generous modes. 2239b41ff1aSmrg # However, 'strip' requires both read and write access to temps. 2249b41ff1aSmrg case $mode in 2259b41ff1aSmrg # Optimize common cases. 2269b41ff1aSmrg *644) cp_umask=133;; 2279b41ff1aSmrg *755) cp_umask=22;; 2289b41ff1aSmrg 2299b41ff1aSmrg *[0-7]) 2309b41ff1aSmrg if test -z "$stripcmd"; then 231585aa3f7Smrg u_plus_rw= 2329b41ff1aSmrg else 233585aa3f7Smrg u_plus_rw='% 200' 2349b41ff1aSmrg fi 2359b41ff1aSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2369b41ff1aSmrg *) 2379b41ff1aSmrg if test -z "$stripcmd"; then 238585aa3f7Smrg u_plus_rw= 2399b41ff1aSmrg else 240585aa3f7Smrg u_plus_rw=,u+rw 2419b41ff1aSmrg fi 2429b41ff1aSmrg cp_umask=$mode$u_plus_rw;; 2439b41ff1aSmrg esac 2449b41ff1aSmrgfi 245fdb3d228Smrg 2469b41ff1aSmrgfor src 2479b41ff1aSmrgdo 248585aa3f7Smrg # Protect names problematic for 'test' and other utilities. 2499b41ff1aSmrg case $src in 2507d575c90Smrg -* | [=\(\)!]) src=./$src;; 2519b41ff1aSmrg esac 2529b41ff1aSmrg 2539b41ff1aSmrg if test -n "$dir_arg"; then 2549b41ff1aSmrg dst=$src 2559b41ff1aSmrg dstdir=$dst 2569b41ff1aSmrg test -d "$dstdir" 2579b41ff1aSmrg dstdir_status=$? 2589b41ff1aSmrg else 2599b41ff1aSmrg 2609b41ff1aSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2619b41ff1aSmrg # might cause directories to be created, which would be especially bad 2629b41ff1aSmrg # if $src (and thus $dsttmp) contains '*'. 2639b41ff1aSmrg if test ! -f "$src" && test ! -d "$src"; then 2649b41ff1aSmrg echo "$0: $src does not exist." >&2 2659b41ff1aSmrg exit 1 2669b41ff1aSmrg fi 2679b41ff1aSmrg 2689b41ff1aSmrg if test -z "$dst_arg"; then 2699b41ff1aSmrg echo "$0: no destination specified." >&2 2709b41ff1aSmrg exit 1 2719b41ff1aSmrg fi 2729b41ff1aSmrg dst=$dst_arg 273fdb3d228Smrg 2749b41ff1aSmrg # If destination is a directory, append the input filename; won't work 2759b41ff1aSmrg # if double slashes aren't ignored. 2769b41ff1aSmrg if test -d "$dst"; then 277585aa3f7Smrg if test "$is_target_a_directory" = never; then 278585aa3f7Smrg echo "$0: $dst_arg: Is a directory" >&2 279585aa3f7Smrg exit 1 2809b41ff1aSmrg fi 2819b41ff1aSmrg dstdir=$dst 2829b41ff1aSmrg dst=$dstdir/`basename "$src"` 2839b41ff1aSmrg dstdir_status=0 2849b41ff1aSmrg else 285585aa3f7Smrg dstdir=`dirname "$dst"` 2869b41ff1aSmrg test -d "$dstdir" 2879b41ff1aSmrg dstdir_status=$? 2889b41ff1aSmrg fi 2899b41ff1aSmrg fi 2909b41ff1aSmrg 2919b41ff1aSmrg obsolete_mkdir_used=false 2929b41ff1aSmrg 2939b41ff1aSmrg if test $dstdir_status != 0; then 2949b41ff1aSmrg case $posix_mkdir in 2959b41ff1aSmrg '') 296585aa3f7Smrg # Create intermediate dirs using mode 755 as modified by the umask. 297585aa3f7Smrg # This is like FreeBSD 'install' as of 1997-10-28. 298585aa3f7Smrg umask=`umask` 299585aa3f7Smrg case $stripcmd.$umask in 300585aa3f7Smrg # Optimize common cases. 301585aa3f7Smrg *[2367][2367]) mkdir_umask=$umask;; 302585aa3f7Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303585aa3f7Smrg 304585aa3f7Smrg *[0-7]) 305585aa3f7Smrg mkdir_umask=`expr $umask + 22 \ 306585aa3f7Smrg - $umask % 100 % 40 + $umask % 20 \ 307585aa3f7Smrg - $umask % 10 % 4 + $umask % 2 308585aa3f7Smrg `;; 309585aa3f7Smrg *) mkdir_umask=$umask,go-w;; 310585aa3f7Smrg esac 311585aa3f7Smrg 312585aa3f7Smrg # With -d, create the new directory with the user-specified mode. 313585aa3f7Smrg # Otherwise, rely on $mkdir_umask. 314585aa3f7Smrg if test -n "$dir_arg"; then 315585aa3f7Smrg mkdir_mode=-m$mode 316585aa3f7Smrg else 317585aa3f7Smrg mkdir_mode= 318585aa3f7Smrg fi 319585aa3f7Smrg 320585aa3f7Smrg posix_mkdir=false 321585aa3f7Smrg case $umask in 322585aa3f7Smrg *[123567][0-7][0-7]) 323585aa3f7Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324585aa3f7Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325585aa3f7Smrg ;; 326585aa3f7Smrg *) 327585aa3f7Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328585aa3f7Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329585aa3f7Smrg 330585aa3f7Smrg if (umask $mkdir_umask && 331585aa3f7Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332585aa3f7Smrg then 333585aa3f7Smrg if test -z "$dir_arg" || { 334585aa3f7Smrg # Check for POSIX incompatibilities with -m. 335585aa3f7Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336585aa3f7Smrg # other-writable bit of parent directory when it shouldn't. 337585aa3f7Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338585aa3f7Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339585aa3f7Smrg case $ls_ld_tmpdir in 340585aa3f7Smrg d????-?r-*) different_mode=700;; 341585aa3f7Smrg d????-?--*) different_mode=755;; 342585aa3f7Smrg *) false;; 343585aa3f7Smrg esac && 344585aa3f7Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345585aa3f7Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346585aa3f7Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347585aa3f7Smrg } 348585aa3f7Smrg } 349585aa3f7Smrg then posix_mkdir=: 350585aa3f7Smrg fi 351585aa3f7Smrg rmdir "$tmpdir/d" "$tmpdir" 352585aa3f7Smrg else 353585aa3f7Smrg # Remove any dirs left behind by ancient mkdir implementations. 354585aa3f7Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355585aa3f7Smrg fi 356585aa3f7Smrg trap '' 0;; 357585aa3f7Smrg esac;; 3589b41ff1aSmrg esac 359fdb3d228Smrg 3609b41ff1aSmrg if 3619b41ff1aSmrg $posix_mkdir && ( 362585aa3f7Smrg umask $mkdir_umask && 363585aa3f7Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3649b41ff1aSmrg ) 3659b41ff1aSmrg then : 3669b41ff1aSmrg else 3679b41ff1aSmrg 3689b41ff1aSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3699b41ff1aSmrg # or it failed possibly due to a race condition. Create the 3709b41ff1aSmrg # directory the slow way, step by step, checking for races as we go. 3719b41ff1aSmrg 3729b41ff1aSmrg case $dstdir in 373585aa3f7Smrg /*) prefix='/';; 374585aa3f7Smrg [-=\(\)!]*) prefix='./';; 375585aa3f7Smrg *) prefix='';; 3769b41ff1aSmrg esac 3779b41ff1aSmrg 3789b41ff1aSmrg oIFS=$IFS 3799b41ff1aSmrg IFS=/ 380585aa3f7Smrg set -f 3819b41ff1aSmrg set fnord $dstdir 3829b41ff1aSmrg shift 383585aa3f7Smrg set +f 3849b41ff1aSmrg IFS=$oIFS 3859b41ff1aSmrg 3869b41ff1aSmrg prefixes= 3879b41ff1aSmrg 3889b41ff1aSmrg for d 3899b41ff1aSmrg do 390585aa3f7Smrg test X"$d" = X && continue 391585aa3f7Smrg 392585aa3f7Smrg prefix=$prefix$d 393585aa3f7Smrg if test -d "$prefix"; then 394585aa3f7Smrg prefixes= 395585aa3f7Smrg else 396585aa3f7Smrg if $posix_mkdir; then 397585aa3f7Smrg (umask=$mkdir_umask && 398585aa3f7Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399585aa3f7Smrg # Don't fail if two instances are running concurrently. 400585aa3f7Smrg test -d "$prefix" || exit 1 401585aa3f7Smrg else 402585aa3f7Smrg case $prefix in 403585aa3f7Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404585aa3f7Smrg *) qprefix=$prefix;; 405585aa3f7Smrg esac 406585aa3f7Smrg prefixes="$prefixes '$qprefix'" 407585aa3f7Smrg fi 408585aa3f7Smrg fi 409585aa3f7Smrg prefix=$prefix/ 4109b41ff1aSmrg done 4119b41ff1aSmrg 4129b41ff1aSmrg if test -n "$prefixes"; then 413585aa3f7Smrg # Don't fail if two instances are running concurrently. 414585aa3f7Smrg (umask $mkdir_umask && 415585aa3f7Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 416585aa3f7Smrg test -d "$dstdir" || exit 1 417585aa3f7Smrg obsolete_mkdir_used=true 4189b41ff1aSmrg fi 4199b41ff1aSmrg fi 4209b41ff1aSmrg fi 4219b41ff1aSmrg 4229b41ff1aSmrg if test -n "$dir_arg"; then 4239b41ff1aSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4249b41ff1aSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4259b41ff1aSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4269b41ff1aSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4279b41ff1aSmrg else 4289b41ff1aSmrg 4299b41ff1aSmrg # Make a couple of temp file names in the proper directory. 4309b41ff1aSmrg dsttmp=$dstdir/_inst.$$_ 4319b41ff1aSmrg rmtmp=$dstdir/_rm.$$_ 4329b41ff1aSmrg 4339b41ff1aSmrg # Trap to clean up those temp files at exit. 4349b41ff1aSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4359b41ff1aSmrg 4369b41ff1aSmrg # Copy the file name to the temp name. 4379b41ff1aSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4389b41ff1aSmrg 4399b41ff1aSmrg # and set any options; do chmod last to preserve setuid bits. 4409b41ff1aSmrg # 4419b41ff1aSmrg # If any of these fail, we abort the whole thing. If we want to 4429b41ff1aSmrg # ignore errors from any of these, just make sure not to ignore 4439b41ff1aSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4449b41ff1aSmrg # 4459b41ff1aSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4469b41ff1aSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4479b41ff1aSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4489b41ff1aSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4499b41ff1aSmrg 4509b41ff1aSmrg # If -C, don't bother to copy if it wouldn't change the file. 4519b41ff1aSmrg if $copy_on_change && 452585aa3f7Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453585aa3f7Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454585aa3f7Smrg set -f && 4559b41ff1aSmrg set X $old && old=:$2:$4:$5:$6 && 4569b41ff1aSmrg set X $new && new=:$2:$4:$5:$6 && 457585aa3f7Smrg set +f && 4589b41ff1aSmrg test "$old" = "$new" && 4599b41ff1aSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4609b41ff1aSmrg then 4619b41ff1aSmrg rm -f "$dsttmp" 4629b41ff1aSmrg else 4639b41ff1aSmrg # Rename the file to the real destination. 4649b41ff1aSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4659b41ff1aSmrg 4669b41ff1aSmrg # The rename failed, perhaps because mv can't rename something else 4679b41ff1aSmrg # to itself, or perhaps because mv is so ancient that it does not 4689b41ff1aSmrg # support -f. 4699b41ff1aSmrg { 470585aa3f7Smrg # Now remove or move aside any old file at destination location. 471585aa3f7Smrg # We try this two ways since rm can't unlink itself on some 472585aa3f7Smrg # systems and the destination file might be busy for other 473585aa3f7Smrg # reasons. In this case, the final cleanup might fail but the new 474585aa3f7Smrg # file should still install successfully. 475585aa3f7Smrg { 476585aa3f7Smrg test ! -f "$dst" || 477585aa3f7Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 478585aa3f7Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479585aa3f7Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480585aa3f7Smrg } || 481585aa3f7Smrg { echo "$0: cannot unlink or rename $dst" >&2 482585aa3f7Smrg (exit 1); exit 1 483585aa3f7Smrg } 484585aa3f7Smrg } && 485585aa3f7Smrg 486585aa3f7Smrg # Now rename the file to the real destination. 487585aa3f7Smrg $doit $mvcmd "$dsttmp" "$dst" 4889b41ff1aSmrg } 4899b41ff1aSmrg fi || exit 1 4909b41ff1aSmrg 4919b41ff1aSmrg trap '' 0 4929b41ff1aSmrg fi 4939b41ff1aSmrgdone 494fdb3d228Smrg 4959b41ff1aSmrg# Local variables: 4969b41ff1aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 4979b41ff1aSmrg# time-stamp-start: "scriptversion=" 4989b41ff1aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 4999b41ff1aSmrg# time-stamp-time-zone: "UTC" 5009b41ff1aSmrg# time-stamp-end: "; # UTC" 5019b41ff1aSmrg# End: 502