install-sh revision 5977a007
18108eb18Smrg#!/bin/sh 28108eb18Smrg# install - install a program, script, or datafile 31a650d1eSmrg 45977a007Smrgscriptversion=2011-01-19.21; # UTC 51a650d1eSmrg 68108eb18Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 78108eb18Smrg# later released in X11R6 (xc/config/util/install.sh) with the 88108eb18Smrg# following copyright and license. 98108eb18Smrg# 108108eb18Smrg# Copyright (C) 1994 X Consortium 118108eb18Smrg# 128108eb18Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 138108eb18Smrg# of this software and associated documentation files (the "Software"), to 148108eb18Smrg# deal in the Software without restriction, including without limitation the 158108eb18Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 168108eb18Smrg# sell copies of the Software, and to permit persons to whom the Software is 178108eb18Smrg# furnished to do so, subject to the following conditions: 188108eb18Smrg# 198108eb18Smrg# The above copyright notice and this permission notice shall be included in 208108eb18Smrg# all copies or substantial portions of the Software. 218108eb18Smrg# 228108eb18Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 238108eb18Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 248108eb18Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 258108eb18Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 268108eb18Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 278108eb18Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 288108eb18Smrg# 298108eb18Smrg# Except as contained in this notice, the name of the X Consortium shall not 308108eb18Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 318108eb18Smrg# ings in this Software without prior written authorization from the X Consor- 328108eb18Smrg# tium. 338108eb18Smrg# 348108eb18Smrg# 358108eb18Smrg# FSF changes to this file are in the public domain. 368108eb18Smrg# 378108eb18Smrg# Calling this script install-sh is preferred over install.sh, to prevent 388108eb18Smrg# `make' implicit rules from creating a file called install from it 398108eb18Smrg# when there is no Makefile. 408108eb18Smrg# 418108eb18Smrg# This script is compatible with the BSD install script, but was written 421a650d1eSmrg# from scratch. 438108eb18Smrg 441a650d1eSmrgnl=' 451a650d1eSmrg' 461a650d1eSmrgIFS=" "" $nl" 478108eb18Smrg 488108eb18Smrg# set DOITPROG to echo to test this script 498108eb18Smrg 508108eb18Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 511a650d1eSmrgdoit=${DOITPROG-} 521a650d1eSmrgif test -z "$doit"; then 531a650d1eSmrg doit_exec=exec 548108eb18Smrgelse 551a650d1eSmrg doit_exec=$doit 568108eb18Smrgfi 578108eb18Smrg 581a650d1eSmrg# Put in absolute file names if you don't have them in your path; 591a650d1eSmrg# or use environment vars. 601a650d1eSmrg 611a650d1eSmrgchgrpprog=${CHGRPPROG-chgrp} 621a650d1eSmrgchmodprog=${CHMODPROG-chmod} 631a650d1eSmrgchownprog=${CHOWNPROG-chown} 641a650d1eSmrgcmpprog=${CMPPROG-cmp} 651a650d1eSmrgcpprog=${CPPROG-cp} 661a650d1eSmrgmkdirprog=${MKDIRPROG-mkdir} 671a650d1eSmrgmvprog=${MVPROG-mv} 681a650d1eSmrgrmprog=${RMPROG-rm} 691a650d1eSmrgstripprog=${STRIPPROG-strip} 701a650d1eSmrg 711a650d1eSmrgposix_glob='?' 721a650d1eSmrginitialize_posix_glob=' 731a650d1eSmrg test "$posix_glob" != "?" || { 741a650d1eSmrg if (set -f) 2>/dev/null; then 751a650d1eSmrg posix_glob= 761a650d1eSmrg else 771a650d1eSmrg posix_glob=: 781a650d1eSmrg fi 791a650d1eSmrg } 801a650d1eSmrg' 811a650d1eSmrg 821a650d1eSmrgposix_mkdir= 831a650d1eSmrg 841a650d1eSmrg# Desired mode of installed file. 851a650d1eSmrgmode=0755 861a650d1eSmrg 871a650d1eSmrgchgrpcmd= 881a650d1eSmrgchmodcmd=$chmodprog 891a650d1eSmrgchowncmd= 901a650d1eSmrgmvcmd=$mvprog 911a650d1eSmrgrmcmd="$rmprog -f" 921a650d1eSmrgstripcmd= 938108eb18Smrg 941a650d1eSmrgsrc= 951a650d1eSmrgdst= 961a650d1eSmrgdir_arg= 971a650d1eSmrgdst_arg= 988108eb18Smrg 991a650d1eSmrgcopy_on_change=false 1001a650d1eSmrgno_target_directory= 1018108eb18Smrg 1021a650d1eSmrgusage="\ 1031a650d1eSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 1041a650d1eSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 1051a650d1eSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 1061a650d1eSmrg or: $0 [OPTION]... -d DIRECTORIES... 1078108eb18Smrg 1081a650d1eSmrgIn the 1st form, copy SRCFILE to DSTFILE. 1091a650d1eSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1101a650d1eSmrgIn the 4th, create DIRECTORIES. 1118108eb18Smrg 1121a650d1eSmrgOptions: 1131a650d1eSmrg --help display this help and exit. 1141a650d1eSmrg --version display version info and exit. 1158108eb18Smrg 1161a650d1eSmrg -c (ignored) 1171a650d1eSmrg -C install only if different (preserve the last data modification time) 1181a650d1eSmrg -d create directories instead of installing files. 1191a650d1eSmrg -g GROUP $chgrpprog installed files to GROUP. 1201a650d1eSmrg -m MODE $chmodprog installed files to MODE. 1211a650d1eSmrg -o USER $chownprog installed files to USER. 1221a650d1eSmrg -s $stripprog installed files. 1231a650d1eSmrg -t DIRECTORY install into DIRECTORY. 1241a650d1eSmrg -T report an error if DSTFILE is a directory. 1258108eb18Smrg 1261a650d1eSmrgEnvironment variables override the default commands: 1271a650d1eSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1281a650d1eSmrg RMPROG STRIPPROG 1291a650d1eSmrg" 1308108eb18Smrg 1311a650d1eSmrgwhile test $# -ne 0; do 1321a650d1eSmrg case $1 in 1331a650d1eSmrg -c) ;; 1348108eb18Smrg 1351a650d1eSmrg -C) copy_on_change=true;; 1368108eb18Smrg 1371a650d1eSmrg -d) dir_arg=true;; 1388108eb18Smrg 1391a650d1eSmrg -g) chgrpcmd="$chgrpprog $2" 1401a650d1eSmrg shift;; 1418108eb18Smrg 1421a650d1eSmrg --help) echo "$usage"; exit $?;; 1438108eb18Smrg 1441a650d1eSmrg -m) mode=$2 1451a650d1eSmrg case $mode in 1461a650d1eSmrg *' '* | *' '* | *' 1471a650d1eSmrg'* | *'*'* | *'?'* | *'['*) 1481a650d1eSmrg echo "$0: invalid mode: $mode" >&2 1491a650d1eSmrg exit 1;; 1501a650d1eSmrg esac 1511a650d1eSmrg shift;; 1528108eb18Smrg 1531a650d1eSmrg -o) chowncmd="$chownprog $2" 1541a650d1eSmrg shift;; 1558108eb18Smrg 1561a650d1eSmrg -s) stripcmd=$stripprog;; 1578108eb18Smrg 1581a650d1eSmrg -t) dst_arg=$2 1595977a007Smrg # Protect names problematic for `test' and other utilities. 1605977a007Smrg case $dst_arg in 1615977a007Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1625977a007Smrg esac 1631a650d1eSmrg shift;; 1648108eb18Smrg 1651a650d1eSmrg -T) no_target_directory=true;; 1668108eb18Smrg 1671a650d1eSmrg --version) echo "$0 $scriptversion"; exit $?;; 1688108eb18Smrg 1691a650d1eSmrg --) shift 1701a650d1eSmrg break;; 1718108eb18Smrg 1721a650d1eSmrg -*) echo "$0: invalid option: $1" >&2 1731a650d1eSmrg exit 1;; 1748108eb18Smrg 1751a650d1eSmrg *) break;; 1761a650d1eSmrg esac 1771a650d1eSmrg shift 1781a650d1eSmrgdone 1798108eb18Smrg 1801a650d1eSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1811a650d1eSmrg # When -d is used, all remaining arguments are directories to create. 1821a650d1eSmrg # When -t is used, the destination is already specified. 1831a650d1eSmrg # Otherwise, the last argument is the destination. Remove it from $@. 1841a650d1eSmrg for arg 1851a650d1eSmrg do 1861a650d1eSmrg if test -n "$dst_arg"; then 1871a650d1eSmrg # $@ is not empty: it contains at least $arg. 1881a650d1eSmrg set fnord "$@" "$dst_arg" 1891a650d1eSmrg shift # fnord 1901a650d1eSmrg fi 1911a650d1eSmrg shift # arg 1921a650d1eSmrg dst_arg=$arg 1935977a007Smrg # Protect names problematic for `test' and other utilities. 1945977a007Smrg case $dst_arg in 1955977a007Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1965977a007Smrg esac 1971a650d1eSmrg done 1981a650d1eSmrgfi 1998108eb18Smrg 2001a650d1eSmrgif test $# -eq 0; then 2011a650d1eSmrg if test -z "$dir_arg"; then 2021a650d1eSmrg echo "$0: no input file specified." >&2 2031a650d1eSmrg exit 1 2041a650d1eSmrg fi 2051a650d1eSmrg # It's OK to call `install-sh -d' without argument. 2061a650d1eSmrg # This can happen when creating conditional directories. 2071a650d1eSmrg exit 0 2081a650d1eSmrgfi 2098108eb18Smrg 2101a650d1eSmrgif test -z "$dir_arg"; then 2115977a007Smrg do_exit='(exit $ret); exit $ret' 2125977a007Smrg trap "ret=129; $do_exit" 1 2135977a007Smrg trap "ret=130; $do_exit" 2 2145977a007Smrg trap "ret=141; $do_exit" 13 2155977a007Smrg trap "ret=143; $do_exit" 15 2161a650d1eSmrg 2171a650d1eSmrg # Set umask so as not to create temps with too-generous modes. 2181a650d1eSmrg # However, 'strip' requires both read and write access to temps. 2191a650d1eSmrg case $mode in 2201a650d1eSmrg # Optimize common cases. 2211a650d1eSmrg *644) cp_umask=133;; 2221a650d1eSmrg *755) cp_umask=22;; 2231a650d1eSmrg 2241a650d1eSmrg *[0-7]) 2251a650d1eSmrg if test -z "$stripcmd"; then 2261a650d1eSmrg u_plus_rw= 2271a650d1eSmrg else 2281a650d1eSmrg u_plus_rw='% 200' 2291a650d1eSmrg fi 2301a650d1eSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2311a650d1eSmrg *) 2321a650d1eSmrg if test -z "$stripcmd"; then 2331a650d1eSmrg u_plus_rw= 2341a650d1eSmrg else 2351a650d1eSmrg u_plus_rw=,u+rw 2361a650d1eSmrg fi 2371a650d1eSmrg cp_umask=$mode$u_plus_rw;; 2381a650d1eSmrg esac 2391a650d1eSmrgfi 2408108eb18Smrg 2411a650d1eSmrgfor src 2421a650d1eSmrgdo 2435977a007Smrg # Protect names problematic for `test' and other utilities. 2441a650d1eSmrg case $src in 2455977a007Smrg -* | [=\(\)!]) src=./$src;; 2461a650d1eSmrg esac 2471a650d1eSmrg 2481a650d1eSmrg if test -n "$dir_arg"; then 2491a650d1eSmrg dst=$src 2501a650d1eSmrg dstdir=$dst 2511a650d1eSmrg test -d "$dstdir" 2521a650d1eSmrg dstdir_status=$? 2531a650d1eSmrg else 2541a650d1eSmrg 2551a650d1eSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2561a650d1eSmrg # might cause directories to be created, which would be especially bad 2571a650d1eSmrg # if $src (and thus $dsttmp) contains '*'. 2581a650d1eSmrg if test ! -f "$src" && test ! -d "$src"; then 2591a650d1eSmrg echo "$0: $src does not exist." >&2 2601a650d1eSmrg exit 1 2611a650d1eSmrg fi 2621a650d1eSmrg 2631a650d1eSmrg if test -z "$dst_arg"; then 2641a650d1eSmrg echo "$0: no destination specified." >&2 2651a650d1eSmrg exit 1 2661a650d1eSmrg fi 2671a650d1eSmrg dst=$dst_arg 2688108eb18Smrg 2691a650d1eSmrg # If destination is a directory, append the input filename; won't work 2701a650d1eSmrg # if double slashes aren't ignored. 2711a650d1eSmrg if test -d "$dst"; then 2721a650d1eSmrg if test -n "$no_target_directory"; then 2731a650d1eSmrg echo "$0: $dst_arg: Is a directory" >&2 2741a650d1eSmrg exit 1 2751a650d1eSmrg fi 2761a650d1eSmrg dstdir=$dst 2771a650d1eSmrg dst=$dstdir/`basename "$src"` 2781a650d1eSmrg dstdir_status=0 2791a650d1eSmrg else 2801a650d1eSmrg # Prefer dirname, but fall back on a substitute if dirname fails. 2811a650d1eSmrg dstdir=` 2821a650d1eSmrg (dirname "$dst") 2>/dev/null || 2831a650d1eSmrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 2841a650d1eSmrg X"$dst" : 'X\(//\)[^/]' \| \ 2851a650d1eSmrg X"$dst" : 'X\(//\)$' \| \ 2861a650d1eSmrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 2871a650d1eSmrg echo X"$dst" | 2881a650d1eSmrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 2891a650d1eSmrg s//\1/ 2901a650d1eSmrg q 2911a650d1eSmrg } 2921a650d1eSmrg /^X\(\/\/\)[^/].*/{ 2931a650d1eSmrg s//\1/ 2941a650d1eSmrg q 2951a650d1eSmrg } 2961a650d1eSmrg /^X\(\/\/\)$/{ 2971a650d1eSmrg s//\1/ 2981a650d1eSmrg q 2991a650d1eSmrg } 3001a650d1eSmrg /^X\(\/\).*/{ 3011a650d1eSmrg s//\1/ 3021a650d1eSmrg q 3031a650d1eSmrg } 3041a650d1eSmrg s/.*/./; q' 3051a650d1eSmrg ` 3061a650d1eSmrg 3071a650d1eSmrg test -d "$dstdir" 3081a650d1eSmrg dstdir_status=$? 3091a650d1eSmrg fi 3101a650d1eSmrg fi 3111a650d1eSmrg 3121a650d1eSmrg obsolete_mkdir_used=false 3131a650d1eSmrg 3141a650d1eSmrg if test $dstdir_status != 0; then 3151a650d1eSmrg case $posix_mkdir in 3161a650d1eSmrg '') 3171a650d1eSmrg # Create intermediate dirs using mode 755 as modified by the umask. 3181a650d1eSmrg # This is like FreeBSD 'install' as of 1997-10-28. 3191a650d1eSmrg umask=`umask` 3201a650d1eSmrg case $stripcmd.$umask in 3211a650d1eSmrg # Optimize common cases. 3221a650d1eSmrg *[2367][2367]) mkdir_umask=$umask;; 3231a650d1eSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3241a650d1eSmrg 3251a650d1eSmrg *[0-7]) 3261a650d1eSmrg mkdir_umask=`expr $umask + 22 \ 3271a650d1eSmrg - $umask % 100 % 40 + $umask % 20 \ 3281a650d1eSmrg - $umask % 10 % 4 + $umask % 2 3291a650d1eSmrg `;; 3301a650d1eSmrg *) mkdir_umask=$umask,go-w;; 3311a650d1eSmrg esac 3321a650d1eSmrg 3331a650d1eSmrg # With -d, create the new directory with the user-specified mode. 3341a650d1eSmrg # Otherwise, rely on $mkdir_umask. 3351a650d1eSmrg if test -n "$dir_arg"; then 3361a650d1eSmrg mkdir_mode=-m$mode 3378108eb18Smrg else 3381a650d1eSmrg mkdir_mode= 3398108eb18Smrg fi 3408108eb18Smrg 3411a650d1eSmrg posix_mkdir=false 3421a650d1eSmrg case $umask in 3431a650d1eSmrg *[123567][0-7][0-7]) 3441a650d1eSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3451a650d1eSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3461a650d1eSmrg ;; 3471a650d1eSmrg *) 3481a650d1eSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3491a650d1eSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3501a650d1eSmrg 3511a650d1eSmrg if (umask $mkdir_umask && 3521a650d1eSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3531a650d1eSmrg then 3541a650d1eSmrg if test -z "$dir_arg" || { 3551a650d1eSmrg # Check for POSIX incompatibilities with -m. 3561a650d1eSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3571a650d1eSmrg # other-writeable bit of parent directory when it shouldn't. 3581a650d1eSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3591a650d1eSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3601a650d1eSmrg case $ls_ld_tmpdir in 3611a650d1eSmrg d????-?r-*) different_mode=700;; 3621a650d1eSmrg d????-?--*) different_mode=755;; 3631a650d1eSmrg *) false;; 3641a650d1eSmrg esac && 3651a650d1eSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3661a650d1eSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3671a650d1eSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3681a650d1eSmrg } 3691a650d1eSmrg } 3701a650d1eSmrg then posix_mkdir=: 3711a650d1eSmrg fi 3721a650d1eSmrg rmdir "$tmpdir/d" "$tmpdir" 3731a650d1eSmrg else 3741a650d1eSmrg # Remove any dirs left behind by ancient mkdir implementations. 3751a650d1eSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3761a650d1eSmrg fi 3771a650d1eSmrg trap '' 0;; 3781a650d1eSmrg esac;; 3791a650d1eSmrg esac 3808108eb18Smrg 3811a650d1eSmrg if 3821a650d1eSmrg $posix_mkdir && ( 3831a650d1eSmrg umask $mkdir_umask && 3841a650d1eSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3851a650d1eSmrg ) 3861a650d1eSmrg then : 3871a650d1eSmrg else 3881a650d1eSmrg 3891a650d1eSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3901a650d1eSmrg # or it failed possibly due to a race condition. Create the 3911a650d1eSmrg # directory the slow way, step by step, checking for races as we go. 3921a650d1eSmrg 3931a650d1eSmrg case $dstdir in 3941a650d1eSmrg /*) prefix='/';; 3955977a007Smrg [-=\(\)!]*) prefix='./';; 3961a650d1eSmrg *) prefix='';; 3971a650d1eSmrg esac 3981a650d1eSmrg 3991a650d1eSmrg eval "$initialize_posix_glob" 4001a650d1eSmrg 4011a650d1eSmrg oIFS=$IFS 4021a650d1eSmrg IFS=/ 4031a650d1eSmrg $posix_glob set -f 4041a650d1eSmrg set fnord $dstdir 4051a650d1eSmrg shift 4061a650d1eSmrg $posix_glob set +f 4071a650d1eSmrg IFS=$oIFS 4081a650d1eSmrg 4091a650d1eSmrg prefixes= 4101a650d1eSmrg 4111a650d1eSmrg for d 4121a650d1eSmrg do 4135977a007Smrg test X"$d" = X && continue 4141a650d1eSmrg 4151a650d1eSmrg prefix=$prefix$d 4161a650d1eSmrg if test -d "$prefix"; then 4171a650d1eSmrg prefixes= 4181a650d1eSmrg else 4191a650d1eSmrg if $posix_mkdir; then 4201a650d1eSmrg (umask=$mkdir_umask && 4211a650d1eSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4221a650d1eSmrg # Don't fail if two instances are running concurrently. 4231a650d1eSmrg test -d "$prefix" || exit 1 4241a650d1eSmrg else 4251a650d1eSmrg case $prefix in 4261a650d1eSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4271a650d1eSmrg *) qprefix=$prefix;; 4281a650d1eSmrg esac 4291a650d1eSmrg prefixes="$prefixes '$qprefix'" 4301a650d1eSmrg fi 4311a650d1eSmrg fi 4321a650d1eSmrg prefix=$prefix/ 4331a650d1eSmrg done 4341a650d1eSmrg 4351a650d1eSmrg if test -n "$prefixes"; then 4361a650d1eSmrg # Don't fail if two instances are running concurrently. 4371a650d1eSmrg (umask $mkdir_umask && 4381a650d1eSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 4391a650d1eSmrg test -d "$dstdir" || exit 1 4401a650d1eSmrg obsolete_mkdir_used=true 4411a650d1eSmrg fi 4421a650d1eSmrg fi 4431a650d1eSmrg fi 4441a650d1eSmrg 4451a650d1eSmrg if test -n "$dir_arg"; then 4461a650d1eSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4471a650d1eSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4481a650d1eSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4491a650d1eSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4501a650d1eSmrg else 4511a650d1eSmrg 4521a650d1eSmrg # Make a couple of temp file names in the proper directory. 4531a650d1eSmrg dsttmp=$dstdir/_inst.$$_ 4541a650d1eSmrg rmtmp=$dstdir/_rm.$$_ 4551a650d1eSmrg 4561a650d1eSmrg # Trap to clean up those temp files at exit. 4571a650d1eSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4581a650d1eSmrg 4591a650d1eSmrg # Copy the file name to the temp name. 4601a650d1eSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4611a650d1eSmrg 4621a650d1eSmrg # and set any options; do chmod last to preserve setuid bits. 4631a650d1eSmrg # 4641a650d1eSmrg # If any of these fail, we abort the whole thing. If we want to 4651a650d1eSmrg # ignore errors from any of these, just make sure not to ignore 4661a650d1eSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4671a650d1eSmrg # 4681a650d1eSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4691a650d1eSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4701a650d1eSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4711a650d1eSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4721a650d1eSmrg 4731a650d1eSmrg # If -C, don't bother to copy if it wouldn't change the file. 4741a650d1eSmrg if $copy_on_change && 4751a650d1eSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4761a650d1eSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4771a650d1eSmrg 4781a650d1eSmrg eval "$initialize_posix_glob" && 4791a650d1eSmrg $posix_glob set -f && 4801a650d1eSmrg set X $old && old=:$2:$4:$5:$6 && 4811a650d1eSmrg set X $new && new=:$2:$4:$5:$6 && 4821a650d1eSmrg $posix_glob set +f && 4831a650d1eSmrg 4841a650d1eSmrg test "$old" = "$new" && 4851a650d1eSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4861a650d1eSmrg then 4871a650d1eSmrg rm -f "$dsttmp" 4881a650d1eSmrg else 4891a650d1eSmrg # Rename the file to the real destination. 4901a650d1eSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4911a650d1eSmrg 4921a650d1eSmrg # The rename failed, perhaps because mv can't rename something else 4931a650d1eSmrg # to itself, or perhaps because mv is so ancient that it does not 4941a650d1eSmrg # support -f. 4951a650d1eSmrg { 4961a650d1eSmrg # Now remove or move aside any old file at destination location. 4971a650d1eSmrg # We try this two ways since rm can't unlink itself on some 4981a650d1eSmrg # systems and the destination file might be busy for other 4991a650d1eSmrg # reasons. In this case, the final cleanup might fail but the new 5001a650d1eSmrg # file should still install successfully. 5011a650d1eSmrg { 5021a650d1eSmrg test ! -f "$dst" || 5031a650d1eSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 5041a650d1eSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5051a650d1eSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 5061a650d1eSmrg } || 5071a650d1eSmrg { echo "$0: cannot unlink or rename $dst" >&2 5081a650d1eSmrg (exit 1); exit 1 5091a650d1eSmrg } 5101a650d1eSmrg } && 5111a650d1eSmrg 5121a650d1eSmrg # Now rename the file to the real destination. 5131a650d1eSmrg $doit $mvcmd "$dsttmp" "$dst" 5141a650d1eSmrg } 5151a650d1eSmrg fi || exit 1 5161a650d1eSmrg 5171a650d1eSmrg trap '' 0 5181a650d1eSmrg fi 5191a650d1eSmrgdone 5208108eb18Smrg 5211a650d1eSmrg# Local variables: 5221a650d1eSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 5231a650d1eSmrg# time-stamp-start: "scriptversion=" 5241a650d1eSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5251a650d1eSmrg# time-stamp-time-zone: "UTC" 5261a650d1eSmrg# time-stamp-end: "; # UTC" 5271a650d1eSmrg# End: 528