install-sh revision 1abf7346
11abf7346Smrg#!/bin/sh
21abf7346Smrg# install - install a program, script, or datafile
31abf7346Smrg
41abf7346Smrgscriptversion=2006-10-14.15
51abf7346Smrg
61abf7346Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
71abf7346Smrg# later released in X11R6 (xc/config/util/install.sh) with the
81abf7346Smrg# following copyright and license.
91abf7346Smrg#
101abf7346Smrg# Copyright (C) 1994 X Consortium
111abf7346Smrg#
121abf7346Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
131abf7346Smrg# of this software and associated documentation files (the "Software"), to
141abf7346Smrg# deal in the Software without restriction, including without limitation the
151abf7346Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
161abf7346Smrg# sell copies of the Software, and to permit persons to whom the Software is
171abf7346Smrg# furnished to do so, subject to the following conditions:
181abf7346Smrg#
191abf7346Smrg# The above copyright notice and this permission notice shall be included in
201abf7346Smrg# all copies or substantial portions of the Software.
211abf7346Smrg#
221abf7346Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
231abf7346Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
241abf7346Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
251abf7346Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
261abf7346Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
271abf7346Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
281abf7346Smrg#
291abf7346Smrg# Except as contained in this notice, the name of the X Consortium shall not
301abf7346Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
311abf7346Smrg# ings in this Software without prior written authorization from the X Consor-
321abf7346Smrg# tium.
331abf7346Smrg#
341abf7346Smrg#
351abf7346Smrg# FSF changes to this file are in the public domain.
361abf7346Smrg#
371abf7346Smrg# Calling this script install-sh is preferred over install.sh, to prevent
381abf7346Smrg# `make' implicit rules from creating a file called install from it
391abf7346Smrg# when there is no Makefile.
401abf7346Smrg#
411abf7346Smrg# This script is compatible with the BSD install script, but was written
421abf7346Smrg# from scratch.
431abf7346Smrg
441abf7346Smrgnl='
451abf7346Smrg'
461abf7346SmrgIFS=" ""	$nl"
471abf7346Smrg
481abf7346Smrg# set DOITPROG to echo to test this script
491abf7346Smrg
501abf7346Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
511abf7346Smrgdoit="${DOITPROG-}"
521abf7346Smrgif test -z "$doit"; then
531abf7346Smrg  doit_exec=exec
541abf7346Smrgelse
551abf7346Smrg  doit_exec=$doit
561abf7346Smrgfi
571abf7346Smrg
581abf7346Smrg# Put in absolute file names if you don't have them in your path;
591abf7346Smrg# or use environment vars.
601abf7346Smrg
611abf7346Smrgmvprog="${MVPROG-mv}"
621abf7346Smrgcpprog="${CPPROG-cp}"
631abf7346Smrgchmodprog="${CHMODPROG-chmod}"
641abf7346Smrgchownprog="${CHOWNPROG-chown}"
651abf7346Smrgchgrpprog="${CHGRPPROG-chgrp}"
661abf7346Smrgstripprog="${STRIPPROG-strip}"
671abf7346Smrgrmprog="${RMPROG-rm}"
681abf7346Smrgmkdirprog="${MKDIRPROG-mkdir}"
691abf7346Smrg
701abf7346Smrgposix_glob=
711abf7346Smrgposix_mkdir=
721abf7346Smrg
731abf7346Smrg# Desired mode of installed file.
741abf7346Smrgmode=0755
751abf7346Smrg
761abf7346Smrgchmodcmd=$chmodprog
771abf7346Smrgchowncmd=
781abf7346Smrgchgrpcmd=
791abf7346Smrgstripcmd=
801abf7346Smrgrmcmd="$rmprog -f"
811abf7346Smrgmvcmd="$mvprog"
821abf7346Smrgsrc=
831abf7346Smrgdst=
841abf7346Smrgdir_arg=
851abf7346Smrgdstarg=
861abf7346Smrgno_target_directory=
871abf7346Smrg
881abf7346Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
891abf7346Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
901abf7346Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
911abf7346Smrg   or: $0 [OPTION]... -d DIRECTORIES...
921abf7346Smrg
931abf7346SmrgIn the 1st form, copy SRCFILE to DSTFILE.
941abf7346SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
951abf7346SmrgIn the 4th, create DIRECTORIES.
961abf7346Smrg
971abf7346SmrgOptions:
981abf7346Smrg-c         (ignored)
991abf7346Smrg-d         create directories instead of installing files.
1001abf7346Smrg-g GROUP   $chgrpprog installed files to GROUP.
1011abf7346Smrg-m MODE    $chmodprog installed files to MODE.
1021abf7346Smrg-o USER    $chownprog installed files to USER.
1031abf7346Smrg-s         $stripprog installed files.
1041abf7346Smrg-t DIRECTORY  install into DIRECTORY.
1051abf7346Smrg-T         report an error if DSTFILE is a directory.
1061abf7346Smrg--help     display this help and exit.
1071abf7346Smrg--version  display version info and exit.
1081abf7346Smrg
1091abf7346SmrgEnvironment variables override the default commands:
1101abf7346Smrg  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
1111abf7346Smrg"
1121abf7346Smrg
1131abf7346Smrgwhile test $# -ne 0; do
1141abf7346Smrg  case $1 in
1151abf7346Smrg    -c) shift
1161abf7346Smrg        continue;;
1171abf7346Smrg
1181abf7346Smrg    -d) dir_arg=true
1191abf7346Smrg        shift
1201abf7346Smrg        continue;;
1211abf7346Smrg
1221abf7346Smrg    -g) chgrpcmd="$chgrpprog $2"
1231abf7346Smrg        shift
1241abf7346Smrg        shift
1251abf7346Smrg        continue;;
1261abf7346Smrg
1271abf7346Smrg    --help) echo "$usage"; exit $?;;
1281abf7346Smrg
1291abf7346Smrg    -m) mode=$2
1301abf7346Smrg        shift
1311abf7346Smrg        shift
1321abf7346Smrg	case $mode in
1331abf7346Smrg	  *' '* | *'	'* | *'
1341abf7346Smrg'*	  | *'*'* | *'?'* | *'['*)
1351abf7346Smrg	    echo "$0: invalid mode: $mode" >&2
1361abf7346Smrg	    exit 1;;
1371abf7346Smrg	esac
1381abf7346Smrg        continue;;
1391abf7346Smrg
1401abf7346Smrg    -o) chowncmd="$chownprog $2"
1411abf7346Smrg        shift
1421abf7346Smrg        shift
1431abf7346Smrg        continue;;
1441abf7346Smrg
1451abf7346Smrg    -s) stripcmd=$stripprog
1461abf7346Smrg        shift
1471abf7346Smrg        continue;;
1481abf7346Smrg
1491abf7346Smrg    -t) dstarg=$2
1501abf7346Smrg	shift
1511abf7346Smrg	shift
1521abf7346Smrg	continue;;
1531abf7346Smrg
1541abf7346Smrg    -T) no_target_directory=true
1551abf7346Smrg	shift
1561abf7346Smrg	continue;;
1571abf7346Smrg
1581abf7346Smrg    --version) echo "$0 $scriptversion"; exit $?;;
1591abf7346Smrg
1601abf7346Smrg    --)	shift
1611abf7346Smrg	break;;
1621abf7346Smrg
1631abf7346Smrg    -*)	echo "$0: invalid option: $1" >&2
1641abf7346Smrg	exit 1;;
1651abf7346Smrg
1661abf7346Smrg    *)  break;;
1671abf7346Smrg  esac
1681abf7346Smrgdone
1691abf7346Smrg
1701abf7346Smrgif test $# -ne 0 && test -z "$dir_arg$dstarg"; then
1711abf7346Smrg  # When -d is used, all remaining arguments are directories to create.
1721abf7346Smrg  # When -t is used, the destination is already specified.
1731abf7346Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1741abf7346Smrg  for arg
1751abf7346Smrg  do
1761abf7346Smrg    if test -n "$dstarg"; then
1771abf7346Smrg      # $@ is not empty: it contains at least $arg.
1781abf7346Smrg      set fnord "$@" "$dstarg"
1791abf7346Smrg      shift # fnord
1801abf7346Smrg    fi
1811abf7346Smrg    shift # arg
1821abf7346Smrg    dstarg=$arg
1831abf7346Smrg  done
1841abf7346Smrgfi
1851abf7346Smrg
1861abf7346Smrgif test $# -eq 0; then
1871abf7346Smrg  if test -z "$dir_arg"; then
1881abf7346Smrg    echo "$0: no input file specified." >&2
1891abf7346Smrg    exit 1
1901abf7346Smrg  fi
1911abf7346Smrg  # It's OK to call `install-sh -d' without argument.
1921abf7346Smrg  # This can happen when creating conditional directories.
1931abf7346Smrg  exit 0
1941abf7346Smrgfi
1951abf7346Smrg
1961abf7346Smrgif test -z "$dir_arg"; then
1971abf7346Smrg  trap '(exit $?); exit' 1 2 13 15
1981abf7346Smrg
1991abf7346Smrg  # Set umask so as not to create temps with too-generous modes.
2001abf7346Smrg  # However, 'strip' requires both read and write access to temps.
2011abf7346Smrg  case $mode in
2021abf7346Smrg    # Optimize common cases.
2031abf7346Smrg    *644) cp_umask=133;;
2041abf7346Smrg    *755) cp_umask=22;;
2051abf7346Smrg
2061abf7346Smrg    *[0-7])
2071abf7346Smrg      if test -z "$stripcmd"; then
2081abf7346Smrg	u_plus_rw=
2091abf7346Smrg      else
2101abf7346Smrg	u_plus_rw='% 200'
2111abf7346Smrg      fi
2121abf7346Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2131abf7346Smrg    *)
2141abf7346Smrg      if test -z "$stripcmd"; then
2151abf7346Smrg	u_plus_rw=
2161abf7346Smrg      else
2171abf7346Smrg	u_plus_rw=,u+rw
2181abf7346Smrg      fi
2191abf7346Smrg      cp_umask=$mode$u_plus_rw;;
2201abf7346Smrg  esac
2211abf7346Smrgfi
2221abf7346Smrg
2231abf7346Smrgfor src
2241abf7346Smrgdo
2251abf7346Smrg  # Protect names starting with `-'.
2261abf7346Smrg  case $src in
2271abf7346Smrg    -*) src=./$src ;;
2281abf7346Smrg  esac
2291abf7346Smrg
2301abf7346Smrg  if test -n "$dir_arg"; then
2311abf7346Smrg    dst=$src
2321abf7346Smrg    dstdir=$dst
2331abf7346Smrg    test -d "$dstdir"
2341abf7346Smrg    dstdir_status=$?
2351abf7346Smrg  else
2361abf7346Smrg
2371abf7346Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2381abf7346Smrg    # might cause directories to be created, which would be especially bad
2391abf7346Smrg    # if $src (and thus $dsttmp) contains '*'.
2401abf7346Smrg    if test ! -f "$src" && test ! -d "$src"; then
2411abf7346Smrg      echo "$0: $src does not exist." >&2
2421abf7346Smrg      exit 1
2431abf7346Smrg    fi
2441abf7346Smrg
2451abf7346Smrg    if test -z "$dstarg"; then
2461abf7346Smrg      echo "$0: no destination specified." >&2
2471abf7346Smrg      exit 1
2481abf7346Smrg    fi
2491abf7346Smrg
2501abf7346Smrg    dst=$dstarg
2511abf7346Smrg    # Protect names starting with `-'.
2521abf7346Smrg    case $dst in
2531abf7346Smrg      -*) dst=./$dst ;;
2541abf7346Smrg    esac
2551abf7346Smrg
2561abf7346Smrg    # If destination is a directory, append the input filename; won't work
2571abf7346Smrg    # if double slashes aren't ignored.
2581abf7346Smrg    if test -d "$dst"; then
2591abf7346Smrg      if test -n "$no_target_directory"; then
2601abf7346Smrg	echo "$0: $dstarg: Is a directory" >&2
2611abf7346Smrg	exit 1
2621abf7346Smrg      fi
2631abf7346Smrg      dstdir=$dst
2641abf7346Smrg      dst=$dstdir/`basename "$src"`
2651abf7346Smrg      dstdir_status=0
2661abf7346Smrg    else
2671abf7346Smrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2681abf7346Smrg      dstdir=`
2691abf7346Smrg	(dirname "$dst") 2>/dev/null ||
2701abf7346Smrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2711abf7346Smrg	     X"$dst" : 'X\(//\)[^/]' \| \
2721abf7346Smrg	     X"$dst" : 'X\(//\)$' \| \
2731abf7346Smrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2741abf7346Smrg	echo X"$dst" |
2751abf7346Smrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2761abf7346Smrg		   s//\1/
2771abf7346Smrg		   q
2781abf7346Smrg		 }
2791abf7346Smrg		 /^X\(\/\/\)[^/].*/{
2801abf7346Smrg		   s//\1/
2811abf7346Smrg		   q
2821abf7346Smrg		 }
2831abf7346Smrg		 /^X\(\/\/\)$/{
2841abf7346Smrg		   s//\1/
2851abf7346Smrg		   q
2861abf7346Smrg		 }
2871abf7346Smrg		 /^X\(\/\).*/{
2881abf7346Smrg		   s//\1/
2891abf7346Smrg		   q
2901abf7346Smrg		 }
2911abf7346Smrg		 s/.*/./; q'
2921abf7346Smrg      `
2931abf7346Smrg
2941abf7346Smrg      test -d "$dstdir"
2951abf7346Smrg      dstdir_status=$?
2961abf7346Smrg    fi
2971abf7346Smrg  fi
2981abf7346Smrg
2991abf7346Smrg  obsolete_mkdir_used=false
3001abf7346Smrg
3011abf7346Smrg  if test $dstdir_status != 0; then
3021abf7346Smrg    case $posix_mkdir in
3031abf7346Smrg      '')
3041abf7346Smrg	# Create intermediate dirs using mode 755 as modified by the umask.
3051abf7346Smrg	# This is like FreeBSD 'install' as of 1997-10-28.
3061abf7346Smrg	umask=`umask`
3071abf7346Smrg	case $stripcmd.$umask in
3081abf7346Smrg	  # Optimize common cases.
3091abf7346Smrg	  *[2367][2367]) mkdir_umask=$umask;;
3101abf7346Smrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3111abf7346Smrg
3121abf7346Smrg	  *[0-7])
3131abf7346Smrg	    mkdir_umask=`expr $umask + 22 \
3141abf7346Smrg	      - $umask % 100 % 40 + $umask % 20 \
3151abf7346Smrg	      - $umask % 10 % 4 + $umask % 2
3161abf7346Smrg	    `;;
3171abf7346Smrg	  *) mkdir_umask=$umask,go-w;;
3181abf7346Smrg	esac
3191abf7346Smrg
3201abf7346Smrg	# With -d, create the new directory with the user-specified mode.
3211abf7346Smrg	# Otherwise, rely on $mkdir_umask.
3221abf7346Smrg	if test -n "$dir_arg"; then
3231abf7346Smrg	  mkdir_mode=-m$mode
3241abf7346Smrg	else
3251abf7346Smrg	  mkdir_mode=
3261abf7346Smrg	fi
3271abf7346Smrg
3281abf7346Smrg	posix_mkdir=false
3291abf7346Smrg	case $umask in
3301abf7346Smrg	  *[123567][0-7][0-7])
3311abf7346Smrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3321abf7346Smrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3331abf7346Smrg	    ;;
3341abf7346Smrg	  *)
3351abf7346Smrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3361abf7346Smrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3371abf7346Smrg
3381abf7346Smrg	    if (umask $mkdir_umask &&
3391abf7346Smrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3401abf7346Smrg	    then
3411abf7346Smrg	      if test -z "$dir_arg" || {
3421abf7346Smrg		   # Check for POSIX incompatibilities with -m.
3431abf7346Smrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3441abf7346Smrg		   # other-writeable bit of parent directory when it shouldn't.
3451abf7346Smrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3461abf7346Smrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3471abf7346Smrg		   case $ls_ld_tmpdir in
3481abf7346Smrg		     d????-?r-*) different_mode=700;;
3491abf7346Smrg		     d????-?--*) different_mode=755;;
3501abf7346Smrg		     *) false;;
3511abf7346Smrg		   esac &&
3521abf7346Smrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3531abf7346Smrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3541abf7346Smrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3551abf7346Smrg		   }
3561abf7346Smrg		 }
3571abf7346Smrg	      then posix_mkdir=:
3581abf7346Smrg	      fi
3591abf7346Smrg	      rmdir "$tmpdir/d" "$tmpdir"
3601abf7346Smrg	    else
3611abf7346Smrg	      # Remove any dirs left behind by ancient mkdir implementations.
3621abf7346Smrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3631abf7346Smrg	    fi
3641abf7346Smrg	    trap '' 0;;
3651abf7346Smrg	esac;;
3661abf7346Smrg    esac
3671abf7346Smrg
3681abf7346Smrg    if
3691abf7346Smrg      $posix_mkdir && (
3701abf7346Smrg	umask $mkdir_umask &&
3711abf7346Smrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3721abf7346Smrg      )
3731abf7346Smrg    then :
3741abf7346Smrg    else
3751abf7346Smrg
3761abf7346Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3771abf7346Smrg      # or it failed possibly due to a race condition.  Create the
3781abf7346Smrg      # directory the slow way, step by step, checking for races as we go.
3791abf7346Smrg
3801abf7346Smrg      case $dstdir in
3811abf7346Smrg	/*) prefix=/ ;;
3821abf7346Smrg	-*) prefix=./ ;;
3831abf7346Smrg	*)  prefix= ;;
3841abf7346Smrg      esac
3851abf7346Smrg
3861abf7346Smrg      case $posix_glob in
3871abf7346Smrg        '')
3881abf7346Smrg	  if (set -f) 2>/dev/null; then
3891abf7346Smrg	    posix_glob=true
3901abf7346Smrg	  else
3911abf7346Smrg	    posix_glob=false
3921abf7346Smrg	  fi ;;
3931abf7346Smrg      esac
3941abf7346Smrg
3951abf7346Smrg      oIFS=$IFS
3961abf7346Smrg      IFS=/
3971abf7346Smrg      $posix_glob && set -f
3981abf7346Smrg      set fnord $dstdir
3991abf7346Smrg      shift
4001abf7346Smrg      $posix_glob && set +f
4011abf7346Smrg      IFS=$oIFS
4021abf7346Smrg
4031abf7346Smrg      prefixes=
4041abf7346Smrg
4051abf7346Smrg      for d
4061abf7346Smrg      do
4071abf7346Smrg	test -z "$d" && continue
4081abf7346Smrg
4091abf7346Smrg	prefix=$prefix$d
4101abf7346Smrg	if test -d "$prefix"; then
4111abf7346Smrg	  prefixes=
4121abf7346Smrg	else
4131abf7346Smrg	  if $posix_mkdir; then
4141abf7346Smrg	    (umask=$mkdir_umask &&
4151abf7346Smrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4161abf7346Smrg	    # Don't fail if two instances are running concurrently.
4171abf7346Smrg	    test -d "$prefix" || exit 1
4181abf7346Smrg	  else
4191abf7346Smrg	    case $prefix in
4201abf7346Smrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4211abf7346Smrg	      *) qprefix=$prefix;;
4221abf7346Smrg	    esac
4231abf7346Smrg	    prefixes="$prefixes '$qprefix'"
4241abf7346Smrg	  fi
4251abf7346Smrg	fi
4261abf7346Smrg	prefix=$prefix/
4271abf7346Smrg      done
4281abf7346Smrg
4291abf7346Smrg      if test -n "$prefixes"; then
4301abf7346Smrg	# Don't fail if two instances are running concurrently.
4311abf7346Smrg	(umask $mkdir_umask &&
4321abf7346Smrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4331abf7346Smrg	  test -d "$dstdir" || exit 1
4341abf7346Smrg	obsolete_mkdir_used=true
4351abf7346Smrg      fi
4361abf7346Smrg    fi
4371abf7346Smrg  fi
4381abf7346Smrg
4391abf7346Smrg  if test -n "$dir_arg"; then
4401abf7346Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4411abf7346Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4421abf7346Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4431abf7346Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4441abf7346Smrg  else
4451abf7346Smrg
4461abf7346Smrg    # Make a couple of temp file names in the proper directory.
4471abf7346Smrg    dsttmp=$dstdir/_inst.$$_
4481abf7346Smrg    rmtmp=$dstdir/_rm.$$_
4491abf7346Smrg
4501abf7346Smrg    # Trap to clean up those temp files at exit.
4511abf7346Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4521abf7346Smrg
4531abf7346Smrg    # Copy the file name to the temp name.
4541abf7346Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4551abf7346Smrg
4561abf7346Smrg    # and set any options; do chmod last to preserve setuid bits.
4571abf7346Smrg    #
4581abf7346Smrg    # If any of these fail, we abort the whole thing.  If we want to
4591abf7346Smrg    # ignore errors from any of these, just make sure not to ignore
4601abf7346Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4611abf7346Smrg    #
4621abf7346Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
4631abf7346Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
4641abf7346Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
4651abf7346Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4661abf7346Smrg
4671abf7346Smrg    # Now rename the file to the real destination.
4681abf7346Smrg    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
4691abf7346Smrg      || {
4701abf7346Smrg	   # The rename failed, perhaps because mv can't rename something else
4711abf7346Smrg	   # to itself, or perhaps because mv is so ancient that it does not
4721abf7346Smrg	   # support -f.
4731abf7346Smrg
4741abf7346Smrg	   # Now remove or move aside any old file at destination location.
4751abf7346Smrg	   # We try this two ways since rm can't unlink itself on some
4761abf7346Smrg	   # systems and the destination file might be busy for other
4771abf7346Smrg	   # reasons.  In this case, the final cleanup might fail but the new
4781abf7346Smrg	   # file should still install successfully.
4791abf7346Smrg	   {
4801abf7346Smrg	     if test -f "$dst"; then
4811abf7346Smrg	       $doit $rmcmd -f "$dst" 2>/dev/null \
4821abf7346Smrg	       || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
4831abf7346Smrg		     && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
4841abf7346Smrg	       || {
4851abf7346Smrg		 echo "$0: cannot unlink or rename $dst" >&2
4861abf7346Smrg		 (exit 1); exit 1
4871abf7346Smrg	       }
4881abf7346Smrg	     else
4891abf7346Smrg	       :
4901abf7346Smrg	     fi
4911abf7346Smrg	   } &&
4921abf7346Smrg
4931abf7346Smrg	   # Now rename the file to the real destination.
4941abf7346Smrg	   $doit $mvcmd "$dsttmp" "$dst"
4951abf7346Smrg	 }
4961abf7346Smrg    } || exit 1
4971abf7346Smrg
4981abf7346Smrg    trap '' 0
4991abf7346Smrg  fi
5001abf7346Smrgdone
5011abf7346Smrg
5021abf7346Smrg# Local variables:
5031abf7346Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
5041abf7346Smrg# time-stamp-start: "scriptversion="
5051abf7346Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5061abf7346Smrg# time-stamp-end: "$"
5071abf7346Smrg# End:
508