install-sh revision 7965d9ac
150806d53Smrg#!/bin/sh
250806d53Smrg# install - install a program, script, or datafile
350806d53Smrg
47965d9acSmrgscriptversion=2006-12-25.00
550806d53Smrg
650806d53Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
750806d53Smrg# later released in X11R6 (xc/config/util/install.sh) with the
850806d53Smrg# following copyright and license.
950806d53Smrg#
1050806d53Smrg# Copyright (C) 1994 X Consortium
1150806d53Smrg#
1250806d53Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1350806d53Smrg# of this software and associated documentation files (the "Software"), to
1450806d53Smrg# deal in the Software without restriction, including without limitation the
1550806d53Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1650806d53Smrg# sell copies of the Software, and to permit persons to whom the Software is
1750806d53Smrg# furnished to do so, subject to the following conditions:
1850806d53Smrg#
1950806d53Smrg# The above copyright notice and this permission notice shall be included in
2050806d53Smrg# all copies or substantial portions of the Software.
2150806d53Smrg#
2250806d53Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2350806d53Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2450806d53Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2550806d53Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2650806d53Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2750806d53Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2850806d53Smrg#
2950806d53Smrg# Except as contained in this notice, the name of the X Consortium shall not
3050806d53Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3150806d53Smrg# ings in this Software without prior written authorization from the X Consor-
3250806d53Smrg# tium.
3350806d53Smrg#
3450806d53Smrg#
3550806d53Smrg# FSF changes to this file are in the public domain.
3650806d53Smrg#
3750806d53Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3850806d53Smrg# `make' implicit rules from creating a file called install from it
3950806d53Smrg# when there is no Makefile.
4050806d53Smrg#
4150806d53Smrg# This script is compatible with the BSD install script, but was written
427965d9acSmrg# from scratch.
437965d9acSmrg
447965d9acSmrgnl='
457965d9acSmrg'
467965d9acSmrgIFS=" ""	$nl"
4750806d53Smrg
4850806d53Smrg# set DOITPROG to echo to test this script
4950806d53Smrg
5050806d53Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
517965d9acSmrgdoit=${DOITPROG-}
527965d9acSmrgif test -z "$doit"; then
537965d9acSmrg  doit_exec=exec
547965d9acSmrgelse
557965d9acSmrg  doit_exec=$doit
567965d9acSmrgfi
5750806d53Smrg
587965d9acSmrg# Put in absolute file names if you don't have them in your path;
597965d9acSmrg# or use environment vars.
607965d9acSmrg
617965d9acSmrgchgrpprog=${CHGRPPROG-chgrp}
627965d9acSmrgchmodprog=${CHMODPROG-chmod}
637965d9acSmrgchownprog=${CHOWNPROG-chown}
647965d9acSmrgcmpprog=${CMPPROG-cmp}
657965d9acSmrgcpprog=${CPPROG-cp}
667965d9acSmrgmkdirprog=${MKDIRPROG-mkdir}
677965d9acSmrgmvprog=${MVPROG-mv}
687965d9acSmrgrmprog=${RMPROG-rm}
697965d9acSmrgstripprog=${STRIPPROG-strip}
707965d9acSmrg
717965d9acSmrgposix_glob='?'
727965d9acSmrginitialize_posix_glob='
737965d9acSmrg  test "$posix_glob" != "?" || {
747965d9acSmrg    if (set -f) 2>/dev/null; then
757965d9acSmrg      posix_glob=
767965d9acSmrg    else
777965d9acSmrg      posix_glob=:
787965d9acSmrg    fi
797965d9acSmrg  }
807965d9acSmrg'
8150806d53Smrg
827965d9acSmrgposix_mkdir=
837965d9acSmrg
847965d9acSmrg# Desired mode of installed file.
857965d9acSmrgmode=0755
8650806d53Smrg
8750806d53Smrgchgrpcmd=
887965d9acSmrgchmodcmd=$chmodprog
897965d9acSmrgchowncmd=
907965d9acSmrgmvcmd=$mvprog
9150806d53Smrgrmcmd="$rmprog -f"
927965d9acSmrgstripcmd=
937965d9acSmrg
9450806d53Smrgsrc=
9550806d53Smrgdst=
9650806d53Smrgdir_arg=
977965d9acSmrgdst_arg=
987965d9acSmrg
997965d9acSmrgcopy_on_change=false
10050806d53Smrgno_target_directory=
10150806d53Smrg
1027965d9acSmrgusage="\
1037965d9acSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
10450806d53Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
10550806d53Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
10650806d53Smrg   or: $0 [OPTION]... -d DIRECTORIES...
10750806d53Smrg
10850806d53SmrgIn the 1st form, copy SRCFILE to DSTFILE.
10950806d53SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
11050806d53SmrgIn the 4th, create DIRECTORIES.
11150806d53Smrg
11250806d53SmrgOptions:
1137965d9acSmrg     --help     display this help and exit.
1147965d9acSmrg     --version  display version info and exit.
1157965d9acSmrg
1167965d9acSmrg  -c            (ignored)
1177965d9acSmrg  -C            install only if different (preserve the last data modification time)
1187965d9acSmrg  -d            create directories instead of installing files.
1197965d9acSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1207965d9acSmrg  -m MODE       $chmodprog installed files to MODE.
1217965d9acSmrg  -o USER       $chownprog installed files to USER.
1227965d9acSmrg  -s            $stripprog installed files.
1237965d9acSmrg  -t DIRECTORY  install into DIRECTORY.
1247965d9acSmrg  -T            report an error if DSTFILE is a directory.
12550806d53Smrg
12650806d53SmrgEnvironment variables override the default commands:
1277965d9acSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1287965d9acSmrg  RMPROG STRIPPROG
12950806d53Smrg"
13050806d53Smrg
1317965d9acSmrgwhile test $# -ne 0; do
13250806d53Smrg  case $1 in
1337965d9acSmrg    -c) ;;
1347965d9acSmrg
1357965d9acSmrg    -C) copy_on_change=true;;
13650806d53Smrg
1377965d9acSmrg    -d) dir_arg=true;;
13850806d53Smrg
13950806d53Smrg    -g) chgrpcmd="$chgrpprog $2"
1407965d9acSmrg	shift;;
14150806d53Smrg
14250806d53Smrg    --help) echo "$usage"; exit $?;;
14350806d53Smrg
1447965d9acSmrg    -m) mode=$2
1457965d9acSmrg	case $mode in
1467965d9acSmrg	  *' '* | *'	'* | *'
1477965d9acSmrg'*	  | *'*'* | *'?'* | *'['*)
1487965d9acSmrg	    echo "$0: invalid mode: $mode" >&2
1497965d9acSmrg	    exit 1;;
1507965d9acSmrg	esac
1517965d9acSmrg	shift;;
15250806d53Smrg
15350806d53Smrg    -o) chowncmd="$chownprog $2"
1547965d9acSmrg	shift;;
15550806d53Smrg
1567965d9acSmrg    -s) stripcmd=$stripprog;;
15750806d53Smrg
1587965d9acSmrg    -t) dst_arg=$2
1597965d9acSmrg	shift;;
16050806d53Smrg
1617965d9acSmrg    -T) no_target_directory=true;;
16250806d53Smrg
16350806d53Smrg    --version) echo "$0 $scriptversion"; exit $?;;
16450806d53Smrg
1657965d9acSmrg    --)	shift
16650806d53Smrg	break;;
1677965d9acSmrg
1687965d9acSmrg    -*)	echo "$0: invalid option: $1" >&2
1697965d9acSmrg	exit 1;;
1707965d9acSmrg
1717965d9acSmrg    *)  break;;
17250806d53Smrg  esac
1737965d9acSmrg  shift
17450806d53Smrgdone
17550806d53Smrg
1767965d9acSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1777965d9acSmrg  # When -d is used, all remaining arguments are directories to create.
1787965d9acSmrg  # When -t is used, the destination is already specified.
1797965d9acSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1807965d9acSmrg  for arg
1817965d9acSmrg  do
1827965d9acSmrg    if test -n "$dst_arg"; then
1837965d9acSmrg      # $@ is not empty: it contains at least $arg.
1847965d9acSmrg      set fnord "$@" "$dst_arg"
1857965d9acSmrg      shift # fnord
1867965d9acSmrg    fi
1877965d9acSmrg    shift # arg
1887965d9acSmrg    dst_arg=$arg
1897965d9acSmrg  done
1907965d9acSmrgfi
1917965d9acSmrg
1927965d9acSmrgif test $# -eq 0; then
19350806d53Smrg  if test -z "$dir_arg"; then
19450806d53Smrg    echo "$0: no input file specified." >&2
19550806d53Smrg    exit 1
19650806d53Smrg  fi
19750806d53Smrg  # It's OK to call `install-sh -d' without argument.
19850806d53Smrg  # This can happen when creating conditional directories.
19950806d53Smrg  exit 0
20050806d53Smrgfi
20150806d53Smrg
2027965d9acSmrgif test -z "$dir_arg"; then
2037965d9acSmrg  trap '(exit $?); exit' 1 2 13 15
2047965d9acSmrg
2057965d9acSmrg  # Set umask so as not to create temps with too-generous modes.
2067965d9acSmrg  # However, 'strip' requires both read and write access to temps.
2077965d9acSmrg  case $mode in
2087965d9acSmrg    # Optimize common cases.
2097965d9acSmrg    *644) cp_umask=133;;
2107965d9acSmrg    *755) cp_umask=22;;
2117965d9acSmrg
2127965d9acSmrg    *[0-7])
2137965d9acSmrg      if test -z "$stripcmd"; then
2147965d9acSmrg	u_plus_rw=
2157965d9acSmrg      else
2167965d9acSmrg	u_plus_rw='% 200'
2177965d9acSmrg      fi
2187965d9acSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2197965d9acSmrg    *)
2207965d9acSmrg      if test -z "$stripcmd"; then
2217965d9acSmrg	u_plus_rw=
2227965d9acSmrg      else
2237965d9acSmrg	u_plus_rw=,u+rw
2247965d9acSmrg      fi
2257965d9acSmrg      cp_umask=$mode$u_plus_rw;;
2267965d9acSmrg  esac
2277965d9acSmrgfi
2287965d9acSmrg
22950806d53Smrgfor src
23050806d53Smrgdo
23150806d53Smrg  # Protect names starting with `-'.
23250806d53Smrg  case $src in
2337965d9acSmrg    -*) src=./$src;;
23450806d53Smrg  esac
23550806d53Smrg
23650806d53Smrg  if test -n "$dir_arg"; then
23750806d53Smrg    dst=$src
2387965d9acSmrg    dstdir=$dst
2397965d9acSmrg    test -d "$dstdir"
2407965d9acSmrg    dstdir_status=$?
24150806d53Smrg  else
2427965d9acSmrg
24350806d53Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
24450806d53Smrg    # might cause directories to be created, which would be especially bad
24550806d53Smrg    # if $src (and thus $dsttmp) contains '*'.
24650806d53Smrg    if test ! -f "$src" && test ! -d "$src"; then
24750806d53Smrg      echo "$0: $src does not exist." >&2
24850806d53Smrg      exit 1
24950806d53Smrg    fi
25050806d53Smrg
2517965d9acSmrg    if test -z "$dst_arg"; then
25250806d53Smrg      echo "$0: no destination specified." >&2
25350806d53Smrg      exit 1
25450806d53Smrg    fi
25550806d53Smrg
2567965d9acSmrg    dst=$dst_arg
25750806d53Smrg    # Protect names starting with `-'.
25850806d53Smrg    case $dst in
2597965d9acSmrg      -*) dst=./$dst;;
26050806d53Smrg    esac
26150806d53Smrg
26250806d53Smrg    # If destination is a directory, append the input filename; won't work
26350806d53Smrg    # if double slashes aren't ignored.
26450806d53Smrg    if test -d "$dst"; then
26550806d53Smrg      if test -n "$no_target_directory"; then
2667965d9acSmrg	echo "$0: $dst_arg: Is a directory" >&2
26750806d53Smrg	exit 1
26850806d53Smrg      fi
2697965d9acSmrg      dstdir=$dst
2707965d9acSmrg      dst=$dstdir/`basename "$src"`
2717965d9acSmrg      dstdir_status=0
2727965d9acSmrg    else
2737965d9acSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2747965d9acSmrg      dstdir=`
2757965d9acSmrg	(dirname "$dst") 2>/dev/null ||
2767965d9acSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2777965d9acSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
2787965d9acSmrg	     X"$dst" : 'X\(//\)$' \| \
2797965d9acSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2807965d9acSmrg	echo X"$dst" |
2817965d9acSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2827965d9acSmrg		   s//\1/
2837965d9acSmrg		   q
2847965d9acSmrg		 }
2857965d9acSmrg		 /^X\(\/\/\)[^/].*/{
2867965d9acSmrg		   s//\1/
2877965d9acSmrg		   q
2887965d9acSmrg		 }
2897965d9acSmrg		 /^X\(\/\/\)$/{
2907965d9acSmrg		   s//\1/
2917965d9acSmrg		   q
2927965d9acSmrg		 }
2937965d9acSmrg		 /^X\(\/\).*/{
2947965d9acSmrg		   s//\1/
2957965d9acSmrg		   q
2967965d9acSmrg		 }
2977965d9acSmrg		 s/.*/./; q'
2987965d9acSmrg      `
2997965d9acSmrg
3007965d9acSmrg      test -d "$dstdir"
3017965d9acSmrg      dstdir_status=$?
30250806d53Smrg    fi
30350806d53Smrg  fi
30450806d53Smrg
3057965d9acSmrg  obsolete_mkdir_used=false
3067965d9acSmrg
3077965d9acSmrg  if test $dstdir_status != 0; then
3087965d9acSmrg    case $posix_mkdir in
3097965d9acSmrg      '')
3107965d9acSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
3117965d9acSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
3127965d9acSmrg	umask=`umask`
3137965d9acSmrg	case $stripcmd.$umask in
3147965d9acSmrg	  # Optimize common cases.
3157965d9acSmrg	  *[2367][2367]) mkdir_umask=$umask;;
3167965d9acSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3177965d9acSmrg
3187965d9acSmrg	  *[0-7])
3197965d9acSmrg	    mkdir_umask=`expr $umask + 22 \
3207965d9acSmrg	      - $umask % 100 % 40 + $umask % 20 \
3217965d9acSmrg	      - $umask % 10 % 4 + $umask % 2
3227965d9acSmrg	    `;;
3237965d9acSmrg	  *) mkdir_umask=$umask,go-w;;
3247965d9acSmrg	esac
3257965d9acSmrg
3267965d9acSmrg	# With -d, create the new directory with the user-specified mode.
3277965d9acSmrg	# Otherwise, rely on $mkdir_umask.
3287965d9acSmrg	if test -n "$dir_arg"; then
3297965d9acSmrg	  mkdir_mode=-m$mode
3307965d9acSmrg	else
3317965d9acSmrg	  mkdir_mode=
3327965d9acSmrg	fi
3337965d9acSmrg
3347965d9acSmrg	posix_mkdir=false
3357965d9acSmrg	case $umask in
3367965d9acSmrg	  *[123567][0-7][0-7])
3377965d9acSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3387965d9acSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3397965d9acSmrg	    ;;
3407965d9acSmrg	  *)
3417965d9acSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3427965d9acSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3437965d9acSmrg
3447965d9acSmrg	    if (umask $mkdir_umask &&
3457965d9acSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3467965d9acSmrg	    then
3477965d9acSmrg	      if test -z "$dir_arg" || {
3487965d9acSmrg		   # Check for POSIX incompatibilities with -m.
3497965d9acSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3507965d9acSmrg		   # other-writeable bit of parent directory when it shouldn't.
3517965d9acSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3527965d9acSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3537965d9acSmrg		   case $ls_ld_tmpdir in
3547965d9acSmrg		     d????-?r-*) different_mode=700;;
3557965d9acSmrg		     d????-?--*) different_mode=755;;
3567965d9acSmrg		     *) false;;
3577965d9acSmrg		   esac &&
3587965d9acSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3597965d9acSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3607965d9acSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3617965d9acSmrg		   }
3627965d9acSmrg		 }
3637965d9acSmrg	      then posix_mkdir=:
3647965d9acSmrg	      fi
3657965d9acSmrg	      rmdir "$tmpdir/d" "$tmpdir"
3667965d9acSmrg	    else
3677965d9acSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
3687965d9acSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3697965d9acSmrg	    fi
3707965d9acSmrg	    trap '' 0;;
3717965d9acSmrg	esac;;
3727965d9acSmrg    esac
37350806d53Smrg
3747965d9acSmrg    if
3757965d9acSmrg      $posix_mkdir && (
3767965d9acSmrg	umask $mkdir_umask &&
3777965d9acSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3787965d9acSmrg      )
3797965d9acSmrg    then :
3807965d9acSmrg    else
38150806d53Smrg
3827965d9acSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3837965d9acSmrg      # or it failed possibly due to a race condition.  Create the
3847965d9acSmrg      # directory the slow way, step by step, checking for races as we go.
38550806d53Smrg
3867965d9acSmrg      case $dstdir in
3877965d9acSmrg	/*) prefix='/';;
3887965d9acSmrg	-*) prefix='./';;
3897965d9acSmrg	*)  prefix='';;
3907965d9acSmrg      esac
39150806d53Smrg
3927965d9acSmrg      eval "$initialize_posix_glob"
39350806d53Smrg
3947965d9acSmrg      oIFS=$IFS
3957965d9acSmrg      IFS=/
3967965d9acSmrg      $posix_glob set -f
3977965d9acSmrg      set fnord $dstdir
39850806d53Smrg      shift
3997965d9acSmrg      $posix_glob set +f
4007965d9acSmrg      IFS=$oIFS
4017965d9acSmrg
4027965d9acSmrg      prefixes=
4037965d9acSmrg
4047965d9acSmrg      for d
4057965d9acSmrg      do
4067965d9acSmrg	test -z "$d" && continue
4077965d9acSmrg
4087965d9acSmrg	prefix=$prefix$d
4097965d9acSmrg	if test -d "$prefix"; then
4107965d9acSmrg	  prefixes=
4117965d9acSmrg	else
4127965d9acSmrg	  if $posix_mkdir; then
4137965d9acSmrg	    (umask=$mkdir_umask &&
4147965d9acSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4157965d9acSmrg	    # Don't fail if two instances are running concurrently.
4167965d9acSmrg	    test -d "$prefix" || exit 1
4177965d9acSmrg	  else
4187965d9acSmrg	    case $prefix in
4197965d9acSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4207965d9acSmrg	      *) qprefix=$prefix;;
4217965d9acSmrg	    esac
4227965d9acSmrg	    prefixes="$prefixes '$qprefix'"
4237965d9acSmrg	  fi
4247965d9acSmrg	fi
4257965d9acSmrg	prefix=$prefix/
4267965d9acSmrg      done
4277965d9acSmrg
4287965d9acSmrg      if test -n "$prefixes"; then
4297965d9acSmrg	# Don't fail if two instances are running concurrently.
4307965d9acSmrg	(umask $mkdir_umask &&
4317965d9acSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4327965d9acSmrg	  test -d "$dstdir" || exit 1
4337965d9acSmrg	obsolete_mkdir_used=true
43450806d53Smrg      fi
4357965d9acSmrg    fi
43650806d53Smrg  fi
43750806d53Smrg
43850806d53Smrg  if test -n "$dir_arg"; then
4397965d9acSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4407965d9acSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4417965d9acSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4427965d9acSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44350806d53Smrg  else
44450806d53Smrg
44550806d53Smrg    # Make a couple of temp file names in the proper directory.
44650806d53Smrg    dsttmp=$dstdir/_inst.$$_
44750806d53Smrg    rmtmp=$dstdir/_rm.$$_
44850806d53Smrg
44950806d53Smrg    # Trap to clean up those temp files at exit.
45050806d53Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45150806d53Smrg
45250806d53Smrg    # Copy the file name to the temp name.
4537965d9acSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
45450806d53Smrg
45550806d53Smrg    # and set any options; do chmod last to preserve setuid bits.
45650806d53Smrg    #
45750806d53Smrg    # If any of these fail, we abort the whole thing.  If we want to
45850806d53Smrg    # ignore errors from any of these, just make sure not to ignore
45950806d53Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
46050806d53Smrg    #
4617965d9acSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4627965d9acSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4637965d9acSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4647965d9acSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4657965d9acSmrg
4667965d9acSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4677965d9acSmrg    if $copy_on_change &&
4687965d9acSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
4697965d9acSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
4707965d9acSmrg
4717965d9acSmrg       eval "$initialize_posix_glob" &&
4727965d9acSmrg       $posix_glob set -f &&
4737965d9acSmrg       set X $old && old=:$2:$4:$5:$6 &&
4747965d9acSmrg       set X $new && new=:$2:$4:$5:$6 &&
4757965d9acSmrg       $posix_glob set +f &&
4767965d9acSmrg
4777965d9acSmrg       test "$old" = "$new" &&
4787965d9acSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4797965d9acSmrg    then
4807965d9acSmrg      rm -f "$dsttmp"
4817965d9acSmrg    else
4827965d9acSmrg      # Rename the file to the real destination.
4837965d9acSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4847965d9acSmrg
4857965d9acSmrg      # The rename failed, perhaps because mv can't rename something else
4867965d9acSmrg      # to itself, or perhaps because mv is so ancient that it does not
4877965d9acSmrg      # support -f.
4887965d9acSmrg      {
4897965d9acSmrg	# Now remove or move aside any old file at destination location.
4907965d9acSmrg	# We try this two ways since rm can't unlink itself on some
4917965d9acSmrg	# systems and the destination file might be busy for other
4927965d9acSmrg	# reasons.  In this case, the final cleanup might fail but the new
4937965d9acSmrg	# file should still install successfully.
4947965d9acSmrg	{
4957965d9acSmrg	  test ! -f "$dst" ||
4967965d9acSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
4977965d9acSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4987965d9acSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4997965d9acSmrg	  } ||
5007965d9acSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
5017965d9acSmrg	    (exit 1); exit 1
5027965d9acSmrg	  }
5037965d9acSmrg	} &&
5047965d9acSmrg
5057965d9acSmrg	# Now rename the file to the real destination.
5067965d9acSmrg	$doit $mvcmd "$dsttmp" "$dst"
5077965d9acSmrg      }
5087965d9acSmrg    fi || exit 1
5097965d9acSmrg
5107965d9acSmrg    trap '' 0
5117965d9acSmrg  fi
51250806d53Smrgdone
51350806d53Smrg
51450806d53Smrg# Local variables:
51550806d53Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
51650806d53Smrg# time-stamp-start: "scriptversion="
51750806d53Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
51850806d53Smrg# time-stamp-end: "$"
51950806d53Smrg# End:
520