install-sh revision 05b261ec
105b261ecSmrg#!/bin/sh
205b261ecSmrg# install - install a program, script, or datafile
305b261ecSmrg
405b261ecSmrgscriptversion=2006-12-25.00
505b261ecSmrg
605b261ecSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
705b261ecSmrg# later released in X11R6 (xc/config/util/install.sh) with the
805b261ecSmrg# following copyright and license.
905b261ecSmrg#
1005b261ecSmrg# Copyright (C) 1994 X Consortium
1105b261ecSmrg#
1205b261ecSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1305b261ecSmrg# of this software and associated documentation files (the "Software"), to
1405b261ecSmrg# deal in the Software without restriction, including without limitation the
1505b261ecSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1605b261ecSmrg# sell copies of the Software, and to permit persons to whom the Software is
1705b261ecSmrg# furnished to do so, subject to the following conditions:
1805b261ecSmrg#
1905b261ecSmrg# The above copyright notice and this permission notice shall be included in
2005b261ecSmrg# all copies or substantial portions of the Software.
2105b261ecSmrg#
2205b261ecSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2305b261ecSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2405b261ecSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2505b261ecSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2605b261ecSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2705b261ecSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2805b261ecSmrg#
2905b261ecSmrg# Except as contained in this notice, the name of the X Consortium shall not
3005b261ecSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
3105b261ecSmrg# ings in this Software without prior written authorization from the X Consor-
3205b261ecSmrg# tium.
3305b261ecSmrg#
3405b261ecSmrg#
3505b261ecSmrg# FSF changes to this file are in the public domain.
3605b261ecSmrg#
3705b261ecSmrg# Calling this script install-sh is preferred over install.sh, to prevent
3805b261ecSmrg# `make' implicit rules from creating a file called install from it
3905b261ecSmrg# when there is no Makefile.
4005b261ecSmrg#
4105b261ecSmrg# This script is compatible with the BSD install script, but was written
4205b261ecSmrg# from scratch.
4305b261ecSmrg
4405b261ecSmrgnl='
4505b261ecSmrg'
4605b261ecSmrgIFS=" ""	$nl"
4705b261ecSmrg
4805b261ecSmrg# set DOITPROG to echo to test this script
4905b261ecSmrg
5005b261ecSmrg# Don't use :- since 4.3BSD and earlier shells don't like it.
5105b261ecSmrgdoit=${DOITPROG-}
5205b261ecSmrgif test -z "$doit"; then
5305b261ecSmrg  doit_exec=exec
5405b261ecSmrgelse
5505b261ecSmrg  doit_exec=$doit
5605b261ecSmrgfi
5705b261ecSmrg
5805b261ecSmrg# Put in absolute file names if you don't have them in your path;
5905b261ecSmrg# or use environment vars.
6005b261ecSmrg
6105b261ecSmrgchgrpprog=${CHGRPPROG-chgrp}
6205b261ecSmrgchmodprog=${CHMODPROG-chmod}
6305b261ecSmrgchownprog=${CHOWNPROG-chown}
6405b261ecSmrgcmpprog=${CMPPROG-cmp}
6505b261ecSmrgcpprog=${CPPROG-cp}
6605b261ecSmrgmkdirprog=${MKDIRPROG-mkdir}
6705b261ecSmrgmvprog=${MVPROG-mv}
6805b261ecSmrgrmprog=${RMPROG-rm}
6905b261ecSmrgstripprog=${STRIPPROG-strip}
7005b261ecSmrg
7105b261ecSmrgposix_glob='?'
7205b261ecSmrginitialize_posix_glob='
7305b261ecSmrg  test "$posix_glob" != "?" || {
7405b261ecSmrg    if (set -f) 2>/dev/null; then
7505b261ecSmrg      posix_glob=
7605b261ecSmrg    else
7705b261ecSmrg      posix_glob=:
7805b261ecSmrg    fi
7905b261ecSmrg  }
8005b261ecSmrg'
8105b261ecSmrg
8205b261ecSmrgposix_mkdir=
8305b261ecSmrg
8405b261ecSmrg# Desired mode of installed file.
8505b261ecSmrgmode=0755
8605b261ecSmrg
8705b261ecSmrgchgrpcmd=
8805b261ecSmrgchmodcmd=$chmodprog
8905b261ecSmrgchowncmd=
9005b261ecSmrgmvcmd=$mvprog
9105b261ecSmrgrmcmd="$rmprog -f"
9205b261ecSmrgstripcmd=
9305b261ecSmrg
9405b261ecSmrgsrc=
9505b261ecSmrgdst=
9605b261ecSmrgdir_arg=
9705b261ecSmrgdst_arg=
9805b261ecSmrg
9905b261ecSmrgcopy_on_change=false
10005b261ecSmrgno_target_directory=
10105b261ecSmrg
10205b261ecSmrgusage="\
10305b261ecSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
10405b261ecSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
10505b261ecSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
10605b261ecSmrg   or: $0 [OPTION]... -d DIRECTORIES...
10705b261ecSmrg
10805b261ecSmrgIn the 1st form, copy SRCFILE to DSTFILE.
10905b261ecSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
11005b261ecSmrgIn the 4th, create DIRECTORIES.
11105b261ecSmrg
11205b261ecSmrgOptions:
11305b261ecSmrg     --help     display this help and exit.
11405b261ecSmrg     --version  display version info and exit.
11505b261ecSmrg
11605b261ecSmrg  -c            (ignored)
11705b261ecSmrg  -C            install only if different (preserve the last data modification time)
11805b261ecSmrg  -d            create directories instead of installing files.
11905b261ecSmrg  -g GROUP      $chgrpprog installed files to GROUP.
12005b261ecSmrg  -m MODE       $chmodprog installed files to MODE.
12105b261ecSmrg  -o USER       $chownprog installed files to USER.
12205b261ecSmrg  -s            $stripprog installed files.
12305b261ecSmrg  -t DIRECTORY  install into DIRECTORY.
12405b261ecSmrg  -T            report an error if DSTFILE is a directory.
12505b261ecSmrg
12605b261ecSmrgEnvironment variables override the default commands:
12705b261ecSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
12805b261ecSmrg  RMPROG STRIPPROG
12905b261ecSmrg"
13005b261ecSmrg
13105b261ecSmrgwhile test $# -ne 0; do
13205b261ecSmrg  case $1 in
13305b261ecSmrg    -c) ;;
13405b261ecSmrg
13505b261ecSmrg    -C) copy_on_change=true;;
13605b261ecSmrg
13705b261ecSmrg    -d) dir_arg=true;;
13805b261ecSmrg
13905b261ecSmrg    -g) chgrpcmd="$chgrpprog $2"
14005b261ecSmrg	shift;;
14105b261ecSmrg
14205b261ecSmrg    --help) echo "$usage"; exit $?;;
14305b261ecSmrg
14405b261ecSmrg    -m) mode=$2
14505b261ecSmrg	case $mode in
14605b261ecSmrg	  *' '* | *'	'* | *'
14705b261ecSmrg'*	  | *'*'* | *'?'* | *'['*)
14805b261ecSmrg	    echo "$0: invalid mode: $mode" >&2
14905b261ecSmrg	    exit 1;;
15005b261ecSmrg	esac
15105b261ecSmrg	shift;;
15205b261ecSmrg
15305b261ecSmrg    -o) chowncmd="$chownprog $2"
15405b261ecSmrg	shift;;
15505b261ecSmrg
15605b261ecSmrg    -s) stripcmd=$stripprog;;
15705b261ecSmrg
15805b261ecSmrg    -t) dst_arg=$2
15905b261ecSmrg	shift;;
16005b261ecSmrg
16105b261ecSmrg    -T) no_target_directory=true;;
16205b261ecSmrg
16305b261ecSmrg    --version) echo "$0 $scriptversion"; exit $?;;
16405b261ecSmrg
16505b261ecSmrg    --)	shift
16605b261ecSmrg	break;;
16705b261ecSmrg
16805b261ecSmrg    -*)	echo "$0: invalid option: $1" >&2
16905b261ecSmrg	exit 1;;
17005b261ecSmrg
17105b261ecSmrg    *)  break;;
17205b261ecSmrg  esac
17305b261ecSmrg  shift
17405b261ecSmrgdone
17505b261ecSmrg
17605b261ecSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
17705b261ecSmrg  # When -d is used, all remaining arguments are directories to create.
17805b261ecSmrg  # When -t is used, the destination is already specified.
17905b261ecSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
18005b261ecSmrg  for arg
18105b261ecSmrg  do
18205b261ecSmrg    if test -n "$dst_arg"; then
18305b261ecSmrg      # $@ is not empty: it contains at least $arg.
18405b261ecSmrg      set fnord "$@" "$dst_arg"
18505b261ecSmrg      shift # fnord
18605b261ecSmrg    fi
18705b261ecSmrg    shift # arg
18805b261ecSmrg    dst_arg=$arg
18905b261ecSmrg  done
19005b261ecSmrgfi
19105b261ecSmrg
19205b261ecSmrgif test $# -eq 0; then
19305b261ecSmrg  if test -z "$dir_arg"; then
19405b261ecSmrg    echo "$0: no input file specified." >&2
19505b261ecSmrg    exit 1
19605b261ecSmrg  fi
19705b261ecSmrg  # It's OK to call `install-sh -d' without argument.
19805b261ecSmrg  # This can happen when creating conditional directories.
19905b261ecSmrg  exit 0
20005b261ecSmrgfi
20105b261ecSmrg
20205b261ecSmrgif test -z "$dir_arg"; then
20305b261ecSmrg  trap '(exit $?); exit' 1 2 13 15
20405b261ecSmrg
20505b261ecSmrg  # Set umask so as not to create temps with too-generous modes.
20605b261ecSmrg  # However, 'strip' requires both read and write access to temps.
20705b261ecSmrg  case $mode in
20805b261ecSmrg    # Optimize common cases.
20905b261ecSmrg    *644) cp_umask=133;;
21005b261ecSmrg    *755) cp_umask=22;;
21105b261ecSmrg
21205b261ecSmrg    *[0-7])
21305b261ecSmrg      if test -z "$stripcmd"; then
21405b261ecSmrg	u_plus_rw=
21505b261ecSmrg      else
21605b261ecSmrg	u_plus_rw='% 200'
21705b261ecSmrg      fi
21805b261ecSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
21905b261ecSmrg    *)
22005b261ecSmrg      if test -z "$stripcmd"; then
22105b261ecSmrg	u_plus_rw=
22205b261ecSmrg      else
22305b261ecSmrg	u_plus_rw=,u+rw
22405b261ecSmrg      fi
22505b261ecSmrg      cp_umask=$mode$u_plus_rw;;
22605b261ecSmrg  esac
22705b261ecSmrgfi
22805b261ecSmrg
22905b261ecSmrgfor src
23005b261ecSmrgdo
23105b261ecSmrg  # Protect names starting with `-'.
23205b261ecSmrg  case $src in
23305b261ecSmrg    -*) src=./$src;;
23405b261ecSmrg  esac
23505b261ecSmrg
23605b261ecSmrg  if test -n "$dir_arg"; then
23705b261ecSmrg    dst=$src
23805b261ecSmrg    dstdir=$dst
23905b261ecSmrg    test -d "$dstdir"
24005b261ecSmrg    dstdir_status=$?
24105b261ecSmrg  else
24205b261ecSmrg
24305b261ecSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
24405b261ecSmrg    # might cause directories to be created, which would be especially bad
24505b261ecSmrg    # if $src (and thus $dsttmp) contains '*'.
24605b261ecSmrg    if test ! -f "$src" && test ! -d "$src"; then
24705b261ecSmrg      echo "$0: $src does not exist." >&2
24805b261ecSmrg      exit 1
24905b261ecSmrg    fi
25005b261ecSmrg
25105b261ecSmrg    if test -z "$dst_arg"; then
25205b261ecSmrg      echo "$0: no destination specified." >&2
25305b261ecSmrg      exit 1
25405b261ecSmrg    fi
25505b261ecSmrg
25605b261ecSmrg    dst=$dst_arg
25705b261ecSmrg    # Protect names starting with `-'.
25805b261ecSmrg    case $dst in
25905b261ecSmrg      -*) dst=./$dst;;
26005b261ecSmrg    esac
26105b261ecSmrg
26205b261ecSmrg    # If destination is a directory, append the input filename; won't work
26305b261ecSmrg    # if double slashes aren't ignored.
26405b261ecSmrg    if test -d "$dst"; then
26505b261ecSmrg      if test -n "$no_target_directory"; then
26605b261ecSmrg	echo "$0: $dst_arg: Is a directory" >&2
26705b261ecSmrg	exit 1
26805b261ecSmrg      fi
26905b261ecSmrg      dstdir=$dst
27005b261ecSmrg      dst=$dstdir/`basename "$src"`
27105b261ecSmrg      dstdir_status=0
27205b261ecSmrg    else
27305b261ecSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
27405b261ecSmrg      dstdir=`
27505b261ecSmrg	(dirname "$dst") 2>/dev/null ||
27605b261ecSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
27705b261ecSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
27805b261ecSmrg	     X"$dst" : 'X\(//\)$' \| \
27905b261ecSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
28005b261ecSmrg	echo X"$dst" |
28105b261ecSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
28205b261ecSmrg		   s//\1/
28305b261ecSmrg		   q
28405b261ecSmrg		 }
28505b261ecSmrg		 /^X\(\/\/\)[^/].*/{
28605b261ecSmrg		   s//\1/
28705b261ecSmrg		   q
28805b261ecSmrg		 }
28905b261ecSmrg		 /^X\(\/\/\)$/{
29005b261ecSmrg		   s//\1/
29105b261ecSmrg		   q
29205b261ecSmrg		 }
29305b261ecSmrg		 /^X\(\/\).*/{
29405b261ecSmrg		   s//\1/
29505b261ecSmrg		   q
29605b261ecSmrg		 }
29705b261ecSmrg		 s/.*/./; q'
29805b261ecSmrg      `
29905b261ecSmrg
30005b261ecSmrg      test -d "$dstdir"
30105b261ecSmrg      dstdir_status=$?
30205b261ecSmrg    fi
30305b261ecSmrg  fi
30405b261ecSmrg
30505b261ecSmrg  obsolete_mkdir_used=false
30605b261ecSmrg
30705b261ecSmrg  if test $dstdir_status != 0; then
30805b261ecSmrg    case $posix_mkdir in
30905b261ecSmrg      '')
31005b261ecSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
31105b261ecSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
31205b261ecSmrg	umask=`umask`
31305b261ecSmrg	case $stripcmd.$umask in
31405b261ecSmrg	  # Optimize common cases.
31505b261ecSmrg	  *[2367][2367]) mkdir_umask=$umask;;
31605b261ecSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
31705b261ecSmrg
31805b261ecSmrg	  *[0-7])
31905b261ecSmrg	    mkdir_umask=`expr $umask + 22 \
32005b261ecSmrg	      - $umask % 100 % 40 + $umask % 20 \
32105b261ecSmrg	      - $umask % 10 % 4 + $umask % 2
32205b261ecSmrg	    `;;
32305b261ecSmrg	  *) mkdir_umask=$umask,go-w;;
32405b261ecSmrg	esac
32505b261ecSmrg
32605b261ecSmrg	# With -d, create the new directory with the user-specified mode.
32705b261ecSmrg	# Otherwise, rely on $mkdir_umask.
32805b261ecSmrg	if test -n "$dir_arg"; then
32905b261ecSmrg	  mkdir_mode=-m$mode
33005b261ecSmrg	else
33105b261ecSmrg	  mkdir_mode=
33205b261ecSmrg	fi
33305b261ecSmrg
33405b261ecSmrg	posix_mkdir=false
33505b261ecSmrg	case $umask in
33605b261ecSmrg	  *[123567][0-7][0-7])
33705b261ecSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
33805b261ecSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
33905b261ecSmrg	    ;;
34005b261ecSmrg	  *)
34105b261ecSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34205b261ecSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
34305b261ecSmrg
34405b261ecSmrg	    if (umask $mkdir_umask &&
34505b261ecSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
34605b261ecSmrg	    then
34705b261ecSmrg	      if test -z "$dir_arg" || {
34805b261ecSmrg		   # Check for POSIX incompatibilities with -m.
34905b261ecSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35005b261ecSmrg		   # other-writeable bit of parent directory when it shouldn't.
35105b261ecSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
35205b261ecSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
35305b261ecSmrg		   case $ls_ld_tmpdir in
35405b261ecSmrg		     d????-?r-*) different_mode=700;;
35505b261ecSmrg		     d????-?--*) different_mode=755;;
35605b261ecSmrg		     *) false;;
35705b261ecSmrg		   esac &&
35805b261ecSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
35905b261ecSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
36005b261ecSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
36105b261ecSmrg		   }
36205b261ecSmrg		 }
36305b261ecSmrg	      then posix_mkdir=:
36405b261ecSmrg	      fi
36505b261ecSmrg	      rmdir "$tmpdir/d" "$tmpdir"
36605b261ecSmrg	    else
36705b261ecSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
36805b261ecSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
36905b261ecSmrg	    fi
37005b261ecSmrg	    trap '' 0;;
37105b261ecSmrg	esac;;
37205b261ecSmrg    esac
37305b261ecSmrg
37405b261ecSmrg    if
37505b261ecSmrg      $posix_mkdir && (
37605b261ecSmrg	umask $mkdir_umask &&
37705b261ecSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
37805b261ecSmrg      )
37905b261ecSmrg    then :
38005b261ecSmrg    else
38105b261ecSmrg
38205b261ecSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
38305b261ecSmrg      # or it failed possibly due to a race condition.  Create the
38405b261ecSmrg      # directory the slow way, step by step, checking for races as we go.
38505b261ecSmrg
38605b261ecSmrg      case $dstdir in
38705b261ecSmrg	/*) prefix='/';;
38805b261ecSmrg	-*) prefix='./';;
38905b261ecSmrg	*)  prefix='';;
39005b261ecSmrg      esac
39105b261ecSmrg
39205b261ecSmrg      eval "$initialize_posix_glob"
39305b261ecSmrg
39405b261ecSmrg      oIFS=$IFS
39505b261ecSmrg      IFS=/
39605b261ecSmrg      $posix_glob set -f
39705b261ecSmrg      set fnord $dstdir
39805b261ecSmrg      shift
39905b261ecSmrg      $posix_glob set +f
40005b261ecSmrg      IFS=$oIFS
40105b261ecSmrg
40205b261ecSmrg      prefixes=
40305b261ecSmrg
40405b261ecSmrg      for d
40505b261ecSmrg      do
40605b261ecSmrg	test -z "$d" && continue
40705b261ecSmrg
40805b261ecSmrg	prefix=$prefix$d
40905b261ecSmrg	if test -d "$prefix"; then
41005b261ecSmrg	  prefixes=
41105b261ecSmrg	else
41205b261ecSmrg	  if $posix_mkdir; then
41305b261ecSmrg	    (umask=$mkdir_umask &&
41405b261ecSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
41505b261ecSmrg	    # Don't fail if two instances are running concurrently.
41605b261ecSmrg	    test -d "$prefix" || exit 1
41705b261ecSmrg	  else
41805b261ecSmrg	    case $prefix in
41905b261ecSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42005b261ecSmrg	      *) qprefix=$prefix;;
42105b261ecSmrg	    esac
42205b261ecSmrg	    prefixes="$prefixes '$qprefix'"
42305b261ecSmrg	  fi
42405b261ecSmrg	fi
42505b261ecSmrg	prefix=$prefix/
42605b261ecSmrg      done
42705b261ecSmrg
42805b261ecSmrg      if test -n "$prefixes"; then
42905b261ecSmrg	# Don't fail if two instances are running concurrently.
43005b261ecSmrg	(umask $mkdir_umask &&
43105b261ecSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
43205b261ecSmrg	  test -d "$dstdir" || exit 1
43305b261ecSmrg	obsolete_mkdir_used=true
43405b261ecSmrg      fi
43505b261ecSmrg    fi
43605b261ecSmrg  fi
43705b261ecSmrg
43805b261ecSmrg  if test -n "$dir_arg"; then
43905b261ecSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
44005b261ecSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
44105b261ecSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
44205b261ecSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44305b261ecSmrg  else
44405b261ecSmrg
44505b261ecSmrg    # Make a couple of temp file names in the proper directory.
44605b261ecSmrg    dsttmp=$dstdir/_inst.$$_
44705b261ecSmrg    rmtmp=$dstdir/_rm.$$_
44805b261ecSmrg
44905b261ecSmrg    # Trap to clean up those temp files at exit.
45005b261ecSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45105b261ecSmrg
45205b261ecSmrg    # Copy the file name to the temp name.
45305b261ecSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
45405b261ecSmrg
45505b261ecSmrg    # and set any options; do chmod last to preserve setuid bits.
45605b261ecSmrg    #
45705b261ecSmrg    # If any of these fail, we abort the whole thing.  If we want to
45805b261ecSmrg    # ignore errors from any of these, just make sure not to ignore
45905b261ecSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
46005b261ecSmrg    #
46105b261ecSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
46205b261ecSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
46305b261ecSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
46405b261ecSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
46505b261ecSmrg
46605b261ecSmrg    # If -C, don't bother to copy if it wouldn't change the file.
46705b261ecSmrg    if $copy_on_change &&
46805b261ecSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
46905b261ecSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
47005b261ecSmrg
47105b261ecSmrg       eval "$initialize_posix_glob" &&
47205b261ecSmrg       $posix_glob set -f &&
47305b261ecSmrg       set X $old && old=:$2:$4:$5:$6 &&
47405b261ecSmrg       set X $new && new=:$2:$4:$5:$6 &&
47505b261ecSmrg       $posix_glob set +f &&
47605b261ecSmrg
47705b261ecSmrg       test "$old" = "$new" &&
47805b261ecSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
47905b261ecSmrg    then
48005b261ecSmrg      rm -f "$dsttmp"
48105b261ecSmrg    else
48205b261ecSmrg      # Rename the file to the real destination.
48305b261ecSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
48405b261ecSmrg
48505b261ecSmrg      # The rename failed, perhaps because mv can't rename something else
48605b261ecSmrg      # to itself, or perhaps because mv is so ancient that it does not
48705b261ecSmrg      # support -f.
48805b261ecSmrg      {
48905b261ecSmrg	# Now remove or move aside any old file at destination location.
49005b261ecSmrg	# We try this two ways since rm can't unlink itself on some
49105b261ecSmrg	# systems and the destination file might be busy for other
49205b261ecSmrg	# reasons.  In this case, the final cleanup might fail but the new
49305b261ecSmrg	# file should still install successfully.
49405b261ecSmrg	{
49505b261ecSmrg	  test ! -f "$dst" ||
49605b261ecSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
49705b261ecSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
49805b261ecSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
49905b261ecSmrg	  } ||
50005b261ecSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
50105b261ecSmrg	    (exit 1); exit 1
50205b261ecSmrg	  }
50305b261ecSmrg	} &&
50405b261ecSmrg
50505b261ecSmrg	# Now rename the file to the real destination.
50605b261ecSmrg	$doit $mvcmd "$dsttmp" "$dst"
50705b261ecSmrg      }
50805b261ecSmrg    fi || exit 1
50905b261ecSmrg
51005b261ecSmrg    trap '' 0
51105b261ecSmrg  fi
51205b261ecSmrgdone
51305b261ecSmrg
51405b261ecSmrg# Local variables:
51505b261ecSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
51605b261ecSmrg# time-stamp-start: "scriptversion="
51705b261ecSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
51805b261ecSmrg# time-stamp-end: "$"
51905b261ecSmrg# End:
520