install-sh revision 4e7590ef
14b0ead49Smrg#!/bin/sh
24b0ead49Smrg# install - install a program, script, or datafile
34b0ead49Smrg
44e7590efSmrgscriptversion=2011-01-19.21; # UTC
54b0ead49Smrg
64b0ead49Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
74b0ead49Smrg# later released in X11R6 (xc/config/util/install.sh) with the
84b0ead49Smrg# following copyright and license.
94b0ead49Smrg#
104b0ead49Smrg# Copyright (C) 1994 X Consortium
114b0ead49Smrg#
124b0ead49Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
134b0ead49Smrg# of this software and associated documentation files (the "Software"), to
144b0ead49Smrg# deal in the Software without restriction, including without limitation the
154b0ead49Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
164b0ead49Smrg# sell copies of the Software, and to permit persons to whom the Software is
174b0ead49Smrg# furnished to do so, subject to the following conditions:
184b0ead49Smrg#
194b0ead49Smrg# The above copyright notice and this permission notice shall be included in
204b0ead49Smrg# all copies or substantial portions of the Software.
214b0ead49Smrg#
224b0ead49Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
234b0ead49Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
244b0ead49Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
254b0ead49Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
264b0ead49Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
274b0ead49Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
284b0ead49Smrg#
294b0ead49Smrg# Except as contained in this notice, the name of the X Consortium shall not
304b0ead49Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
314b0ead49Smrg# ings in this Software without prior written authorization from the X Consor-
324b0ead49Smrg# tium.
334b0ead49Smrg#
344b0ead49Smrg#
354b0ead49Smrg# FSF changes to this file are in the public domain.
364b0ead49Smrg#
374b0ead49Smrg# Calling this script install-sh is preferred over install.sh, to prevent
384b0ead49Smrg# `make' implicit rules from creating a file called install from it
394b0ead49Smrg# when there is no Makefile.
404b0ead49Smrg#
414b0ead49Smrg# This script is compatible with the BSD install script, but was written
4252b01e16Smrg# from scratch.
4352b01e16Smrg
4452b01e16Smrgnl='
4552b01e16Smrg'
4652b01e16SmrgIFS=" ""	$nl"
474b0ead49Smrg
484b0ead49Smrg# set DOITPROG to echo to test this script
494b0ead49Smrg
504b0ead49Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
5152b01e16Smrgdoit=${DOITPROG-}
5252b01e16Smrgif test -z "$doit"; then
5352b01e16Smrg  doit_exec=exec
5452b01e16Smrgelse
5552b01e16Smrg  doit_exec=$doit
5652b01e16Smrgfi
574b0ead49Smrg
5852b01e16Smrg# Put in absolute file names if you don't have them in your path;
5952b01e16Smrg# or use environment vars.
6052b01e16Smrg
6152b01e16Smrgchgrpprog=${CHGRPPROG-chgrp}
6252b01e16Smrgchmodprog=${CHMODPROG-chmod}
6352b01e16Smrgchownprog=${CHOWNPROG-chown}
6452b01e16Smrgcmpprog=${CMPPROG-cmp}
6552b01e16Smrgcpprog=${CPPROG-cp}
6652b01e16Smrgmkdirprog=${MKDIRPROG-mkdir}
6752b01e16Smrgmvprog=${MVPROG-mv}
6852b01e16Smrgrmprog=${RMPROG-rm}
6952b01e16Smrgstripprog=${STRIPPROG-strip}
7052b01e16Smrg
7152b01e16Smrgposix_glob='?'
7252b01e16Smrginitialize_posix_glob='
7352b01e16Smrg  test "$posix_glob" != "?" || {
7452b01e16Smrg    if (set -f) 2>/dev/null; then
7552b01e16Smrg      posix_glob=
7652b01e16Smrg    else
7752b01e16Smrg      posix_glob=:
7852b01e16Smrg    fi
7952b01e16Smrg  }
8052b01e16Smrg'
814b0ead49Smrg
8252b01e16Smrgposix_mkdir=
8352b01e16Smrg
8452b01e16Smrg# Desired mode of installed file.
8552b01e16Smrgmode=0755
864b0ead49Smrg
874b0ead49Smrgchgrpcmd=
8852b01e16Smrgchmodcmd=$chmodprog
8952b01e16Smrgchowncmd=
9052b01e16Smrgmvcmd=$mvprog
914b0ead49Smrgrmcmd="$rmprog -f"
9252b01e16Smrgstripcmd=
9352b01e16Smrg
944b0ead49Smrgsrc=
954b0ead49Smrgdst=
964b0ead49Smrgdir_arg=
9752b01e16Smrgdst_arg=
9852b01e16Smrg
9952b01e16Smrgcopy_on_change=false
1004b0ead49Smrgno_target_directory=
1014b0ead49Smrg
10252b01e16Smrgusage="\
10352b01e16SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
1044b0ead49Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
1054b0ead49Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
1064b0ead49Smrg   or: $0 [OPTION]... -d DIRECTORIES...
1074b0ead49Smrg
1084b0ead49SmrgIn the 1st form, copy SRCFILE to DSTFILE.
1094b0ead49SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1104b0ead49SmrgIn the 4th, create DIRECTORIES.
1114b0ead49Smrg
1124b0ead49SmrgOptions:
11352b01e16Smrg     --help     display this help and exit.
11452b01e16Smrg     --version  display version info and exit.
11552b01e16Smrg
11652b01e16Smrg  -c            (ignored)
11752b01e16Smrg  -C            install only if different (preserve the last data modification time)
11852b01e16Smrg  -d            create directories instead of installing files.
11952b01e16Smrg  -g GROUP      $chgrpprog installed files to GROUP.
12052b01e16Smrg  -m MODE       $chmodprog installed files to MODE.
12152b01e16Smrg  -o USER       $chownprog installed files to USER.
12252b01e16Smrg  -s            $stripprog installed files.
12352b01e16Smrg  -t DIRECTORY  install into DIRECTORY.
12452b01e16Smrg  -T            report an error if DSTFILE is a directory.
1254b0ead49Smrg
1264b0ead49SmrgEnvironment variables override the default commands:
12752b01e16Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
12852b01e16Smrg  RMPROG STRIPPROG
1294b0ead49Smrg"
1304b0ead49Smrg
13152b01e16Smrgwhile test $# -ne 0; do
1324b0ead49Smrg  case $1 in
13352b01e16Smrg    -c) ;;
13452b01e16Smrg
13552b01e16Smrg    -C) copy_on_change=true;;
1364b0ead49Smrg
13752b01e16Smrg    -d) dir_arg=true;;
1384b0ead49Smrg
1394b0ead49Smrg    -g) chgrpcmd="$chgrpprog $2"
14052b01e16Smrg	shift;;
1414b0ead49Smrg
1424b0ead49Smrg    --help) echo "$usage"; exit $?;;
1434b0ead49Smrg
14452b01e16Smrg    -m) mode=$2
14552b01e16Smrg	case $mode in
14652b01e16Smrg	  *' '* | *'	'* | *'
14752b01e16Smrg'*	  | *'*'* | *'?'* | *'['*)
14852b01e16Smrg	    echo "$0: invalid mode: $mode" >&2
14952b01e16Smrg	    exit 1;;
15052b01e16Smrg	esac
15152b01e16Smrg	shift;;
1524b0ead49Smrg
1534b0ead49Smrg    -o) chowncmd="$chownprog $2"
15452b01e16Smrg	shift;;
1554b0ead49Smrg
15652b01e16Smrg    -s) stripcmd=$stripprog;;
1574b0ead49Smrg
15852b01e16Smrg    -t) dst_arg=$2
1594e7590efSmrg	# Protect names problematic for `test' and other utilities.
1604e7590efSmrg	case $dst_arg in
1614e7590efSmrg	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
1624e7590efSmrg	esac
16352b01e16Smrg	shift;;
1644b0ead49Smrg
16552b01e16Smrg    -T) no_target_directory=true;;
1664b0ead49Smrg
1674b0ead49Smrg    --version) echo "$0 $scriptversion"; exit $?;;
1684b0ead49Smrg
16952b01e16Smrg    --)	shift
1704b0ead49Smrg	break;;
17152b01e16Smrg
17252b01e16Smrg    -*)	echo "$0: invalid option: $1" >&2
17352b01e16Smrg	exit 1;;
17452b01e16Smrg
17552b01e16Smrg    *)  break;;
1764b0ead49Smrg  esac
17752b01e16Smrg  shift
1784b0ead49Smrgdone
1794b0ead49Smrg
18052b01e16Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
18152b01e16Smrg  # When -d is used, all remaining arguments are directories to create.
18252b01e16Smrg  # When -t is used, the destination is already specified.
18352b01e16Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
18452b01e16Smrg  for arg
18552b01e16Smrg  do
18652b01e16Smrg    if test -n "$dst_arg"; then
18752b01e16Smrg      # $@ is not empty: it contains at least $arg.
18852b01e16Smrg      set fnord "$@" "$dst_arg"
18952b01e16Smrg      shift # fnord
19052b01e16Smrg    fi
19152b01e16Smrg    shift # arg
19252b01e16Smrg    dst_arg=$arg
1934e7590efSmrg    # Protect names problematic for `test' and other utilities.
1944e7590efSmrg    case $dst_arg in
1954e7590efSmrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1964e7590efSmrg    esac
19752b01e16Smrg  done
19852b01e16Smrgfi
19952b01e16Smrg
20052b01e16Smrgif test $# -eq 0; then
2014b0ead49Smrg  if test -z "$dir_arg"; then
2024b0ead49Smrg    echo "$0: no input file specified." >&2
2034b0ead49Smrg    exit 1
2044b0ead49Smrg  fi
2054b0ead49Smrg  # It's OK to call `install-sh -d' without argument.
2064b0ead49Smrg  # This can happen when creating conditional directories.
2074b0ead49Smrg  exit 0
2084b0ead49Smrgfi
2094b0ead49Smrg
21052b01e16Smrgif test -z "$dir_arg"; then
2114e7590efSmrg  do_exit='(exit $ret); exit $ret'
2124e7590efSmrg  trap "ret=129; $do_exit" 1
2134e7590efSmrg  trap "ret=130; $do_exit" 2
2144e7590efSmrg  trap "ret=141; $do_exit" 13
2154e7590efSmrg  trap "ret=143; $do_exit" 15
21652b01e16Smrg
21752b01e16Smrg  # Set umask so as not to create temps with too-generous modes.
21852b01e16Smrg  # However, 'strip' requires both read and write access to temps.
21952b01e16Smrg  case $mode in
22052b01e16Smrg    # Optimize common cases.
22152b01e16Smrg    *644) cp_umask=133;;
22252b01e16Smrg    *755) cp_umask=22;;
22352b01e16Smrg
22452b01e16Smrg    *[0-7])
22552b01e16Smrg      if test -z "$stripcmd"; then
22652b01e16Smrg	u_plus_rw=
22752b01e16Smrg      else
22852b01e16Smrg	u_plus_rw='% 200'
22952b01e16Smrg      fi
23052b01e16Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
23152b01e16Smrg    *)
23252b01e16Smrg      if test -z "$stripcmd"; then
23352b01e16Smrg	u_plus_rw=
23452b01e16Smrg      else
23552b01e16Smrg	u_plus_rw=,u+rw
23652b01e16Smrg      fi
23752b01e16Smrg      cp_umask=$mode$u_plus_rw;;
23852b01e16Smrg  esac
23952b01e16Smrgfi
24052b01e16Smrg
2414b0ead49Smrgfor src
2424b0ead49Smrgdo
2434e7590efSmrg  # Protect names problematic for `test' and other utilities.
2444b0ead49Smrg  case $src in
2454e7590efSmrg    -* | [=\(\)!]) src=./$src;;
2464b0ead49Smrg  esac
2474b0ead49Smrg
2484b0ead49Smrg  if test -n "$dir_arg"; then
2494b0ead49Smrg    dst=$src
25052b01e16Smrg    dstdir=$dst
25152b01e16Smrg    test -d "$dstdir"
25252b01e16Smrg    dstdir_status=$?
2534b0ead49Smrg  else
25452b01e16Smrg
2554b0ead49Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2564b0ead49Smrg    # might cause directories to be created, which would be especially bad
2574b0ead49Smrg    # if $src (and thus $dsttmp) contains '*'.
2584b0ead49Smrg    if test ! -f "$src" && test ! -d "$src"; then
2594b0ead49Smrg      echo "$0: $src does not exist." >&2
2604b0ead49Smrg      exit 1
2614b0ead49Smrg    fi
2624b0ead49Smrg
26352b01e16Smrg    if test -z "$dst_arg"; then
2644b0ead49Smrg      echo "$0: no destination specified." >&2
2654b0ead49Smrg      exit 1
2664b0ead49Smrg    fi
26752b01e16Smrg    dst=$dst_arg
2684b0ead49Smrg
2694b0ead49Smrg    # If destination is a directory, append the input filename; won't work
2704b0ead49Smrg    # if double slashes aren't ignored.
2714b0ead49Smrg    if test -d "$dst"; then
2724b0ead49Smrg      if test -n "$no_target_directory"; then
27352b01e16Smrg	echo "$0: $dst_arg: Is a directory" >&2
2744b0ead49Smrg	exit 1
2754b0ead49Smrg      fi
27652b01e16Smrg      dstdir=$dst
27752b01e16Smrg      dst=$dstdir/`basename "$src"`
27852b01e16Smrg      dstdir_status=0
27952b01e16Smrg    else
28052b01e16Smrg      # Prefer dirname, but fall back on a substitute if dirname fails.
28152b01e16Smrg      dstdir=`
28252b01e16Smrg	(dirname "$dst") 2>/dev/null ||
28352b01e16Smrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
28452b01e16Smrg	     X"$dst" : 'X\(//\)[^/]' \| \
28552b01e16Smrg	     X"$dst" : 'X\(//\)$' \| \
28652b01e16Smrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
28752b01e16Smrg	echo X"$dst" |
28852b01e16Smrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
28952b01e16Smrg		   s//\1/
29052b01e16Smrg		   q
29152b01e16Smrg		 }
29252b01e16Smrg		 /^X\(\/\/\)[^/].*/{
29352b01e16Smrg		   s//\1/
29452b01e16Smrg		   q
29552b01e16Smrg		 }
29652b01e16Smrg		 /^X\(\/\/\)$/{
29752b01e16Smrg		   s//\1/
29852b01e16Smrg		   q
29952b01e16Smrg		 }
30052b01e16Smrg		 /^X\(\/\).*/{
30152b01e16Smrg		   s//\1/
30252b01e16Smrg		   q
30352b01e16Smrg		 }
30452b01e16Smrg		 s/.*/./; q'
30552b01e16Smrg      `
30652b01e16Smrg
30752b01e16Smrg      test -d "$dstdir"
30852b01e16Smrg      dstdir_status=$?
3094b0ead49Smrg    fi
3104b0ead49Smrg  fi
3114b0ead49Smrg
31252b01e16Smrg  obsolete_mkdir_used=false
31352b01e16Smrg
31452b01e16Smrg  if test $dstdir_status != 0; then
31552b01e16Smrg    case $posix_mkdir in
31652b01e16Smrg      '')
31752b01e16Smrg	# Create intermediate dirs using mode 755 as modified by the umask.
31852b01e16Smrg	# This is like FreeBSD 'install' as of 1997-10-28.
31952b01e16Smrg	umask=`umask`
32052b01e16Smrg	case $stripcmd.$umask in
32152b01e16Smrg	  # Optimize common cases.
32252b01e16Smrg	  *[2367][2367]) mkdir_umask=$umask;;
32352b01e16Smrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
32452b01e16Smrg
32552b01e16Smrg	  *[0-7])
32652b01e16Smrg	    mkdir_umask=`expr $umask + 22 \
32752b01e16Smrg	      - $umask % 100 % 40 + $umask % 20 \
32852b01e16Smrg	      - $umask % 10 % 4 + $umask % 2
32952b01e16Smrg	    `;;
33052b01e16Smrg	  *) mkdir_umask=$umask,go-w;;
33152b01e16Smrg	esac
33252b01e16Smrg
33352b01e16Smrg	# With -d, create the new directory with the user-specified mode.
33452b01e16Smrg	# Otherwise, rely on $mkdir_umask.
33552b01e16Smrg	if test -n "$dir_arg"; then
33652b01e16Smrg	  mkdir_mode=-m$mode
33752b01e16Smrg	else
33852b01e16Smrg	  mkdir_mode=
33952b01e16Smrg	fi
34052b01e16Smrg
34152b01e16Smrg	posix_mkdir=false
34252b01e16Smrg	case $umask in
34352b01e16Smrg	  *[123567][0-7][0-7])
34452b01e16Smrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
34552b01e16Smrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
34652b01e16Smrg	    ;;
34752b01e16Smrg	  *)
34852b01e16Smrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34952b01e16Smrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
35052b01e16Smrg
35152b01e16Smrg	    if (umask $mkdir_umask &&
35252b01e16Smrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
35352b01e16Smrg	    then
35452b01e16Smrg	      if test -z "$dir_arg" || {
35552b01e16Smrg		   # Check for POSIX incompatibilities with -m.
35652b01e16Smrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35752b01e16Smrg		   # other-writeable bit of parent directory when it shouldn't.
35852b01e16Smrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
35952b01e16Smrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
36052b01e16Smrg		   case $ls_ld_tmpdir in
36152b01e16Smrg		     d????-?r-*) different_mode=700;;
36252b01e16Smrg		     d????-?--*) different_mode=755;;
36352b01e16Smrg		     *) false;;
36452b01e16Smrg		   esac &&
36552b01e16Smrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
36652b01e16Smrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
36752b01e16Smrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
36852b01e16Smrg		   }
36952b01e16Smrg		 }
37052b01e16Smrg	      then posix_mkdir=:
37152b01e16Smrg	      fi
37252b01e16Smrg	      rmdir "$tmpdir/d" "$tmpdir"
37352b01e16Smrg	    else
37452b01e16Smrg	      # Remove any dirs left behind by ancient mkdir implementations.
37552b01e16Smrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
37652b01e16Smrg	    fi
37752b01e16Smrg	    trap '' 0;;
37852b01e16Smrg	esac;;
37952b01e16Smrg    esac
3804b0ead49Smrg
38152b01e16Smrg    if
38252b01e16Smrg      $posix_mkdir && (
38352b01e16Smrg	umask $mkdir_umask &&
38452b01e16Smrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
38552b01e16Smrg      )
38652b01e16Smrg    then :
38752b01e16Smrg    else
3884b0ead49Smrg
38952b01e16Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
39052b01e16Smrg      # or it failed possibly due to a race condition.  Create the
39152b01e16Smrg      # directory the slow way, step by step, checking for races as we go.
3924b0ead49Smrg
39352b01e16Smrg      case $dstdir in
39452b01e16Smrg	/*) prefix='/';;
3954e7590efSmrg	[-=\(\)!]*) prefix='./';;
39652b01e16Smrg	*)  prefix='';;
39752b01e16Smrg      esac
3984b0ead49Smrg
39952b01e16Smrg      eval "$initialize_posix_glob"
4004b0ead49Smrg
40152b01e16Smrg      oIFS=$IFS
40252b01e16Smrg      IFS=/
40352b01e16Smrg      $posix_glob set -f
40452b01e16Smrg      set fnord $dstdir
4054b0ead49Smrg      shift
40652b01e16Smrg      $posix_glob set +f
40752b01e16Smrg      IFS=$oIFS
40852b01e16Smrg
40952b01e16Smrg      prefixes=
41052b01e16Smrg
41152b01e16Smrg      for d
41252b01e16Smrg      do
4134e7590efSmrg	test X"$d" = X && continue
41452b01e16Smrg
41552b01e16Smrg	prefix=$prefix$d
41652b01e16Smrg	if test -d "$prefix"; then
41752b01e16Smrg	  prefixes=
41852b01e16Smrg	else
41952b01e16Smrg	  if $posix_mkdir; then
42052b01e16Smrg	    (umask=$mkdir_umask &&
42152b01e16Smrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
42252b01e16Smrg	    # Don't fail if two instances are running concurrently.
42352b01e16Smrg	    test -d "$prefix" || exit 1
42452b01e16Smrg	  else
42552b01e16Smrg	    case $prefix in
42652b01e16Smrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42752b01e16Smrg	      *) qprefix=$prefix;;
42852b01e16Smrg	    esac
42952b01e16Smrg	    prefixes="$prefixes '$qprefix'"
43052b01e16Smrg	  fi
43152b01e16Smrg	fi
43252b01e16Smrg	prefix=$prefix/
43352b01e16Smrg      done
43452b01e16Smrg
43552b01e16Smrg      if test -n "$prefixes"; then
43652b01e16Smrg	# Don't fail if two instances are running concurrently.
43752b01e16Smrg	(umask $mkdir_umask &&
43852b01e16Smrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
43952b01e16Smrg	  test -d "$dstdir" || exit 1
44052b01e16Smrg	obsolete_mkdir_used=true
4414b0ead49Smrg      fi
44252b01e16Smrg    fi
4434b0ead49Smrg  fi
4444b0ead49Smrg
4454b0ead49Smrg  if test -n "$dir_arg"; then
44652b01e16Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
44752b01e16Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
44852b01e16Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
44952b01e16Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4504b0ead49Smrg  else
4514b0ead49Smrg
4524b0ead49Smrg    # Make a couple of temp file names in the proper directory.
4534b0ead49Smrg    dsttmp=$dstdir/_inst.$$_
4544b0ead49Smrg    rmtmp=$dstdir/_rm.$$_
4554b0ead49Smrg
4564b0ead49Smrg    # Trap to clean up those temp files at exit.
4574b0ead49Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4584b0ead49Smrg
4594b0ead49Smrg    # Copy the file name to the temp name.
46052b01e16Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4614b0ead49Smrg
4624b0ead49Smrg    # and set any options; do chmod last to preserve setuid bits.
4634b0ead49Smrg    #
4644b0ead49Smrg    # If any of these fail, we abort the whole thing.  If we want to
4654b0ead49Smrg    # ignore errors from any of these, just make sure not to ignore
4664b0ead49Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4674b0ead49Smrg    #
46852b01e16Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
46952b01e16Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
47052b01e16Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
47152b01e16Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
47252b01e16Smrg
47352b01e16Smrg    # If -C, don't bother to copy if it wouldn't change the file.
47452b01e16Smrg    if $copy_on_change &&
47552b01e16Smrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
47652b01e16Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
47752b01e16Smrg
47852b01e16Smrg       eval "$initialize_posix_glob" &&
47952b01e16Smrg       $posix_glob set -f &&
48052b01e16Smrg       set X $old && old=:$2:$4:$5:$6 &&
48152b01e16Smrg       set X $new && new=:$2:$4:$5:$6 &&
48252b01e16Smrg       $posix_glob set +f &&
48352b01e16Smrg
48452b01e16Smrg       test "$old" = "$new" &&
48552b01e16Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
48652b01e16Smrg    then
48752b01e16Smrg      rm -f "$dsttmp"
48852b01e16Smrg    else
48952b01e16Smrg      # Rename the file to the real destination.
49052b01e16Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
49152b01e16Smrg
49252b01e16Smrg      # The rename failed, perhaps because mv can't rename something else
49352b01e16Smrg      # to itself, or perhaps because mv is so ancient that it does not
49452b01e16Smrg      # support -f.
49552b01e16Smrg      {
49652b01e16Smrg	# Now remove or move aside any old file at destination location.
49752b01e16Smrg	# We try this two ways since rm can't unlink itself on some
49852b01e16Smrg	# systems and the destination file might be busy for other
49952b01e16Smrg	# reasons.  In this case, the final cleanup might fail but the new
50052b01e16Smrg	# file should still install successfully.
50152b01e16Smrg	{
50252b01e16Smrg	  test ! -f "$dst" ||
50352b01e16Smrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
50452b01e16Smrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
50552b01e16Smrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
50652b01e16Smrg	  } ||
50752b01e16Smrg	  { echo "$0: cannot unlink or rename $dst" >&2
50852b01e16Smrg	    (exit 1); exit 1
50952b01e16Smrg	  }
51052b01e16Smrg	} &&
51152b01e16Smrg
51252b01e16Smrg	# Now rename the file to the real destination.
51352b01e16Smrg	$doit $mvcmd "$dsttmp" "$dst"
51452b01e16Smrg      }
51552b01e16Smrg    fi || exit 1
51652b01e16Smrg
51752b01e16Smrg    trap '' 0
51852b01e16Smrg  fi
5194b0ead49Smrgdone
5204b0ead49Smrg
5214b0ead49Smrg# Local variables:
5224b0ead49Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
5234b0ead49Smrg# time-stamp-start: "scriptversion="
5244b0ead49Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
52552b01e16Smrg# time-stamp-time-zone: "UTC"
52652b01e16Smrg# time-stamp-end: "; # UTC"
5274b0ead49Smrg# End:
528