130da1778Schristos#!/bin/sh 230da1778Schristos# install - install a program, script, or datafile 330da1778Schristos 4*56bd8546Schristosscriptversion=2014-09-12.12; # UTC 530da1778Schristos 630da1778Schristos# This originates from X11R5 (mit/util/scripts/install.sh), which was 730da1778Schristos# later released in X11R6 (xc/config/util/install.sh) with the 830da1778Schristos# following copyright and license. 930da1778Schristos# 1030da1778Schristos# Copyright (C) 1994 X Consortium 1130da1778Schristos# 1230da1778Schristos# Permission is hereby granted, free of charge, to any person obtaining a copy 1330da1778Schristos# of this software and associated documentation files (the "Software"), to 1430da1778Schristos# deal in the Software without restriction, including without limitation the 1530da1778Schristos# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1630da1778Schristos# sell copies of the Software, and to permit persons to whom the Software is 1730da1778Schristos# furnished to do so, subject to the following conditions: 1830da1778Schristos# 1930da1778Schristos# The above copyright notice and this permission notice shall be included in 2030da1778Schristos# all copies or substantial portions of the Software. 2130da1778Schristos# 2230da1778Schristos# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2330da1778Schristos# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2430da1778Schristos# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2530da1778Schristos# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2630da1778Schristos# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2730da1778Schristos# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2830da1778Schristos# 2930da1778Schristos# Except as contained in this notice, the name of the X Consortium shall not 3030da1778Schristos# be used in advertising or otherwise to promote the sale, use or other deal- 3130da1778Schristos# ings in this Software without prior written authorization from the X Consor- 3230da1778Schristos# tium. 3330da1778Schristos# 3430da1778Schristos# 3530da1778Schristos# FSF changes to this file are in the public domain. 3630da1778Schristos# 3730da1778Schristos# Calling this script install-sh is preferred over install.sh, to prevent 3830da1778Schristos# 'make' implicit rules from creating a file called install from it 3930da1778Schristos# when there is no Makefile. 4030da1778Schristos# 4130da1778Schristos# This script is compatible with the BSD install script, but was written 4230da1778Schristos# from scratch. 4330da1778Schristos 4430da1778Schristostab=' ' 4530da1778Schristosnl=' 4630da1778Schristos' 4730da1778SchristosIFS=" $tab$nl" 4830da1778Schristos 4930da1778Schristos# Set DOITPROG to "echo" to test this script. 5030da1778Schristos 5130da1778Schristosdoit=${DOITPROG-} 5230da1778Schristosdoit_exec=${doit:-exec} 5330da1778Schristos 5430da1778Schristos# Put in absolute file names if you don't have them in your path; 5530da1778Schristos# or use environment vars. 5630da1778Schristos 5730da1778Schristoschgrpprog=${CHGRPPROG-chgrp} 5830da1778Schristoschmodprog=${CHMODPROG-chmod} 5930da1778Schristoschownprog=${CHOWNPROG-chown} 6030da1778Schristoscmpprog=${CMPPROG-cmp} 6130da1778Schristoscpprog=${CPPROG-cp} 6230da1778Schristosmkdirprog=${MKDIRPROG-mkdir} 6330da1778Schristosmvprog=${MVPROG-mv} 6430da1778Schristosrmprog=${RMPROG-rm} 6530da1778Schristosstripprog=${STRIPPROG-strip} 6630da1778Schristos 6730da1778Schristosposix_mkdir= 6830da1778Schristos 6930da1778Schristos# Desired mode of installed file. 7030da1778Schristosmode=0755 7130da1778Schristos 7230da1778Schristoschgrpcmd= 7330da1778Schristoschmodcmd=$chmodprog 7430da1778Schristoschowncmd= 7530da1778Schristosmvcmd=$mvprog 7630da1778Schristosrmcmd="$rmprog -f" 7730da1778Schristosstripcmd= 7830da1778Schristos 7930da1778Schristossrc= 8030da1778Schristosdst= 8130da1778Schristosdir_arg= 8230da1778Schristosdst_arg= 8330da1778Schristos 8430da1778Schristoscopy_on_change=false 8530da1778Schristosis_target_a_directory=possibly 8630da1778Schristos 8730da1778Schristosusage="\ 8830da1778SchristosUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 8930da1778Schristos or: $0 [OPTION]... SRCFILES... DIRECTORY 9030da1778Schristos or: $0 [OPTION]... -t DIRECTORY SRCFILES... 9130da1778Schristos or: $0 [OPTION]... -d DIRECTORIES... 9230da1778Schristos 9330da1778SchristosIn the 1st form, copy SRCFILE to DSTFILE. 9430da1778SchristosIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 9530da1778SchristosIn the 4th, create DIRECTORIES. 9630da1778Schristos 9730da1778SchristosOptions: 9830da1778Schristos --help display this help and exit. 9930da1778Schristos --version display version info and exit. 10030da1778Schristos 10130da1778Schristos -c (ignored) 10230da1778Schristos -C install only if different (preserve the last data modification time) 10330da1778Schristos -d create directories instead of installing files. 10430da1778Schristos -g GROUP $chgrpprog installed files to GROUP. 10530da1778Schristos -m MODE $chmodprog installed files to MODE. 10630da1778Schristos -o USER $chownprog installed files to USER. 10730da1778Schristos -s $stripprog installed files. 10830da1778Schristos -t DIRECTORY install into DIRECTORY. 10930da1778Schristos -T report an error if DSTFILE is a directory. 11030da1778Schristos 11130da1778SchristosEnvironment variables override the default commands: 11230da1778Schristos CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11330da1778Schristos RMPROG STRIPPROG 11430da1778Schristos" 11530da1778Schristos 11630da1778Schristoswhile test $# -ne 0; do 11730da1778Schristos case $1 in 11830da1778Schristos -c) ;; 11930da1778Schristos 12030da1778Schristos -C) copy_on_change=true;; 12130da1778Schristos 12230da1778Schristos -d) dir_arg=true;; 12330da1778Schristos 12430da1778Schristos -g) chgrpcmd="$chgrpprog $2" 12530da1778Schristos shift;; 12630da1778Schristos 12730da1778Schristos --help) echo "$usage"; exit $?;; 12830da1778Schristos 12930da1778Schristos -m) mode=$2 13030da1778Schristos case $mode in 13130da1778Schristos *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 13230da1778Schristos echo "$0: invalid mode: $mode" >&2 13330da1778Schristos exit 1;; 13430da1778Schristos esac 13530da1778Schristos shift;; 13630da1778Schristos 13730da1778Schristos -o) chowncmd="$chownprog $2" 13830da1778Schristos shift;; 13930da1778Schristos 14030da1778Schristos -s) stripcmd=$stripprog;; 14130da1778Schristos 14230da1778Schristos -t) 14330da1778Schristos is_target_a_directory=always 14430da1778Schristos dst_arg=$2 14530da1778Schristos # Protect names problematic for 'test' and other utilities. 14630da1778Schristos case $dst_arg in 14730da1778Schristos -* | [=\(\)!]) dst_arg=./$dst_arg;; 14830da1778Schristos esac 14930da1778Schristos shift;; 15030da1778Schristos 15130da1778Schristos -T) is_target_a_directory=never;; 15230da1778Schristos 15330da1778Schristos --version) echo "$0 $scriptversion"; exit $?;; 15430da1778Schristos 15530da1778Schristos --) shift 15630da1778Schristos break;; 15730da1778Schristos 15830da1778Schristos -*) echo "$0: invalid option: $1" >&2 15930da1778Schristos exit 1;; 16030da1778Schristos 16130da1778Schristos *) break;; 16230da1778Schristos esac 16330da1778Schristos shift 16430da1778Schristosdone 16530da1778Schristos 16630da1778Schristos# We allow the use of options -d and -T together, by making -d 16730da1778Schristos# take the precedence; this is for compatibility with GNU install. 16830da1778Schristos 16930da1778Schristosif test -n "$dir_arg"; then 17030da1778Schristos if test -n "$dst_arg"; then 17130da1778Schristos echo "$0: target directory not allowed when installing a directory." >&2 17230da1778Schristos exit 1 17330da1778Schristos fi 17430da1778Schristosfi 17530da1778Schristos 17630da1778Schristosif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17730da1778Schristos # When -d is used, all remaining arguments are directories to create. 17830da1778Schristos # When -t is used, the destination is already specified. 17930da1778Schristos # Otherwise, the last argument is the destination. Remove it from $@. 18030da1778Schristos for arg 18130da1778Schristos do 18230da1778Schristos if test -n "$dst_arg"; then 18330da1778Schristos # $@ is not empty: it contains at least $arg. 18430da1778Schristos set fnord "$@" "$dst_arg" 18530da1778Schristos shift # fnord 18630da1778Schristos fi 18730da1778Schristos shift # arg 18830da1778Schristos dst_arg=$arg 18930da1778Schristos # Protect names problematic for 'test' and other utilities. 19030da1778Schristos case $dst_arg in 19130da1778Schristos -* | [=\(\)!]) dst_arg=./$dst_arg;; 19230da1778Schristos esac 19330da1778Schristos done 19430da1778Schristosfi 19530da1778Schristos 19630da1778Schristosif test $# -eq 0; then 19730da1778Schristos if test -z "$dir_arg"; then 19830da1778Schristos echo "$0: no input file specified." >&2 19930da1778Schristos exit 1 20030da1778Schristos fi 20130da1778Schristos # It's OK to call 'install-sh -d' without argument. 20230da1778Schristos # This can happen when creating conditional directories. 20330da1778Schristos exit 0 20430da1778Schristosfi 20530da1778Schristos 20630da1778Schristosif test -z "$dir_arg"; then 20730da1778Schristos if test $# -gt 1 || test "$is_target_a_directory" = always; then 20830da1778Schristos if test ! -d "$dst_arg"; then 20930da1778Schristos echo "$0: $dst_arg: Is not a directory." >&2 21030da1778Schristos exit 1 21130da1778Schristos fi 21230da1778Schristos fi 21330da1778Schristosfi 21430da1778Schristos 21530da1778Schristosif test -z "$dir_arg"; then 21630da1778Schristos do_exit='(exit $ret); exit $ret' 21730da1778Schristos trap "ret=129; $do_exit" 1 21830da1778Schristos trap "ret=130; $do_exit" 2 21930da1778Schristos trap "ret=141; $do_exit" 13 22030da1778Schristos trap "ret=143; $do_exit" 15 22130da1778Schristos 22230da1778Schristos # Set umask so as not to create temps with too-generous modes. 22330da1778Schristos # However, 'strip' requires both read and write access to temps. 22430da1778Schristos case $mode in 22530da1778Schristos # Optimize common cases. 22630da1778Schristos *644) cp_umask=133;; 22730da1778Schristos *755) cp_umask=22;; 22830da1778Schristos 22930da1778Schristos *[0-7]) 23030da1778Schristos if test -z "$stripcmd"; then 23130da1778Schristos u_plus_rw= 23230da1778Schristos else 23330da1778Schristos u_plus_rw='% 200' 23430da1778Schristos fi 23530da1778Schristos cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23630da1778Schristos *) 23730da1778Schristos if test -z "$stripcmd"; then 23830da1778Schristos u_plus_rw= 23930da1778Schristos else 24030da1778Schristos u_plus_rw=,u+rw 24130da1778Schristos fi 24230da1778Schristos cp_umask=$mode$u_plus_rw;; 24330da1778Schristos esac 24430da1778Schristosfi 24530da1778Schristos 24630da1778Schristosfor src 24730da1778Schristosdo 24830da1778Schristos # Protect names problematic for 'test' and other utilities. 24930da1778Schristos case $src in 25030da1778Schristos -* | [=\(\)!]) src=./$src;; 25130da1778Schristos esac 25230da1778Schristos 25330da1778Schristos if test -n "$dir_arg"; then 25430da1778Schristos dst=$src 25530da1778Schristos dstdir=$dst 25630da1778Schristos test -d "$dstdir" 25730da1778Schristos dstdir_status=$? 25830da1778Schristos else 25930da1778Schristos 26030da1778Schristos # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 26130da1778Schristos # might cause directories to be created, which would be especially bad 26230da1778Schristos # if $src (and thus $dsttmp) contains '*'. 26330da1778Schristos if test ! -f "$src" && test ! -d "$src"; then 26430da1778Schristos echo "$0: $src does not exist." >&2 26530da1778Schristos exit 1 26630da1778Schristos fi 26730da1778Schristos 26830da1778Schristos if test -z "$dst_arg"; then 26930da1778Schristos echo "$0: no destination specified." >&2 27030da1778Schristos exit 1 27130da1778Schristos fi 27230da1778Schristos dst=$dst_arg 27330da1778Schristos 27430da1778Schristos # If destination is a directory, append the input filename; won't work 27530da1778Schristos # if double slashes aren't ignored. 27630da1778Schristos if test -d "$dst"; then 27730da1778Schristos if test "$is_target_a_directory" = never; then 27830da1778Schristos echo "$0: $dst_arg: Is a directory" >&2 27930da1778Schristos exit 1 28030da1778Schristos fi 28130da1778Schristos dstdir=$dst 28230da1778Schristos dst=$dstdir/`basename "$src"` 28330da1778Schristos dstdir_status=0 28430da1778Schristos else 28530da1778Schristos dstdir=`dirname "$dst"` 28630da1778Schristos test -d "$dstdir" 28730da1778Schristos dstdir_status=$? 28830da1778Schristos fi 28930da1778Schristos fi 29030da1778Schristos 29130da1778Schristos obsolete_mkdir_used=false 29230da1778Schristos 29330da1778Schristos if test $dstdir_status != 0; then 29430da1778Schristos case $posix_mkdir in 29530da1778Schristos '') 29630da1778Schristos # Create intermediate dirs using mode 755 as modified by the umask. 29730da1778Schristos # This is like FreeBSD 'install' as of 1997-10-28. 29830da1778Schristos umask=`umask` 29930da1778Schristos case $stripcmd.$umask in 30030da1778Schristos # Optimize common cases. 30130da1778Schristos *[2367][2367]) mkdir_umask=$umask;; 30230da1778Schristos .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 30330da1778Schristos 30430da1778Schristos *[0-7]) 30530da1778Schristos mkdir_umask=`expr $umask + 22 \ 30630da1778Schristos - $umask % 100 % 40 + $umask % 20 \ 30730da1778Schristos - $umask % 10 % 4 + $umask % 2 30830da1778Schristos `;; 30930da1778Schristos *) mkdir_umask=$umask,go-w;; 31030da1778Schristos esac 31130da1778Schristos 31230da1778Schristos # With -d, create the new directory with the user-specified mode. 31330da1778Schristos # Otherwise, rely on $mkdir_umask. 31430da1778Schristos if test -n "$dir_arg"; then 31530da1778Schristos mkdir_mode=-m$mode 31630da1778Schristos else 31730da1778Schristos mkdir_mode= 31830da1778Schristos fi 31930da1778Schristos 32030da1778Schristos posix_mkdir=false 32130da1778Schristos case $umask in 32230da1778Schristos *[123567][0-7][0-7]) 32330da1778Schristos # POSIX mkdir -p sets u+wx bits regardless of umask, which 32430da1778Schristos # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 32530da1778Schristos ;; 32630da1778Schristos *) 327*56bd8546Schristos # $RANDOM is not portable (e.g. dash); use it when possible to 328*56bd8546Schristos # lower collision chance 32930da1778Schristos tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 330*56bd8546Schristos trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 33130da1778Schristos 332*56bd8546Schristos # As "mkdir -p" follows symlinks and we work in /tmp possibly; so 333*56bd8546Schristos # create the $tmpdir first (and fail if unsuccessful) to make sure 334*56bd8546Schristos # that nobody tries to guess the $tmpdir name. 33530da1778Schristos if (umask $mkdir_umask && 336*56bd8546Schristos $mkdirprog $mkdir_mode "$tmpdir" && 337*56bd8546Schristos exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 33830da1778Schristos then 33930da1778Schristos if test -z "$dir_arg" || { 34030da1778Schristos # Check for POSIX incompatibilities with -m. 34130da1778Schristos # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 34230da1778Schristos # other-writable bit of parent directory when it shouldn't. 34330da1778Schristos # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 344*56bd8546Schristos test_tmpdir="$tmpdir/a" 345*56bd8546Schristos ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 34630da1778Schristos case $ls_ld_tmpdir in 34730da1778Schristos d????-?r-*) different_mode=700;; 34830da1778Schristos d????-?--*) different_mode=755;; 34930da1778Schristos *) false;; 35030da1778Schristos esac && 351*56bd8546Schristos $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 352*56bd8546Schristos ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 35330da1778Schristos test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 35430da1778Schristos } 35530da1778Schristos } 35630da1778Schristos then posix_mkdir=: 35730da1778Schristos fi 358*56bd8546Schristos rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 35930da1778Schristos else 36030da1778Schristos # Remove any dirs left behind by ancient mkdir implementations. 361*56bd8546Schristos rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 36230da1778Schristos fi 36330da1778Schristos trap '' 0;; 36430da1778Schristos esac;; 36530da1778Schristos esac 36630da1778Schristos 36730da1778Schristos if 36830da1778Schristos $posix_mkdir && ( 36930da1778Schristos umask $mkdir_umask && 37030da1778Schristos $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 37130da1778Schristos ) 37230da1778Schristos then : 37330da1778Schristos else 37430da1778Schristos 37530da1778Schristos # The umask is ridiculous, or mkdir does not conform to POSIX, 37630da1778Schristos # or it failed possibly due to a race condition. Create the 37730da1778Schristos # directory the slow way, step by step, checking for races as we go. 37830da1778Schristos 37930da1778Schristos case $dstdir in 38030da1778Schristos /*) prefix='/';; 38130da1778Schristos [-=\(\)!]*) prefix='./';; 38230da1778Schristos *) prefix='';; 38330da1778Schristos esac 38430da1778Schristos 38530da1778Schristos oIFS=$IFS 38630da1778Schristos IFS=/ 38730da1778Schristos set -f 38830da1778Schristos set fnord $dstdir 38930da1778Schristos shift 39030da1778Schristos set +f 39130da1778Schristos IFS=$oIFS 39230da1778Schristos 39330da1778Schristos prefixes= 39430da1778Schristos 39530da1778Schristos for d 39630da1778Schristos do 39730da1778Schristos test X"$d" = X && continue 39830da1778Schristos 39930da1778Schristos prefix=$prefix$d 40030da1778Schristos if test -d "$prefix"; then 40130da1778Schristos prefixes= 40230da1778Schristos else 40330da1778Schristos if $posix_mkdir; then 40430da1778Schristos (umask=$mkdir_umask && 40530da1778Schristos $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 40630da1778Schristos # Don't fail if two instances are running concurrently. 40730da1778Schristos test -d "$prefix" || exit 1 40830da1778Schristos else 40930da1778Schristos case $prefix in 41030da1778Schristos *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 41130da1778Schristos *) qprefix=$prefix;; 41230da1778Schristos esac 41330da1778Schristos prefixes="$prefixes '$qprefix'" 41430da1778Schristos fi 41530da1778Schristos fi 41630da1778Schristos prefix=$prefix/ 41730da1778Schristos done 41830da1778Schristos 41930da1778Schristos if test -n "$prefixes"; then 42030da1778Schristos # Don't fail if two instances are running concurrently. 42130da1778Schristos (umask $mkdir_umask && 42230da1778Schristos eval "\$doit_exec \$mkdirprog $prefixes") || 42330da1778Schristos test -d "$dstdir" || exit 1 42430da1778Schristos obsolete_mkdir_used=true 42530da1778Schristos fi 42630da1778Schristos fi 42730da1778Schristos fi 42830da1778Schristos 42930da1778Schristos if test -n "$dir_arg"; then 43030da1778Schristos { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 43130da1778Schristos { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 43230da1778Schristos { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 43330da1778Schristos test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 43430da1778Schristos else 43530da1778Schristos 43630da1778Schristos # Make a couple of temp file names in the proper directory. 43730da1778Schristos dsttmp=$dstdir/_inst.$$_ 43830da1778Schristos rmtmp=$dstdir/_rm.$$_ 43930da1778Schristos 44030da1778Schristos # Trap to clean up those temp files at exit. 44130da1778Schristos trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 44230da1778Schristos 44330da1778Schristos # Copy the file name to the temp name. 44430da1778Schristos (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 44530da1778Schristos 44630da1778Schristos # and set any options; do chmod last to preserve setuid bits. 44730da1778Schristos # 44830da1778Schristos # If any of these fail, we abort the whole thing. If we want to 44930da1778Schristos # ignore errors from any of these, just make sure not to ignore 45030da1778Schristos # errors from the above "$doit $cpprog $src $dsttmp" command. 45130da1778Schristos # 45230da1778Schristos { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 45330da1778Schristos { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 45430da1778Schristos { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 45530da1778Schristos { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 45630da1778Schristos 45730da1778Schristos # If -C, don't bother to copy if it wouldn't change the file. 45830da1778Schristos if $copy_on_change && 45930da1778Schristos old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 46030da1778Schristos new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 46130da1778Schristos set -f && 46230da1778Schristos set X $old && old=:$2:$4:$5:$6 && 46330da1778Schristos set X $new && new=:$2:$4:$5:$6 && 46430da1778Schristos set +f && 46530da1778Schristos test "$old" = "$new" && 46630da1778Schristos $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 46730da1778Schristos then 46830da1778Schristos rm -f "$dsttmp" 46930da1778Schristos else 47030da1778Schristos # Rename the file to the real destination. 47130da1778Schristos $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 47230da1778Schristos 47330da1778Schristos # The rename failed, perhaps because mv can't rename something else 47430da1778Schristos # to itself, or perhaps because mv is so ancient that it does not 47530da1778Schristos # support -f. 47630da1778Schristos { 47730da1778Schristos # Now remove or move aside any old file at destination location. 47830da1778Schristos # We try this two ways since rm can't unlink itself on some 47930da1778Schristos # systems and the destination file might be busy for other 48030da1778Schristos # reasons. In this case, the final cleanup might fail but the new 48130da1778Schristos # file should still install successfully. 48230da1778Schristos { 48330da1778Schristos test ! -f "$dst" || 48430da1778Schristos $doit $rmcmd -f "$dst" 2>/dev/null || 48530da1778Schristos { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 48630da1778Schristos { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 48730da1778Schristos } || 48830da1778Schristos { echo "$0: cannot unlink or rename $dst" >&2 48930da1778Schristos (exit 1); exit 1 49030da1778Schristos } 49130da1778Schristos } && 49230da1778Schristos 49330da1778Schristos # Now rename the file to the real destination. 49430da1778Schristos $doit $mvcmd "$dsttmp" "$dst" 49530da1778Schristos } 49630da1778Schristos fi || exit 1 49730da1778Schristos 49830da1778Schristos trap '' 0 49930da1778Schristos fi 50030da1778Schristosdone 50130da1778Schristos 50230da1778Schristos# Local variables: 50330da1778Schristos# eval: (add-hook 'write-file-hooks 'time-stamp) 50430da1778Schristos# time-stamp-start: "scriptversion=" 50530da1778Schristos# time-stamp-format: "%:y-%02m-%02d.%02H" 50630da1778Schristos# time-stamp-time-zone: "UTC" 50730da1778Schristos# time-stamp-end: "; # UTC" 50830da1778Schristos# End: 509