install-sh revision 4f6cd06f
1c35d236eSmrg#!/bin/sh 2c35d236eSmrg# install - install a program, script, or datafile 3c35d236eSmrg 44f6cd06fSmrgscriptversion=2006-10-14.15 5c35d236eSmrg 6c35d236eSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7c35d236eSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8c35d236eSmrg# following copyright and license. 9c35d236eSmrg# 10c35d236eSmrg# Copyright (C) 1994 X Consortium 11c35d236eSmrg# 12c35d236eSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13c35d236eSmrg# of this software and associated documentation files (the "Software"), to 14c35d236eSmrg# deal in the Software without restriction, including without limitation the 15c35d236eSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16c35d236eSmrg# sell copies of the Software, and to permit persons to whom the Software is 17c35d236eSmrg# furnished to do so, subject to the following conditions: 18c35d236eSmrg# 19c35d236eSmrg# The above copyright notice and this permission notice shall be included in 20c35d236eSmrg# all copies or substantial portions of the Software. 21c35d236eSmrg# 22c35d236eSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23c35d236eSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24c35d236eSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25c35d236eSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26c35d236eSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27c35d236eSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28c35d236eSmrg# 29c35d236eSmrg# Except as contained in this notice, the name of the X Consortium shall not 30c35d236eSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31c35d236eSmrg# ings in this Software without prior written authorization from the X Consor- 32c35d236eSmrg# tium. 33c35d236eSmrg# 34c35d236eSmrg# 35c35d236eSmrg# FSF changes to this file are in the public domain. 36c35d236eSmrg# 37c35d236eSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38c35d236eSmrg# `make' implicit rules from creating a file called install from it 39c35d236eSmrg# when there is no Makefile. 40c35d236eSmrg# 41c35d236eSmrg# This script is compatible with the BSD install script, but was written 424f6cd06fSmrg# from scratch. 434f6cd06fSmrg 444f6cd06fSmrgnl=' 454f6cd06fSmrg' 464f6cd06fSmrgIFS=" "" $nl" 47c35d236eSmrg 48c35d236eSmrg# set DOITPROG to echo to test this script 49c35d236eSmrg 50c35d236eSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 51c35d236eSmrgdoit="${DOITPROG-}" 524f6cd06fSmrgif test -z "$doit"; then 534f6cd06fSmrg doit_exec=exec 544f6cd06fSmrgelse 554f6cd06fSmrg doit_exec=$doit 564f6cd06fSmrgfi 57c35d236eSmrg 584f6cd06fSmrg# Put in absolute file names if you don't have them in your path; 594f6cd06fSmrg# or use environment vars. 60c35d236eSmrg 61c35d236eSmrgmvprog="${MVPROG-mv}" 62c35d236eSmrgcpprog="${CPPROG-cp}" 63c35d236eSmrgchmodprog="${CHMODPROG-chmod}" 64c35d236eSmrgchownprog="${CHOWNPROG-chown}" 65c35d236eSmrgchgrpprog="${CHGRPPROG-chgrp}" 66c35d236eSmrgstripprog="${STRIPPROG-strip}" 67c35d236eSmrgrmprog="${RMPROG-rm}" 68c35d236eSmrgmkdirprog="${MKDIRPROG-mkdir}" 69c35d236eSmrg 704f6cd06fSmrgposix_glob= 714f6cd06fSmrgposix_mkdir= 724f6cd06fSmrg 734f6cd06fSmrg# Desired mode of installed file. 744f6cd06fSmrgmode=0755 754f6cd06fSmrg 764f6cd06fSmrgchmodcmd=$chmodprog 77c35d236eSmrgchowncmd= 78c35d236eSmrgchgrpcmd= 79c35d236eSmrgstripcmd= 80c35d236eSmrgrmcmd="$rmprog -f" 81c35d236eSmrgmvcmd="$mvprog" 82c35d236eSmrgsrc= 83c35d236eSmrgdst= 84c35d236eSmrgdir_arg= 85c35d236eSmrgdstarg= 86c35d236eSmrgno_target_directory= 87c35d236eSmrg 88c35d236eSmrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89c35d236eSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90c35d236eSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91c35d236eSmrg or: $0 [OPTION]... -d DIRECTORIES... 92c35d236eSmrg 93c35d236eSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94c35d236eSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95c35d236eSmrgIn the 4th, create DIRECTORIES. 96c35d236eSmrg 97c35d236eSmrgOptions: 98c35d236eSmrg-c (ignored) 99c35d236eSmrg-d create directories instead of installing files. 100c35d236eSmrg-g GROUP $chgrpprog installed files to GROUP. 101c35d236eSmrg-m MODE $chmodprog installed files to MODE. 102c35d236eSmrg-o USER $chownprog installed files to USER. 103c35d236eSmrg-s $stripprog installed files. 104c35d236eSmrg-t DIRECTORY install into DIRECTORY. 105c35d236eSmrg-T report an error if DSTFILE is a directory. 106c35d236eSmrg--help display this help and exit. 107c35d236eSmrg--version display version info and exit. 108c35d236eSmrg 109c35d236eSmrgEnvironment variables override the default commands: 110c35d236eSmrg CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 111c35d236eSmrg" 112c35d236eSmrg 1134f6cd06fSmrgwhile test $# -ne 0; do 114c35d236eSmrg case $1 in 115c35d236eSmrg -c) shift 116c35d236eSmrg continue;; 117c35d236eSmrg 118c35d236eSmrg -d) dir_arg=true 119c35d236eSmrg shift 120c35d236eSmrg continue;; 121c35d236eSmrg 122c35d236eSmrg -g) chgrpcmd="$chgrpprog $2" 123c35d236eSmrg shift 124c35d236eSmrg shift 125c35d236eSmrg continue;; 126c35d236eSmrg 127c35d236eSmrg --help) echo "$usage"; exit $?;; 128c35d236eSmrg 1294f6cd06fSmrg -m) mode=$2 130c35d236eSmrg shift 131c35d236eSmrg shift 1324f6cd06fSmrg case $mode in 1334f6cd06fSmrg *' '* | *' '* | *' 1344f6cd06fSmrg'* | *'*'* | *'?'* | *'['*) 1354f6cd06fSmrg echo "$0: invalid mode: $mode" >&2 1364f6cd06fSmrg exit 1;; 1374f6cd06fSmrg esac 138c35d236eSmrg continue;; 139c35d236eSmrg 140c35d236eSmrg -o) chowncmd="$chownprog $2" 141c35d236eSmrg shift 142c35d236eSmrg shift 143c35d236eSmrg continue;; 144c35d236eSmrg 145c35d236eSmrg -s) stripcmd=$stripprog 146c35d236eSmrg shift 147c35d236eSmrg continue;; 148c35d236eSmrg 149c35d236eSmrg -t) dstarg=$2 150c35d236eSmrg shift 151c35d236eSmrg shift 152c35d236eSmrg continue;; 153c35d236eSmrg 154c35d236eSmrg -T) no_target_directory=true 155c35d236eSmrg shift 156c35d236eSmrg continue;; 157c35d236eSmrg 158c35d236eSmrg --version) echo "$0 $scriptversion"; exit $?;; 159c35d236eSmrg 1604f6cd06fSmrg --) shift 161c35d236eSmrg break;; 1624f6cd06fSmrg 1634f6cd06fSmrg -*) echo "$0: invalid option: $1" >&2 1644f6cd06fSmrg exit 1;; 1654f6cd06fSmrg 1664f6cd06fSmrg *) break;; 167c35d236eSmrg esac 168c35d236eSmrgdone 169c35d236eSmrg 1704f6cd06fSmrgif test $# -ne 0 && test -z "$dir_arg$dstarg"; then 1714f6cd06fSmrg # When -d is used, all remaining arguments are directories to create. 1724f6cd06fSmrg # When -t is used, the destination is already specified. 1734f6cd06fSmrg # Otherwise, the last argument is the destination. Remove it from $@. 1744f6cd06fSmrg for arg 1754f6cd06fSmrg do 1764f6cd06fSmrg if test -n "$dstarg"; then 1774f6cd06fSmrg # $@ is not empty: it contains at least $arg. 1784f6cd06fSmrg set fnord "$@" "$dstarg" 1794f6cd06fSmrg shift # fnord 1804f6cd06fSmrg fi 1814f6cd06fSmrg shift # arg 1824f6cd06fSmrg dstarg=$arg 1834f6cd06fSmrg done 1844f6cd06fSmrgfi 1854f6cd06fSmrg 1864f6cd06fSmrgif test $# -eq 0; then 187c35d236eSmrg if test -z "$dir_arg"; then 188c35d236eSmrg echo "$0: no input file specified." >&2 189c35d236eSmrg exit 1 190c35d236eSmrg fi 191c35d236eSmrg # It's OK to call `install-sh -d' without argument. 192c35d236eSmrg # This can happen when creating conditional directories. 193c35d236eSmrg exit 0 194c35d236eSmrgfi 195c35d236eSmrg 1964f6cd06fSmrgif test -z "$dir_arg"; then 1974f6cd06fSmrg trap '(exit $?); exit' 1 2 13 15 1984f6cd06fSmrg 1994f6cd06fSmrg # Set umask so as not to create temps with too-generous modes. 2004f6cd06fSmrg # However, 'strip' requires both read and write access to temps. 2014f6cd06fSmrg case $mode in 2024f6cd06fSmrg # Optimize common cases. 2034f6cd06fSmrg *644) cp_umask=133;; 2044f6cd06fSmrg *755) cp_umask=22;; 2054f6cd06fSmrg 2064f6cd06fSmrg *[0-7]) 2074f6cd06fSmrg if test -z "$stripcmd"; then 2084f6cd06fSmrg u_plus_rw= 2094f6cd06fSmrg else 2104f6cd06fSmrg u_plus_rw='% 200' 2114f6cd06fSmrg fi 2124f6cd06fSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2134f6cd06fSmrg *) 2144f6cd06fSmrg if test -z "$stripcmd"; then 2154f6cd06fSmrg u_plus_rw= 2164f6cd06fSmrg else 2174f6cd06fSmrg u_plus_rw=,u+rw 2184f6cd06fSmrg fi 2194f6cd06fSmrg cp_umask=$mode$u_plus_rw;; 2204f6cd06fSmrg esac 2214f6cd06fSmrgfi 2224f6cd06fSmrg 223c35d236eSmrgfor src 224c35d236eSmrgdo 225c35d236eSmrg # Protect names starting with `-'. 226c35d236eSmrg case $src in 227c35d236eSmrg -*) src=./$src ;; 228c35d236eSmrg esac 229c35d236eSmrg 230c35d236eSmrg if test -n "$dir_arg"; then 231c35d236eSmrg dst=$src 2324f6cd06fSmrg dstdir=$dst 2334f6cd06fSmrg test -d "$dstdir" 2344f6cd06fSmrg dstdir_status=$? 235c35d236eSmrg else 2364f6cd06fSmrg 237c35d236eSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 238c35d236eSmrg # might cause directories to be created, which would be especially bad 239c35d236eSmrg # if $src (and thus $dsttmp) contains '*'. 240c35d236eSmrg if test ! -f "$src" && test ! -d "$src"; then 241c35d236eSmrg echo "$0: $src does not exist." >&2 242c35d236eSmrg exit 1 243c35d236eSmrg fi 244c35d236eSmrg 245c35d236eSmrg if test -z "$dstarg"; then 246c35d236eSmrg echo "$0: no destination specified." >&2 247c35d236eSmrg exit 1 248c35d236eSmrg fi 249c35d236eSmrg 250c35d236eSmrg dst=$dstarg 251c35d236eSmrg # Protect names starting with `-'. 252c35d236eSmrg case $dst in 253c35d236eSmrg -*) dst=./$dst ;; 254c35d236eSmrg esac 255c35d236eSmrg 256c35d236eSmrg # If destination is a directory, append the input filename; won't work 257c35d236eSmrg # if double slashes aren't ignored. 258c35d236eSmrg if test -d "$dst"; then 259c35d236eSmrg if test -n "$no_target_directory"; then 260c35d236eSmrg echo "$0: $dstarg: Is a directory" >&2 261c35d236eSmrg exit 1 262c35d236eSmrg fi 2634f6cd06fSmrg dstdir=$dst 2644f6cd06fSmrg dst=$dstdir/`basename "$src"` 2654f6cd06fSmrg dstdir_status=0 2664f6cd06fSmrg else 2674f6cd06fSmrg # Prefer dirname, but fall back on a substitute if dirname fails. 2684f6cd06fSmrg dstdir=` 2694f6cd06fSmrg (dirname "$dst") 2>/dev/null || 2704f6cd06fSmrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 2714f6cd06fSmrg X"$dst" : 'X\(//\)[^/]' \| \ 2724f6cd06fSmrg X"$dst" : 'X\(//\)$' \| \ 2734f6cd06fSmrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 2744f6cd06fSmrg echo X"$dst" | 2754f6cd06fSmrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 2764f6cd06fSmrg s//\1/ 2774f6cd06fSmrg q 2784f6cd06fSmrg } 2794f6cd06fSmrg /^X\(\/\/\)[^/].*/{ 2804f6cd06fSmrg s//\1/ 2814f6cd06fSmrg q 2824f6cd06fSmrg } 2834f6cd06fSmrg /^X\(\/\/\)$/{ 2844f6cd06fSmrg s//\1/ 2854f6cd06fSmrg q 2864f6cd06fSmrg } 2874f6cd06fSmrg /^X\(\/\).*/{ 2884f6cd06fSmrg s//\1/ 2894f6cd06fSmrg q 2904f6cd06fSmrg } 2914f6cd06fSmrg s/.*/./; q' 2924f6cd06fSmrg ` 2934f6cd06fSmrg 2944f6cd06fSmrg test -d "$dstdir" 2954f6cd06fSmrg dstdir_status=$? 296c35d236eSmrg fi 297c35d236eSmrg fi 298c35d236eSmrg 2994f6cd06fSmrg obsolete_mkdir_used=false 3004f6cd06fSmrg 3014f6cd06fSmrg if test $dstdir_status != 0; then 3024f6cd06fSmrg case $posix_mkdir in 3034f6cd06fSmrg '') 3044f6cd06fSmrg # Create intermediate dirs using mode 755 as modified by the umask. 3054f6cd06fSmrg # This is like FreeBSD 'install' as of 1997-10-28. 3064f6cd06fSmrg umask=`umask` 3074f6cd06fSmrg case $stripcmd.$umask in 3084f6cd06fSmrg # Optimize common cases. 3094f6cd06fSmrg *[2367][2367]) mkdir_umask=$umask;; 3104f6cd06fSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3114f6cd06fSmrg 3124f6cd06fSmrg *[0-7]) 3134f6cd06fSmrg mkdir_umask=`expr $umask + 22 \ 3144f6cd06fSmrg - $umask % 100 % 40 + $umask % 20 \ 3154f6cd06fSmrg - $umask % 10 % 4 + $umask % 2 3164f6cd06fSmrg `;; 3174f6cd06fSmrg *) mkdir_umask=$umask,go-w;; 3184f6cd06fSmrg esac 3194f6cd06fSmrg 3204f6cd06fSmrg # With -d, create the new directory with the user-specified mode. 3214f6cd06fSmrg # Otherwise, rely on $mkdir_umask. 3224f6cd06fSmrg if test -n "$dir_arg"; then 3234f6cd06fSmrg mkdir_mode=-m$mode 3244f6cd06fSmrg else 3254f6cd06fSmrg mkdir_mode= 3264f6cd06fSmrg fi 3274f6cd06fSmrg 3284f6cd06fSmrg posix_mkdir=false 3294f6cd06fSmrg case $umask in 3304f6cd06fSmrg *[123567][0-7][0-7]) 3314f6cd06fSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3324f6cd06fSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3334f6cd06fSmrg ;; 3344f6cd06fSmrg *) 3354f6cd06fSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3364f6cd06fSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3374f6cd06fSmrg 3384f6cd06fSmrg if (umask $mkdir_umask && 3394f6cd06fSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3404f6cd06fSmrg then 3414f6cd06fSmrg if test -z "$dir_arg" || { 3424f6cd06fSmrg # Check for POSIX incompatibilities with -m. 3434f6cd06fSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3444f6cd06fSmrg # other-writeable bit of parent directory when it shouldn't. 3454f6cd06fSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3464f6cd06fSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3474f6cd06fSmrg case $ls_ld_tmpdir in 3484f6cd06fSmrg d????-?r-*) different_mode=700;; 3494f6cd06fSmrg d????-?--*) different_mode=755;; 3504f6cd06fSmrg *) false;; 3514f6cd06fSmrg esac && 3524f6cd06fSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3534f6cd06fSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3544f6cd06fSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3554f6cd06fSmrg } 3564f6cd06fSmrg } 3574f6cd06fSmrg then posix_mkdir=: 3584f6cd06fSmrg fi 3594f6cd06fSmrg rmdir "$tmpdir/d" "$tmpdir" 3604f6cd06fSmrg else 3614f6cd06fSmrg # Remove any dirs left behind by ancient mkdir implementations. 3624f6cd06fSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3634f6cd06fSmrg fi 3644f6cd06fSmrg trap '' 0;; 3654f6cd06fSmrg esac;; 3664f6cd06fSmrg esac 367c35d236eSmrg 3684f6cd06fSmrg if 3694f6cd06fSmrg $posix_mkdir && ( 3704f6cd06fSmrg umask $mkdir_umask && 3714f6cd06fSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3724f6cd06fSmrg ) 3734f6cd06fSmrg then : 3744f6cd06fSmrg else 375c35d236eSmrg 3764f6cd06fSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3774f6cd06fSmrg # or it failed possibly due to a race condition. Create the 3784f6cd06fSmrg # directory the slow way, step by step, checking for races as we go. 3794f6cd06fSmrg 3804f6cd06fSmrg case $dstdir in 3814f6cd06fSmrg /*) prefix=/ ;; 3824f6cd06fSmrg -*) prefix=./ ;; 3834f6cd06fSmrg *) prefix= ;; 3844f6cd06fSmrg esac 3854f6cd06fSmrg 3864f6cd06fSmrg case $posix_glob in 3874f6cd06fSmrg '') 3884f6cd06fSmrg if (set -f) 2>/dev/null; then 3894f6cd06fSmrg posix_glob=true 3904f6cd06fSmrg else 3914f6cd06fSmrg posix_glob=false 3924f6cd06fSmrg fi ;; 3934f6cd06fSmrg esac 3944f6cd06fSmrg 3954f6cd06fSmrg oIFS=$IFS 3964f6cd06fSmrg IFS=/ 3974f6cd06fSmrg $posix_glob && set -f 3984f6cd06fSmrg set fnord $dstdir 399c35d236eSmrg shift 4004f6cd06fSmrg $posix_glob && set +f 4014f6cd06fSmrg IFS=$oIFS 4024f6cd06fSmrg 4034f6cd06fSmrg prefixes= 4044f6cd06fSmrg 4054f6cd06fSmrg for d 4064f6cd06fSmrg do 4074f6cd06fSmrg test -z "$d" && continue 4084f6cd06fSmrg 4094f6cd06fSmrg prefix=$prefix$d 4104f6cd06fSmrg if test -d "$prefix"; then 4114f6cd06fSmrg prefixes= 4124f6cd06fSmrg else 4134f6cd06fSmrg if $posix_mkdir; then 4144f6cd06fSmrg (umask=$mkdir_umask && 4154f6cd06fSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4164f6cd06fSmrg # Don't fail if two instances are running concurrently. 4174f6cd06fSmrg test -d "$prefix" || exit 1 4184f6cd06fSmrg else 4194f6cd06fSmrg case $prefix in 4204f6cd06fSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4214f6cd06fSmrg *) qprefix=$prefix;; 4224f6cd06fSmrg esac 4234f6cd06fSmrg prefixes="$prefixes '$qprefix'" 4244f6cd06fSmrg fi 4254f6cd06fSmrg fi 4264f6cd06fSmrg prefix=$prefix/ 4274f6cd06fSmrg done 4284f6cd06fSmrg 4294f6cd06fSmrg if test -n "$prefixes"; then 4304f6cd06fSmrg # Don't fail if two instances are running concurrently. 4314f6cd06fSmrg (umask $mkdir_umask && 4324f6cd06fSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 4334f6cd06fSmrg test -d "$dstdir" || exit 1 4344f6cd06fSmrg obsolete_mkdir_used=true 435c35d236eSmrg fi 4364f6cd06fSmrg fi 437c35d236eSmrg fi 438c35d236eSmrg 439c35d236eSmrg if test -n "$dir_arg"; then 4404f6cd06fSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4414f6cd06fSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4424f6cd06fSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4434f6cd06fSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 444c35d236eSmrg else 445c35d236eSmrg 446c35d236eSmrg # Make a couple of temp file names in the proper directory. 447c35d236eSmrg dsttmp=$dstdir/_inst.$$_ 448c35d236eSmrg rmtmp=$dstdir/_rm.$$_ 449c35d236eSmrg 450c35d236eSmrg # Trap to clean up those temp files at exit. 451c35d236eSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 452c35d236eSmrg 453c35d236eSmrg # Copy the file name to the temp name. 4544f6cd06fSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 455c35d236eSmrg 456c35d236eSmrg # and set any options; do chmod last to preserve setuid bits. 457c35d236eSmrg # 458c35d236eSmrg # If any of these fail, we abort the whole thing. If we want to 459c35d236eSmrg # ignore errors from any of these, just make sure not to ignore 460c35d236eSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 461c35d236eSmrg # 462c35d236eSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 463c35d236eSmrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 464c35d236eSmrg && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 4654f6cd06fSmrg && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466c35d236eSmrg 467c35d236eSmrg # Now rename the file to the real destination. 4684f6cd06fSmrg { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ 469c35d236eSmrg || { 470c35d236eSmrg # The rename failed, perhaps because mv can't rename something else 471c35d236eSmrg # to itself, or perhaps because mv is so ancient that it does not 472c35d236eSmrg # support -f. 473c35d236eSmrg 474c35d236eSmrg # Now remove or move aside any old file at destination location. 475c35d236eSmrg # We try this two ways since rm can't unlink itself on some 476c35d236eSmrg # systems and the destination file might be busy for other 477c35d236eSmrg # reasons. In this case, the final cleanup might fail but the new 478c35d236eSmrg # file should still install successfully. 479c35d236eSmrg { 4804f6cd06fSmrg if test -f "$dst"; then 4814f6cd06fSmrg $doit $rmcmd -f "$dst" 2>/dev/null \ 4824f6cd06fSmrg || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ 4834f6cd06fSmrg && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ 484c35d236eSmrg || { 4854f6cd06fSmrg echo "$0: cannot unlink or rename $dst" >&2 486c35d236eSmrg (exit 1); exit 1 487c35d236eSmrg } 488c35d236eSmrg else 489c35d236eSmrg : 490c35d236eSmrg fi 491c35d236eSmrg } && 492c35d236eSmrg 493c35d236eSmrg # Now rename the file to the real destination. 4944f6cd06fSmrg $doit $mvcmd "$dsttmp" "$dst" 495c35d236eSmrg } 4964f6cd06fSmrg } || exit 1 497c35d236eSmrg 4984f6cd06fSmrg trap '' 0 4994f6cd06fSmrg fi 5004f6cd06fSmrgdone 501c35d236eSmrg 502c35d236eSmrg# Local variables: 503c35d236eSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 504c35d236eSmrg# time-stamp-start: "scriptversion=" 505c35d236eSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 506c35d236eSmrg# time-stamp-end: "$" 507c35d236eSmrg# End: 508