install-sh revision 1ae1b5e8
176888252Smrg#!/bin/sh
276888252Smrg# install - install a program, script, or datafile
376888252Smrg
41ae1b5e8Smrgscriptversion=2006-10-14.15
576888252Smrg
676888252Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
776888252Smrg# later released in X11R6 (xc/config/util/install.sh) with the
876888252Smrg# following copyright and license.
976888252Smrg#
1076888252Smrg# Copyright (C) 1994 X Consortium
1176888252Smrg#
1276888252Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1376888252Smrg# of this software and associated documentation files (the "Software"), to
1476888252Smrg# deal in the Software without restriction, including without limitation the
1576888252Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1676888252Smrg# sell copies of the Software, and to permit persons to whom the Software is
1776888252Smrg# furnished to do so, subject to the following conditions:
1876888252Smrg#
1976888252Smrg# The above copyright notice and this permission notice shall be included in
2076888252Smrg# all copies or substantial portions of the Software.
2176888252Smrg#
2276888252Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2376888252Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2476888252Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2576888252Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2676888252Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2776888252Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2876888252Smrg#
2976888252Smrg# Except as contained in this notice, the name of the X Consortium shall not
3076888252Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3176888252Smrg# ings in this Software without prior written authorization from the X Consor-
3276888252Smrg# tium.
3376888252Smrg#
3476888252Smrg#
3576888252Smrg# FSF changes to this file are in the public domain.
3676888252Smrg#
3776888252Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3876888252Smrg# `make' implicit rules from creating a file called install from it
3976888252Smrg# when there is no Makefile.
4076888252Smrg#
4176888252Smrg# This script is compatible with the BSD install script, but was written
421ae1b5e8Smrg# from scratch.
431ae1b5e8Smrg
441ae1b5e8Smrgnl='
451ae1b5e8Smrg'
461ae1b5e8SmrgIFS=" ""	$nl"
4776888252Smrg
4876888252Smrg# set DOITPROG to echo to test this script
4976888252Smrg
5076888252Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
5176888252Smrgdoit="${DOITPROG-}"
521ae1b5e8Smrgif test -z "$doit"; then
531ae1b5e8Smrg  doit_exec=exec
541ae1b5e8Smrgelse
551ae1b5e8Smrg  doit_exec=$doit
561ae1b5e8Smrgfi
5776888252Smrg
581ae1b5e8Smrg# Put in absolute file names if you don't have them in your path;
591ae1b5e8Smrg# or use environment vars.
6076888252Smrg
6176888252Smrgmvprog="${MVPROG-mv}"
6276888252Smrgcpprog="${CPPROG-cp}"
6376888252Smrgchmodprog="${CHMODPROG-chmod}"
6476888252Smrgchownprog="${CHOWNPROG-chown}"
6576888252Smrgchgrpprog="${CHGRPPROG-chgrp}"
6676888252Smrgstripprog="${STRIPPROG-strip}"
6776888252Smrgrmprog="${RMPROG-rm}"
6876888252Smrgmkdirprog="${MKDIRPROG-mkdir}"
6976888252Smrg
701ae1b5e8Smrgposix_glob=
711ae1b5e8Smrgposix_mkdir=
721ae1b5e8Smrg
731ae1b5e8Smrg# Desired mode of installed file.
741ae1b5e8Smrgmode=0755
751ae1b5e8Smrg
761ae1b5e8Smrgchmodcmd=$chmodprog
7776888252Smrgchowncmd=
7876888252Smrgchgrpcmd=
7976888252Smrgstripcmd=
8076888252Smrgrmcmd="$rmprog -f"
8176888252Smrgmvcmd="$mvprog"
8276888252Smrgsrc=
8376888252Smrgdst=
8476888252Smrgdir_arg=
8576888252Smrgdstarg=
8676888252Smrgno_target_directory=
8776888252Smrg
8876888252Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
8976888252Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9076888252Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9176888252Smrg   or: $0 [OPTION]... -d DIRECTORIES...
9276888252Smrg
9376888252SmrgIn the 1st form, copy SRCFILE to DSTFILE.
9476888252SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
9576888252SmrgIn the 4th, create DIRECTORIES.
9676888252Smrg
9776888252SmrgOptions:
9876888252Smrg-c         (ignored)
9976888252Smrg-d         create directories instead of installing files.
10076888252Smrg-g GROUP   $chgrpprog installed files to GROUP.
10176888252Smrg-m MODE    $chmodprog installed files to MODE.
10276888252Smrg-o USER    $chownprog installed files to USER.
10376888252Smrg-s         $stripprog installed files.
10476888252Smrg-t DIRECTORY  install into DIRECTORY.
10576888252Smrg-T         report an error if DSTFILE is a directory.
10676888252Smrg--help     display this help and exit.
10776888252Smrg--version  display version info and exit.
10876888252Smrg
10976888252SmrgEnvironment variables override the default commands:
11076888252Smrg  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
11176888252Smrg"
11276888252Smrg
1131ae1b5e8Smrgwhile test $# -ne 0; do
11476888252Smrg  case $1 in
11576888252Smrg    -c) shift
11676888252Smrg        continue;;
11776888252Smrg
11876888252Smrg    -d) dir_arg=true
11976888252Smrg        shift
12076888252Smrg        continue;;
12176888252Smrg
12276888252Smrg    -g) chgrpcmd="$chgrpprog $2"
12376888252Smrg        shift
12476888252Smrg        shift
12576888252Smrg        continue;;
12676888252Smrg
12776888252Smrg    --help) echo "$usage"; exit $?;;
12876888252Smrg
1291ae1b5e8Smrg    -m) mode=$2
13076888252Smrg        shift
13176888252Smrg        shift
1321ae1b5e8Smrg	case $mode in
1331ae1b5e8Smrg	  *' '* | *'	'* | *'
1341ae1b5e8Smrg'*	  | *'*'* | *'?'* | *'['*)
1351ae1b5e8Smrg	    echo "$0: invalid mode: $mode" >&2
1361ae1b5e8Smrg	    exit 1;;
1371ae1b5e8Smrg	esac
13876888252Smrg        continue;;
13976888252Smrg
14076888252Smrg    -o) chowncmd="$chownprog $2"
14176888252Smrg        shift
14276888252Smrg        shift
14376888252Smrg        continue;;
14476888252Smrg
14576888252Smrg    -s) stripcmd=$stripprog
14676888252Smrg        shift
14776888252Smrg        continue;;
14876888252Smrg
14976888252Smrg    -t) dstarg=$2
15076888252Smrg	shift
15176888252Smrg	shift
15276888252Smrg	continue;;
15376888252Smrg
15476888252Smrg    -T) no_target_directory=true
15576888252Smrg	shift
15676888252Smrg	continue;;
15776888252Smrg
15876888252Smrg    --version) echo "$0 $scriptversion"; exit $?;;
15976888252Smrg
1601ae1b5e8Smrg    --)	shift
16176888252Smrg	break;;
1621ae1b5e8Smrg
1631ae1b5e8Smrg    -*)	echo "$0: invalid option: $1" >&2
1641ae1b5e8Smrg	exit 1;;
1651ae1b5e8Smrg
1661ae1b5e8Smrg    *)  break;;
16776888252Smrg  esac
16876888252Smrgdone
16976888252Smrg
1701ae1b5e8Smrgif test $# -ne 0 && test -z "$dir_arg$dstarg"; then
1711ae1b5e8Smrg  # When -d is used, all remaining arguments are directories to create.
1721ae1b5e8Smrg  # When -t is used, the destination is already specified.
1731ae1b5e8Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1741ae1b5e8Smrg  for arg
1751ae1b5e8Smrg  do
1761ae1b5e8Smrg    if test -n "$dstarg"; then
1771ae1b5e8Smrg      # $@ is not empty: it contains at least $arg.
1781ae1b5e8Smrg      set fnord "$@" "$dstarg"
1791ae1b5e8Smrg      shift # fnord
1801ae1b5e8Smrg    fi
1811ae1b5e8Smrg    shift # arg
1821ae1b5e8Smrg    dstarg=$arg
1831ae1b5e8Smrg  done
1841ae1b5e8Smrgfi
1851ae1b5e8Smrg
1861ae1b5e8Smrgif test $# -eq 0; then
18776888252Smrg  if test -z "$dir_arg"; then
18876888252Smrg    echo "$0: no input file specified." >&2
18976888252Smrg    exit 1
19076888252Smrg  fi
19176888252Smrg  # It's OK to call `install-sh -d' without argument.
19276888252Smrg  # This can happen when creating conditional directories.
19376888252Smrg  exit 0
19476888252Smrgfi
19576888252Smrg
1961ae1b5e8Smrgif test -z "$dir_arg"; then
1971ae1b5e8Smrg  trap '(exit $?); exit' 1 2 13 15
1981ae1b5e8Smrg
1991ae1b5e8Smrg  # Set umask so as not to create temps with too-generous modes.
2001ae1b5e8Smrg  # However, 'strip' requires both read and write access to temps.
2011ae1b5e8Smrg  case $mode in
2021ae1b5e8Smrg    # Optimize common cases.
2031ae1b5e8Smrg    *644) cp_umask=133;;
2041ae1b5e8Smrg    *755) cp_umask=22;;
2051ae1b5e8Smrg
2061ae1b5e8Smrg    *[0-7])
2071ae1b5e8Smrg      if test -z "$stripcmd"; then
2081ae1b5e8Smrg	u_plus_rw=
2091ae1b5e8Smrg      else
2101ae1b5e8Smrg	u_plus_rw='% 200'
2111ae1b5e8Smrg      fi
2121ae1b5e8Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2131ae1b5e8Smrg    *)
2141ae1b5e8Smrg      if test -z "$stripcmd"; then
2151ae1b5e8Smrg	u_plus_rw=
2161ae1b5e8Smrg      else
2171ae1b5e8Smrg	u_plus_rw=,u+rw
2181ae1b5e8Smrg      fi
2191ae1b5e8Smrg      cp_umask=$mode$u_plus_rw;;
2201ae1b5e8Smrg  esac
2211ae1b5e8Smrgfi
2221ae1b5e8Smrg
22376888252Smrgfor src
22476888252Smrgdo
22576888252Smrg  # Protect names starting with `-'.
22676888252Smrg  case $src in
22776888252Smrg    -*) src=./$src ;;
22876888252Smrg  esac
22976888252Smrg
23076888252Smrg  if test -n "$dir_arg"; then
23176888252Smrg    dst=$src
2321ae1b5e8Smrg    dstdir=$dst
2331ae1b5e8Smrg    test -d "$dstdir"
2341ae1b5e8Smrg    dstdir_status=$?
23576888252Smrg  else
2361ae1b5e8Smrg
23776888252Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
23876888252Smrg    # might cause directories to be created, which would be especially bad
23976888252Smrg    # if $src (and thus $dsttmp) contains '*'.
24076888252Smrg    if test ! -f "$src" && test ! -d "$src"; then
24176888252Smrg      echo "$0: $src does not exist." >&2
24276888252Smrg      exit 1
24376888252Smrg    fi
24476888252Smrg
24576888252Smrg    if test -z "$dstarg"; then
24676888252Smrg      echo "$0: no destination specified." >&2
24776888252Smrg      exit 1
24876888252Smrg    fi
24976888252Smrg
25076888252Smrg    dst=$dstarg
25176888252Smrg    # Protect names starting with `-'.
25276888252Smrg    case $dst in
25376888252Smrg      -*) dst=./$dst ;;
25476888252Smrg    esac
25576888252Smrg
25676888252Smrg    # If destination is a directory, append the input filename; won't work
25776888252Smrg    # if double slashes aren't ignored.
25876888252Smrg    if test -d "$dst"; then
25976888252Smrg      if test -n "$no_target_directory"; then
26076888252Smrg	echo "$0: $dstarg: Is a directory" >&2
26176888252Smrg	exit 1
26276888252Smrg      fi
2631ae1b5e8Smrg      dstdir=$dst
2641ae1b5e8Smrg      dst=$dstdir/`basename "$src"`
2651ae1b5e8Smrg      dstdir_status=0
2661ae1b5e8Smrg    else
2671ae1b5e8Smrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2681ae1b5e8Smrg      dstdir=`
2691ae1b5e8Smrg	(dirname "$dst") 2>/dev/null ||
2701ae1b5e8Smrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2711ae1b5e8Smrg	     X"$dst" : 'X\(//\)[^/]' \| \
2721ae1b5e8Smrg	     X"$dst" : 'X\(//\)$' \| \
2731ae1b5e8Smrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2741ae1b5e8Smrg	echo X"$dst" |
2751ae1b5e8Smrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2761ae1b5e8Smrg		   s//\1/
2771ae1b5e8Smrg		   q
2781ae1b5e8Smrg		 }
2791ae1b5e8Smrg		 /^X\(\/\/\)[^/].*/{
2801ae1b5e8Smrg		   s//\1/
2811ae1b5e8Smrg		   q
2821ae1b5e8Smrg		 }
2831ae1b5e8Smrg		 /^X\(\/\/\)$/{
2841ae1b5e8Smrg		   s//\1/
2851ae1b5e8Smrg		   q
2861ae1b5e8Smrg		 }
2871ae1b5e8Smrg		 /^X\(\/\).*/{
2881ae1b5e8Smrg		   s//\1/
2891ae1b5e8Smrg		   q
2901ae1b5e8Smrg		 }
2911ae1b5e8Smrg		 s/.*/./; q'
2921ae1b5e8Smrg      `
2931ae1b5e8Smrg
2941ae1b5e8Smrg      test -d "$dstdir"
2951ae1b5e8Smrg      dstdir_status=$?
29676888252Smrg    fi
29776888252Smrg  fi
29876888252Smrg
2991ae1b5e8Smrg  obsolete_mkdir_used=false
3001ae1b5e8Smrg
3011ae1b5e8Smrg  if test $dstdir_status != 0; then
3021ae1b5e8Smrg    case $posix_mkdir in
3031ae1b5e8Smrg      '')
3041ae1b5e8Smrg	# Create intermediate dirs using mode 755 as modified by the umask.
3051ae1b5e8Smrg	# This is like FreeBSD 'install' as of 1997-10-28.
3061ae1b5e8Smrg	umask=`umask`
3071ae1b5e8Smrg	case $stripcmd.$umask in
3081ae1b5e8Smrg	  # Optimize common cases.
3091ae1b5e8Smrg	  *[2367][2367]) mkdir_umask=$umask;;
3101ae1b5e8Smrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3111ae1b5e8Smrg
3121ae1b5e8Smrg	  *[0-7])
3131ae1b5e8Smrg	    mkdir_umask=`expr $umask + 22 \
3141ae1b5e8Smrg	      - $umask % 100 % 40 + $umask % 20 \
3151ae1b5e8Smrg	      - $umask % 10 % 4 + $umask % 2
3161ae1b5e8Smrg	    `;;
3171ae1b5e8Smrg	  *) mkdir_umask=$umask,go-w;;
3181ae1b5e8Smrg	esac
3191ae1b5e8Smrg
3201ae1b5e8Smrg	# With -d, create the new directory with the user-specified mode.
3211ae1b5e8Smrg	# Otherwise, rely on $mkdir_umask.
3221ae1b5e8Smrg	if test -n "$dir_arg"; then
3231ae1b5e8Smrg	  mkdir_mode=-m$mode
3241ae1b5e8Smrg	else
3251ae1b5e8Smrg	  mkdir_mode=
3261ae1b5e8Smrg	fi
3271ae1b5e8Smrg
3281ae1b5e8Smrg	posix_mkdir=false
3291ae1b5e8Smrg	case $umask in
3301ae1b5e8Smrg	  *[123567][0-7][0-7])
3311ae1b5e8Smrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3321ae1b5e8Smrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3331ae1b5e8Smrg	    ;;
3341ae1b5e8Smrg	  *)
3351ae1b5e8Smrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3361ae1b5e8Smrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3371ae1b5e8Smrg
3381ae1b5e8Smrg	    if (umask $mkdir_umask &&
3391ae1b5e8Smrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3401ae1b5e8Smrg	    then
3411ae1b5e8Smrg	      if test -z "$dir_arg" || {
3421ae1b5e8Smrg		   # Check for POSIX incompatibilities with -m.
3431ae1b5e8Smrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3441ae1b5e8Smrg		   # other-writeable bit of parent directory when it shouldn't.
3451ae1b5e8Smrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3461ae1b5e8Smrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3471ae1b5e8Smrg		   case $ls_ld_tmpdir in
3481ae1b5e8Smrg		     d????-?r-*) different_mode=700;;
3491ae1b5e8Smrg		     d????-?--*) different_mode=755;;
3501ae1b5e8Smrg		     *) false;;
3511ae1b5e8Smrg		   esac &&
3521ae1b5e8Smrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3531ae1b5e8Smrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3541ae1b5e8Smrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3551ae1b5e8Smrg		   }
3561ae1b5e8Smrg		 }
3571ae1b5e8Smrg	      then posix_mkdir=:
3581ae1b5e8Smrg	      fi
3591ae1b5e8Smrg	      rmdir "$tmpdir/d" "$tmpdir"
3601ae1b5e8Smrg	    else
3611ae1b5e8Smrg	      # Remove any dirs left behind by ancient mkdir implementations.
3621ae1b5e8Smrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3631ae1b5e8Smrg	    fi
3641ae1b5e8Smrg	    trap '' 0;;
3651ae1b5e8Smrg	esac;;
3661ae1b5e8Smrg    esac
36776888252Smrg
3681ae1b5e8Smrg    if
3691ae1b5e8Smrg      $posix_mkdir && (
3701ae1b5e8Smrg	umask $mkdir_umask &&
3711ae1b5e8Smrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3721ae1b5e8Smrg      )
3731ae1b5e8Smrg    then :
3741ae1b5e8Smrg    else
37576888252Smrg
3761ae1b5e8Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3771ae1b5e8Smrg      # or it failed possibly due to a race condition.  Create the
3781ae1b5e8Smrg      # directory the slow way, step by step, checking for races as we go.
3791ae1b5e8Smrg
3801ae1b5e8Smrg      case $dstdir in
3811ae1b5e8Smrg	/*) prefix=/ ;;
3821ae1b5e8Smrg	-*) prefix=./ ;;
3831ae1b5e8Smrg	*)  prefix= ;;
3841ae1b5e8Smrg      esac
3851ae1b5e8Smrg
3861ae1b5e8Smrg      case $posix_glob in
3871ae1b5e8Smrg        '')
3881ae1b5e8Smrg	  if (set -f) 2>/dev/null; then
3891ae1b5e8Smrg	    posix_glob=true
3901ae1b5e8Smrg	  else
3911ae1b5e8Smrg	    posix_glob=false
3921ae1b5e8Smrg	  fi ;;
3931ae1b5e8Smrg      esac
3941ae1b5e8Smrg
3951ae1b5e8Smrg      oIFS=$IFS
3961ae1b5e8Smrg      IFS=/
3971ae1b5e8Smrg      $posix_glob && set -f
3981ae1b5e8Smrg      set fnord $dstdir
39976888252Smrg      shift
4001ae1b5e8Smrg      $posix_glob && set +f
4011ae1b5e8Smrg      IFS=$oIFS
4021ae1b5e8Smrg
4031ae1b5e8Smrg      prefixes=
4041ae1b5e8Smrg
4051ae1b5e8Smrg      for d
4061ae1b5e8Smrg      do
4071ae1b5e8Smrg	test -z "$d" && continue
4081ae1b5e8Smrg
4091ae1b5e8Smrg	prefix=$prefix$d
4101ae1b5e8Smrg	if test -d "$prefix"; then
4111ae1b5e8Smrg	  prefixes=
4121ae1b5e8Smrg	else
4131ae1b5e8Smrg	  if $posix_mkdir; then
4141ae1b5e8Smrg	    (umask=$mkdir_umask &&
4151ae1b5e8Smrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4161ae1b5e8Smrg	    # Don't fail if two instances are running concurrently.
4171ae1b5e8Smrg	    test -d "$prefix" || exit 1
4181ae1b5e8Smrg	  else
4191ae1b5e8Smrg	    case $prefix in
4201ae1b5e8Smrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4211ae1b5e8Smrg	      *) qprefix=$prefix;;
4221ae1b5e8Smrg	    esac
4231ae1b5e8Smrg	    prefixes="$prefixes '$qprefix'"
4241ae1b5e8Smrg	  fi
4251ae1b5e8Smrg	fi
4261ae1b5e8Smrg	prefix=$prefix/
4271ae1b5e8Smrg      done
4281ae1b5e8Smrg
4291ae1b5e8Smrg      if test -n "$prefixes"; then
4301ae1b5e8Smrg	# Don't fail if two instances are running concurrently.
4311ae1b5e8Smrg	(umask $mkdir_umask &&
4321ae1b5e8Smrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4331ae1b5e8Smrg	  test -d "$dstdir" || exit 1
4341ae1b5e8Smrg	obsolete_mkdir_used=true
43576888252Smrg      fi
4361ae1b5e8Smrg    fi
43776888252Smrg  fi
43876888252Smrg
43976888252Smrg  if test -n "$dir_arg"; then
4401ae1b5e8Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4411ae1b5e8Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4421ae1b5e8Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4431ae1b5e8Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44476888252Smrg  else
44576888252Smrg
44676888252Smrg    # Make a couple of temp file names in the proper directory.
44776888252Smrg    dsttmp=$dstdir/_inst.$$_
44876888252Smrg    rmtmp=$dstdir/_rm.$$_
44976888252Smrg
45076888252Smrg    # Trap to clean up those temp files at exit.
45176888252Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45276888252Smrg
45376888252Smrg    # Copy the file name to the temp name.
4541ae1b5e8Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
45576888252Smrg
45676888252Smrg    # and set any options; do chmod last to preserve setuid bits.
45776888252Smrg    #
45876888252Smrg    # If any of these fail, we abort the whole thing.  If we want to
45976888252Smrg    # ignore errors from any of these, just make sure not to ignore
46076888252Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
46176888252Smrg    #
46276888252Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
46376888252Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
46476888252Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
4651ae1b5e8Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
46676888252Smrg
46776888252Smrg    # Now rename the file to the real destination.
4681ae1b5e8Smrg    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
46976888252Smrg      || {
47076888252Smrg	   # The rename failed, perhaps because mv can't rename something else
47176888252Smrg	   # to itself, or perhaps because mv is so ancient that it does not
47276888252Smrg	   # support -f.
47376888252Smrg
47476888252Smrg	   # Now remove or move aside any old file at destination location.
47576888252Smrg	   # We try this two ways since rm can't unlink itself on some
47676888252Smrg	   # systems and the destination file might be busy for other
47776888252Smrg	   # reasons.  In this case, the final cleanup might fail but the new
47876888252Smrg	   # file should still install successfully.
47976888252Smrg	   {
4801ae1b5e8Smrg	     if test -f "$dst"; then
4811ae1b5e8Smrg	       $doit $rmcmd -f "$dst" 2>/dev/null \
4821ae1b5e8Smrg	       || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
4831ae1b5e8Smrg		     && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
48476888252Smrg	       || {
4851ae1b5e8Smrg		 echo "$0: cannot unlink or rename $dst" >&2
48676888252Smrg		 (exit 1); exit 1
48776888252Smrg	       }
48876888252Smrg	     else
48976888252Smrg	       :
49076888252Smrg	     fi
49176888252Smrg	   } &&
49276888252Smrg
49376888252Smrg	   # Now rename the file to the real destination.
4941ae1b5e8Smrg	   $doit $mvcmd "$dsttmp" "$dst"
49576888252Smrg	 }
4961ae1b5e8Smrg    } || exit 1
49776888252Smrg
4981ae1b5e8Smrg    trap '' 0
4991ae1b5e8Smrg  fi
5001ae1b5e8Smrgdone
50176888252Smrg
50276888252Smrg# Local variables:
50376888252Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
50476888252Smrg# time-stamp-start: "scriptversion="
50576888252Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
50676888252Smrg# time-stamp-end: "$"
50776888252Smrg# End:
508