install-sh revision 1a9c160a
13eed67faSmbalmer#!/bin/sh 23eed67faSmbalmer# install - install a program, script, or datafile 33eed67faSmbalmer 41a9c160aSmrgscriptversion=2018-03-11.20; # UTC 53eed67faSmbalmer 63eed67faSmbalmer# This originates from X11R5 (mit/util/scripts/install.sh), which was 73eed67faSmbalmer# later released in X11R6 (xc/config/util/install.sh) with the 83eed67faSmbalmer# following copyright and license. 93eed67faSmbalmer# 103eed67faSmbalmer# Copyright (C) 1994 X Consortium 113eed67faSmbalmer# 123eed67faSmbalmer# Permission is hereby granted, free of charge, to any person obtaining a copy 133eed67faSmbalmer# of this software and associated documentation files (the "Software"), to 143eed67faSmbalmer# deal in the Software without restriction, including without limitation the 153eed67faSmbalmer# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 163eed67faSmbalmer# sell copies of the Software, and to permit persons to whom the Software is 173eed67faSmbalmer# furnished to do so, subject to the following conditions: 183eed67faSmbalmer# 193eed67faSmbalmer# The above copyright notice and this permission notice shall be included in 203eed67faSmbalmer# all copies or substantial portions of the Software. 213eed67faSmbalmer# 223eed67faSmbalmer# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 233eed67faSmbalmer# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 243eed67faSmbalmer# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 253eed67faSmbalmer# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 263eed67faSmbalmer# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 273eed67faSmbalmer# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 283eed67faSmbalmer# 293eed67faSmbalmer# Except as contained in this notice, the name of the X Consortium shall not 303eed67faSmbalmer# be used in advertising or otherwise to promote the sale, use or other deal- 313eed67faSmbalmer# ings in this Software without prior written authorization from the X Consor- 323eed67faSmbalmer# tium. 333eed67faSmbalmer# 343eed67faSmbalmer# 353eed67faSmbalmer# FSF changes to this file are in the public domain. 363eed67faSmbalmer# 373eed67faSmbalmer# Calling this script install-sh is preferred over install.sh, to prevent 381a9c160aSmrg# 'make' implicit rules from creating a file called install from it 393eed67faSmbalmer# when there is no Makefile. 403eed67faSmbalmer# 413eed67faSmbalmer# This script is compatible with the BSD install script, but was written 42dc407927Smrg# from scratch. 43dc407927Smrg 441a9c160aSmrgtab=' ' 45dc407927Smrgnl=' 46dc407927Smrg' 471a9c160aSmrgIFS=" $tab$nl" 483eed67faSmbalmer 491a9c160aSmrg# Set DOITPROG to "echo" to test this script. 503eed67faSmbalmer 51dc407927Smrgdoit=${DOITPROG-} 521a9c160aSmrgdoit_exec=${doit:-exec} 533eed67faSmbalmer 54dc407927Smrg# Put in absolute file names if you don't have them in your path; 55dc407927Smrg# or use environment vars. 56dc407927Smrg 57dc407927Smrgchgrpprog=${CHGRPPROG-chgrp} 58dc407927Smrgchmodprog=${CHMODPROG-chmod} 59dc407927Smrgchownprog=${CHOWNPROG-chown} 60dc407927Smrgcmpprog=${CMPPROG-cmp} 61dc407927Smrgcpprog=${CPPROG-cp} 62dc407927Smrgmkdirprog=${MKDIRPROG-mkdir} 63dc407927Smrgmvprog=${MVPROG-mv} 64dc407927Smrgrmprog=${RMPROG-rm} 65dc407927Smrgstripprog=${STRIPPROG-strip} 66dc407927Smrg 67dc407927Smrgposix_mkdir= 68dc407927Smrg 69dc407927Smrg# Desired mode of installed file. 70dc407927Smrgmode=0755 713eed67faSmbalmer 723eed67faSmbalmerchgrpcmd= 73dc407927Smrgchmodcmd=$chmodprog 74dc407927Smrgchowncmd= 75dc407927Smrgmvcmd=$mvprog 763eed67faSmbalmerrmcmd="$rmprog -f" 77dc407927Smrgstripcmd= 78dc407927Smrg 793eed67faSmbalmersrc= 803eed67faSmbalmerdst= 813eed67faSmbalmerdir_arg= 82dc407927Smrgdst_arg= 83dc407927Smrg 84dc407927Smrgcopy_on_change=false 851a9c160aSmrgis_target_a_directory=possibly 863eed67faSmbalmer 87dc407927Smrgusage="\ 88dc407927SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 893eed67faSmbalmer or: $0 [OPTION]... SRCFILES... DIRECTORY 903eed67faSmbalmer or: $0 [OPTION]... -t DIRECTORY SRCFILES... 913eed67faSmbalmer or: $0 [OPTION]... -d DIRECTORIES... 923eed67faSmbalmer 933eed67faSmbalmerIn the 1st form, copy SRCFILE to DSTFILE. 943eed67faSmbalmerIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 953eed67faSmbalmerIn the 4th, create DIRECTORIES. 963eed67faSmbalmer 973eed67faSmbalmerOptions: 98dc407927Smrg --help display this help and exit. 99dc407927Smrg --version display version info and exit. 100dc407927Smrg 101dc407927Smrg -c (ignored) 102dc407927Smrg -C install only if different (preserve the last data modification time) 103dc407927Smrg -d create directories instead of installing files. 104dc407927Smrg -g GROUP $chgrpprog installed files to GROUP. 105dc407927Smrg -m MODE $chmodprog installed files to MODE. 106dc407927Smrg -o USER $chownprog installed files to USER. 107dc407927Smrg -s $stripprog installed files. 108dc407927Smrg -t DIRECTORY install into DIRECTORY. 109dc407927Smrg -T report an error if DSTFILE is a directory. 1103eed67faSmbalmer 1113eed67faSmbalmerEnvironment variables override the default commands: 112dc407927Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113dc407927Smrg RMPROG STRIPPROG 1143eed67faSmbalmer" 1153eed67faSmbalmer 116dc407927Smrgwhile test $# -ne 0; do 1173eed67faSmbalmer case $1 in 118dc407927Smrg -c) ;; 119dc407927Smrg 120dc407927Smrg -C) copy_on_change=true;; 1213eed67faSmbalmer 122dc407927Smrg -d) dir_arg=true;; 1233eed67faSmbalmer 1243eed67faSmbalmer -g) chgrpcmd="$chgrpprog $2" 1251a9c160aSmrg shift;; 1263eed67faSmbalmer 1273eed67faSmbalmer --help) echo "$usage"; exit $?;; 1283eed67faSmbalmer 129dc407927Smrg -m) mode=$2 1301a9c160aSmrg case $mode in 1311a9c160aSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1321a9c160aSmrg echo "$0: invalid mode: $mode" >&2 1331a9c160aSmrg exit 1;; 1341a9c160aSmrg esac 1351a9c160aSmrg shift;; 1363eed67faSmbalmer 1373eed67faSmbalmer -o) chowncmd="$chownprog $2" 1381a9c160aSmrg shift;; 1393eed67faSmbalmer 140dc407927Smrg -s) stripcmd=$stripprog;; 1413eed67faSmbalmer 1421a9c160aSmrg -t) 1431a9c160aSmrg is_target_a_directory=always 1441a9c160aSmrg dst_arg=$2 1451a9c160aSmrg # Protect names problematic for 'test' and other utilities. 1461a9c160aSmrg case $dst_arg in 1471a9c160aSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1481a9c160aSmrg esac 1491a9c160aSmrg shift;; 1503eed67faSmbalmer 1511a9c160aSmrg -T) is_target_a_directory=never;; 1523eed67faSmbalmer 1533eed67faSmbalmer --version) echo "$0 $scriptversion"; exit $?;; 1543eed67faSmbalmer 1551a9c160aSmrg --) shift 1561a9c160aSmrg break;; 157dc407927Smrg 1581a9c160aSmrg -*) echo "$0: invalid option: $1" >&2 1591a9c160aSmrg exit 1;; 160dc407927Smrg 161dc407927Smrg *) break;; 1623eed67faSmbalmer esac 163dc407927Smrg shift 1643eed67faSmbalmerdone 1653eed67faSmbalmer 1661a9c160aSmrg# We allow the use of options -d and -T together, by making -d 1671a9c160aSmrg# take the precedence; this is for compatibility with GNU install. 1681a9c160aSmrg 1691a9c160aSmrgif test -n "$dir_arg"; then 1701a9c160aSmrg if test -n "$dst_arg"; then 1711a9c160aSmrg echo "$0: target directory not allowed when installing a directory." >&2 1721a9c160aSmrg exit 1 1731a9c160aSmrg fi 1741a9c160aSmrgfi 1751a9c160aSmrg 176dc407927Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177dc407927Smrg # When -d is used, all remaining arguments are directories to create. 178dc407927Smrg # When -t is used, the destination is already specified. 179dc407927Smrg # Otherwise, the last argument is the destination. Remove it from $@. 180dc407927Smrg for arg 181dc407927Smrg do 182dc407927Smrg if test -n "$dst_arg"; then 183dc407927Smrg # $@ is not empty: it contains at least $arg. 184dc407927Smrg set fnord "$@" "$dst_arg" 185dc407927Smrg shift # fnord 186dc407927Smrg fi 187dc407927Smrg shift # arg 188dc407927Smrg dst_arg=$arg 1891a9c160aSmrg # Protect names problematic for 'test' and other utilities. 19075cbef56Smrg case $dst_arg in 19175cbef56Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 19275cbef56Smrg esac 193dc407927Smrg done 194dc407927Smrgfi 195dc407927Smrg 196dc407927Smrgif test $# -eq 0; then 1973eed67faSmbalmer if test -z "$dir_arg"; then 1983eed67faSmbalmer echo "$0: no input file specified." >&2 1993eed67faSmbalmer exit 1 2003eed67faSmbalmer fi 2011a9c160aSmrg # It's OK to call 'install-sh -d' without argument. 2023eed67faSmbalmer # This can happen when creating conditional directories. 2033eed67faSmbalmer exit 0 2043eed67faSmbalmerfi 2053eed67faSmbalmer 2061a9c160aSmrgif test -z "$dir_arg"; then 2071a9c160aSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 2081a9c160aSmrg if test ! -d "$dst_arg"; then 2091a9c160aSmrg echo "$0: $dst_arg: Is not a directory." >&2 2101a9c160aSmrg exit 1 2111a9c160aSmrg fi 2121a9c160aSmrg fi 2131a9c160aSmrgfi 2141a9c160aSmrg 215dc407927Smrgif test -z "$dir_arg"; then 21675cbef56Smrg do_exit='(exit $ret); exit $ret' 21775cbef56Smrg trap "ret=129; $do_exit" 1 21875cbef56Smrg trap "ret=130; $do_exit" 2 21975cbef56Smrg trap "ret=141; $do_exit" 13 22075cbef56Smrg trap "ret=143; $do_exit" 15 221dc407927Smrg 222dc407927Smrg # Set umask so as not to create temps with too-generous modes. 223dc407927Smrg # However, 'strip' requires both read and write access to temps. 224dc407927Smrg case $mode in 225dc407927Smrg # Optimize common cases. 226dc407927Smrg *644) cp_umask=133;; 227dc407927Smrg *755) cp_umask=22;; 228dc407927Smrg 229dc407927Smrg *[0-7]) 230dc407927Smrg if test -z "$stripcmd"; then 2311a9c160aSmrg u_plus_rw= 232dc407927Smrg else 2331a9c160aSmrg u_plus_rw='% 200' 234dc407927Smrg fi 235dc407927Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236dc407927Smrg *) 237dc407927Smrg if test -z "$stripcmd"; then 2381a9c160aSmrg u_plus_rw= 239dc407927Smrg else 2401a9c160aSmrg u_plus_rw=,u+rw 241dc407927Smrg fi 242dc407927Smrg cp_umask=$mode$u_plus_rw;; 243dc407927Smrg esac 244dc407927Smrgfi 245dc407927Smrg 2463eed67faSmbalmerfor src 2473eed67faSmbalmerdo 2481a9c160aSmrg # Protect names problematic for 'test' and other utilities. 2493eed67faSmbalmer case $src in 25075cbef56Smrg -* | [=\(\)!]) src=./$src;; 2513eed67faSmbalmer esac 2523eed67faSmbalmer 2533eed67faSmbalmer if test -n "$dir_arg"; then 2543eed67faSmbalmer dst=$src 255dc407927Smrg dstdir=$dst 256dc407927Smrg test -d "$dstdir" 257dc407927Smrg dstdir_status=$? 2583eed67faSmbalmer else 259dc407927Smrg 2603eed67faSmbalmer # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2613eed67faSmbalmer # might cause directories to be created, which would be especially bad 2623eed67faSmbalmer # if $src (and thus $dsttmp) contains '*'. 2633eed67faSmbalmer if test ! -f "$src" && test ! -d "$src"; then 2643eed67faSmbalmer echo "$0: $src does not exist." >&2 2653eed67faSmbalmer exit 1 2663eed67faSmbalmer fi 2673eed67faSmbalmer 268dc407927Smrg if test -z "$dst_arg"; then 2693eed67faSmbalmer echo "$0: no destination specified." >&2 2703eed67faSmbalmer exit 1 2713eed67faSmbalmer fi 272dc407927Smrg dst=$dst_arg 2733eed67faSmbalmer 2741a9c160aSmrg # If destination is a directory, append the input filename. 2753eed67faSmbalmer if test -d "$dst"; then 2761a9c160aSmrg if test "$is_target_a_directory" = never; then 2771a9c160aSmrg echo "$0: $dst_arg: Is a directory" >&2 2781a9c160aSmrg exit 1 2793eed67faSmbalmer fi 280dc407927Smrg dstdir=$dst 2811a9c160aSmrg dstbase=`basename "$src"` 2821a9c160aSmrg case $dst in 2831a9c160aSmrg */) dst=$dst$dstbase;; 2841a9c160aSmrg *) dst=$dst/$dstbase;; 2851a9c160aSmrg esac 286dc407927Smrg dstdir_status=0 287dc407927Smrg else 2881a9c160aSmrg dstdir=`dirname "$dst"` 289dc407927Smrg test -d "$dstdir" 290dc407927Smrg dstdir_status=$? 2913eed67faSmbalmer fi 2923eed67faSmbalmer fi 2933eed67faSmbalmer 2941a9c160aSmrg case $dstdir in 2951a9c160aSmrg */) dstdirslash=$dstdir;; 2961a9c160aSmrg *) dstdirslash=$dstdir/;; 2971a9c160aSmrg esac 2981a9c160aSmrg 299dc407927Smrg obsolete_mkdir_used=false 300dc407927Smrg 301dc407927Smrg if test $dstdir_status != 0; then 302dc407927Smrg case $posix_mkdir in 303dc407927Smrg '') 3041a9c160aSmrg # Create intermediate dirs using mode 755 as modified by the umask. 3051a9c160aSmrg # This is like FreeBSD 'install' as of 1997-10-28. 3061a9c160aSmrg umask=`umask` 3071a9c160aSmrg case $stripcmd.$umask in 3081a9c160aSmrg # Optimize common cases. 3091a9c160aSmrg *[2367][2367]) mkdir_umask=$umask;; 3101a9c160aSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3111a9c160aSmrg 3121a9c160aSmrg *[0-7]) 3131a9c160aSmrg mkdir_umask=`expr $umask + 22 \ 3141a9c160aSmrg - $umask % 100 % 40 + $umask % 20 \ 3151a9c160aSmrg - $umask % 10 % 4 + $umask % 2 3161a9c160aSmrg `;; 3171a9c160aSmrg *) mkdir_umask=$umask,go-w;; 3181a9c160aSmrg esac 3191a9c160aSmrg 3201a9c160aSmrg # With -d, create the new directory with the user-specified mode. 3211a9c160aSmrg # Otherwise, rely on $mkdir_umask. 3221a9c160aSmrg if test -n "$dir_arg"; then 3231a9c160aSmrg mkdir_mode=-m$mode 3241a9c160aSmrg else 3251a9c160aSmrg mkdir_mode= 3261a9c160aSmrg fi 3271a9c160aSmrg 3281a9c160aSmrg posix_mkdir=false 3291a9c160aSmrg case $umask in 3301a9c160aSmrg *[123567][0-7][0-7]) 3311a9c160aSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3321a9c160aSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3331a9c160aSmrg ;; 3341a9c160aSmrg *) 3351a9c160aSmrg # Note that $RANDOM variable is not portable (e.g. dash); Use it 3361a9c160aSmrg # here however when possible just to lower collision chance. 3371a9c160aSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3381a9c160aSmrg 3391a9c160aSmrg trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 3401a9c160aSmrg 3411a9c160aSmrg # Because "mkdir -p" follows existing symlinks and we likely work 3421a9c160aSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 3431a9c160aSmrg # directory is successfully created first before we actually test 3441a9c160aSmrg # 'mkdir -p' feature. 3451a9c160aSmrg if (umask $mkdir_umask && 3461a9c160aSmrg $mkdirprog $mkdir_mode "$tmpdir" && 3471a9c160aSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 3481a9c160aSmrg then 3491a9c160aSmrg if test -z "$dir_arg" || { 3501a9c160aSmrg # Check for POSIX incompatibilities with -m. 3511a9c160aSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3521a9c160aSmrg # other-writable bit of parent directory when it shouldn't. 3531a9c160aSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3541a9c160aSmrg test_tmpdir="$tmpdir/a" 3551a9c160aSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 3561a9c160aSmrg case $ls_ld_tmpdir in 3571a9c160aSmrg d????-?r-*) different_mode=700;; 3581a9c160aSmrg d????-?--*) different_mode=755;; 3591a9c160aSmrg *) false;; 3601a9c160aSmrg esac && 3611a9c160aSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 3621a9c160aSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 3631a9c160aSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3641a9c160aSmrg } 3651a9c160aSmrg } 3661a9c160aSmrg then posix_mkdir=: 3671a9c160aSmrg fi 3681a9c160aSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3691a9c160aSmrg else 3701a9c160aSmrg # Remove any dirs left behind by ancient mkdir implementations. 3711a9c160aSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3721a9c160aSmrg fi 3731a9c160aSmrg trap '' 0;; 3741a9c160aSmrg esac;; 375dc407927Smrg esac 3763eed67faSmbalmer 377dc407927Smrg if 378dc407927Smrg $posix_mkdir && ( 3791a9c160aSmrg umask $mkdir_umask && 3801a9c160aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 381dc407927Smrg ) 382dc407927Smrg then : 383dc407927Smrg else 3843eed67faSmbalmer 385dc407927Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 386dc407927Smrg # or it failed possibly due to a race condition. Create the 387dc407927Smrg # directory the slow way, step by step, checking for races as we go. 3883eed67faSmbalmer 389dc407927Smrg case $dstdir in 3901a9c160aSmrg /*) prefix='/';; 3911a9c160aSmrg [-=\(\)!]*) prefix='./';; 3921a9c160aSmrg *) prefix='';; 393dc407927Smrg esac 3943eed67faSmbalmer 395dc407927Smrg oIFS=$IFS 396dc407927Smrg IFS=/ 3971a9c160aSmrg set -f 398dc407927Smrg set fnord $dstdir 3993eed67faSmbalmer shift 4001a9c160aSmrg set +f 401dc407927Smrg IFS=$oIFS 402dc407927Smrg 403dc407927Smrg prefixes= 404dc407927Smrg 405dc407927Smrg for d 406dc407927Smrg do 4071a9c160aSmrg test X"$d" = X && continue 4081a9c160aSmrg 4091a9c160aSmrg prefix=$prefix$d 4101a9c160aSmrg if test -d "$prefix"; then 4111a9c160aSmrg prefixes= 4121a9c160aSmrg else 4131a9c160aSmrg if $posix_mkdir; then 4141a9c160aSmrg (umask=$mkdir_umask && 4151a9c160aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4161a9c160aSmrg # Don't fail if two instances are running concurrently. 4171a9c160aSmrg test -d "$prefix" || exit 1 4181a9c160aSmrg else 4191a9c160aSmrg case $prefix in 4201a9c160aSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4211a9c160aSmrg *) qprefix=$prefix;; 4221a9c160aSmrg esac 4231a9c160aSmrg prefixes="$prefixes '$qprefix'" 4241a9c160aSmrg fi 4251a9c160aSmrg fi 4261a9c160aSmrg prefix=$prefix/ 427dc407927Smrg done 428dc407927Smrg 429dc407927Smrg if test -n "$prefixes"; then 4301a9c160aSmrg # Don't fail if two instances are running concurrently. 4311a9c160aSmrg (umask $mkdir_umask && 4321a9c160aSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 4331a9c160aSmrg test -d "$dstdir" || exit 1 4341a9c160aSmrg obsolete_mkdir_used=true 4353eed67faSmbalmer fi 436dc407927Smrg fi 4373eed67faSmbalmer fi 4383eed67faSmbalmer 4393eed67faSmbalmer if test -n "$dir_arg"; then 440dc407927Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441dc407927Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442dc407927Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443dc407927Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4443eed67faSmbalmer else 4453eed67faSmbalmer 4463eed67faSmbalmer # Make a couple of temp file names in the proper directory. 4471a9c160aSmrg dsttmp=${dstdirslash}_inst.$$_ 4481a9c160aSmrg rmtmp=${dstdirslash}_rm.$$_ 4493eed67faSmbalmer 4503eed67faSmbalmer # Trap to clean up those temp files at exit. 4513eed67faSmbalmer trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4523eed67faSmbalmer 4533eed67faSmbalmer # Copy the file name to the temp name. 454dc407927Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4553eed67faSmbalmer 4563eed67faSmbalmer # and set any options; do chmod last to preserve setuid bits. 4573eed67faSmbalmer # 4583eed67faSmbalmer # If any of these fail, we abort the whole thing. If we want to 4593eed67faSmbalmer # ignore errors from any of these, just make sure not to ignore 4603eed67faSmbalmer # errors from the above "$doit $cpprog $src $dsttmp" command. 4613eed67faSmbalmer # 462dc407927Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 463dc407927Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 464dc407927Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 465dc407927Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466dc407927Smrg 467dc407927Smrg # If -C, don't bother to copy if it wouldn't change the file. 468dc407927Smrg if $copy_on_change && 4691a9c160aSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4701a9c160aSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4711a9c160aSmrg set -f && 472dc407927Smrg set X $old && old=:$2:$4:$5:$6 && 473dc407927Smrg set X $new && new=:$2:$4:$5:$6 && 4741a9c160aSmrg set +f && 475dc407927Smrg test "$old" = "$new" && 476dc407927Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 477dc407927Smrg then 478dc407927Smrg rm -f "$dsttmp" 479dc407927Smrg else 480dc407927Smrg # Rename the file to the real destination. 481dc407927Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 482dc407927Smrg 483dc407927Smrg # The rename failed, perhaps because mv can't rename something else 484dc407927Smrg # to itself, or perhaps because mv is so ancient that it does not 485dc407927Smrg # support -f. 486dc407927Smrg { 4871a9c160aSmrg # Now remove or move aside any old file at destination location. 4881a9c160aSmrg # We try this two ways since rm can't unlink itself on some 4891a9c160aSmrg # systems and the destination file might be busy for other 4901a9c160aSmrg # reasons. In this case, the final cleanup might fail but the new 4911a9c160aSmrg # file should still install successfully. 4921a9c160aSmrg { 4931a9c160aSmrg test ! -f "$dst" || 4941a9c160aSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 4951a9c160aSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 4961a9c160aSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 4971a9c160aSmrg } || 4981a9c160aSmrg { echo "$0: cannot unlink or rename $dst" >&2 4991a9c160aSmrg (exit 1); exit 1 5001a9c160aSmrg } 5011a9c160aSmrg } && 5021a9c160aSmrg 5031a9c160aSmrg # Now rename the file to the real destination. 5041a9c160aSmrg $doit $mvcmd "$dsttmp" "$dst" 505dc407927Smrg } 506dc407927Smrg fi || exit 1 507dc407927Smrg 508dc407927Smrg trap '' 0 509dc407927Smrg fi 5103eed67faSmbalmerdone 5113eed67faSmbalmer 5123eed67faSmbalmer# Local variables: 5131a9c160aSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5143eed67faSmbalmer# time-stamp-start: "scriptversion=" 5153eed67faSmbalmer# time-stamp-format: "%:y-%02m-%02d.%02H" 5161a9c160aSmrg# time-stamp-time-zone: "UTC0" 517dc407927Smrg# time-stamp-end: "; # UTC" 5183eed67faSmbalmer# End: 519