install-sh revision 1fb744b4
1c35d236eSmrg#!/bin/sh
2c35d236eSmrg# install - install a program, script, or datafile
3c35d236eSmrg
41fb744b4Smrgscriptversion=2011-01-19.21; # UTC
5c35d236eSmrg
6c35d236eSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7c35d236eSmrg# later released in X11R6 (xc/config/util/install.sh) with the
8c35d236eSmrg# following copyright and license.
9c35d236eSmrg#
10c35d236eSmrg# Copyright (C) 1994 X Consortium
11c35d236eSmrg#
12c35d236eSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13c35d236eSmrg# of this software and associated documentation files (the "Software"), to
14c35d236eSmrg# deal in the Software without restriction, including without limitation the
15c35d236eSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16c35d236eSmrg# sell copies of the Software, and to permit persons to whom the Software is
17c35d236eSmrg# furnished to do so, subject to the following conditions:
18c35d236eSmrg#
19c35d236eSmrg# The above copyright notice and this permission notice shall be included in
20c35d236eSmrg# all copies or substantial portions of the Software.
21c35d236eSmrg#
22c35d236eSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23c35d236eSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24c35d236eSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25c35d236eSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26c35d236eSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27c35d236eSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28c35d236eSmrg#
29c35d236eSmrg# Except as contained in this notice, the name of the X Consortium shall not
30c35d236eSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
31c35d236eSmrg# ings in this Software without prior written authorization from the X Consor-
32c35d236eSmrg# tium.
33c35d236eSmrg#
34c35d236eSmrg#
35c35d236eSmrg# FSF changes to this file are in the public domain.
36c35d236eSmrg#
37c35d236eSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38c35d236eSmrg# `make' implicit rules from creating a file called install from it
39c35d236eSmrg# when there is no Makefile.
40c35d236eSmrg#
41c35d236eSmrg# This script is compatible with the BSD install script, but was written
424f6cd06fSmrg# from scratch.
434f6cd06fSmrg
444f6cd06fSmrgnl='
454f6cd06fSmrg'
464f6cd06fSmrgIFS=" ""	$nl"
47c35d236eSmrg
48c35d236eSmrg# set DOITPROG to echo to test this script
49c35d236eSmrg
50c35d236eSmrg# Don't use :- since 4.3BSD and earlier shells don't like it.
51f55e6a01Smrgdoit=${DOITPROG-}
524f6cd06fSmrgif test -z "$doit"; then
534f6cd06fSmrg  doit_exec=exec
544f6cd06fSmrgelse
554f6cd06fSmrg  doit_exec=$doit
564f6cd06fSmrgfi
57c35d236eSmrg
584f6cd06fSmrg# Put in absolute file names if you don't have them in your path;
594f6cd06fSmrg# or use environment vars.
60c35d236eSmrg
61f55e6a01Smrgchgrpprog=${CHGRPPROG-chgrp}
62f55e6a01Smrgchmodprog=${CHMODPROG-chmod}
63f55e6a01Smrgchownprog=${CHOWNPROG-chown}
64f55e6a01Smrgcmpprog=${CMPPROG-cmp}
65f55e6a01Smrgcpprog=${CPPROG-cp}
66f55e6a01Smrgmkdirprog=${MKDIRPROG-mkdir}
67f55e6a01Smrgmvprog=${MVPROG-mv}
68f55e6a01Smrgrmprog=${RMPROG-rm}
69f55e6a01Smrgstripprog=${STRIPPROG-strip}
70f55e6a01Smrg
71f55e6a01Smrgposix_glob='?'
72f55e6a01Smrginitialize_posix_glob='
73f55e6a01Smrg  test "$posix_glob" != "?" || {
74f55e6a01Smrg    if (set -f) 2>/dev/null; then
75f55e6a01Smrg      posix_glob=
76f55e6a01Smrg    else
77f55e6a01Smrg      posix_glob=:
78f55e6a01Smrg    fi
79f55e6a01Smrg  }
80f55e6a01Smrg'
81c35d236eSmrg
824f6cd06fSmrgposix_mkdir=
834f6cd06fSmrg
844f6cd06fSmrg# Desired mode of installed file.
854f6cd06fSmrgmode=0755
864f6cd06fSmrg
87f55e6a01Smrgchgrpcmd=
884f6cd06fSmrgchmodcmd=$chmodprog
89c35d236eSmrgchowncmd=
90f55e6a01Smrgmvcmd=$mvprog
91c35d236eSmrgrmcmd="$rmprog -f"
92f55e6a01Smrgstripcmd=
93f55e6a01Smrg
94c35d236eSmrgsrc=
95c35d236eSmrgdst=
96c35d236eSmrgdir_arg=
97f55e6a01Smrgdst_arg=
98f55e6a01Smrg
99f55e6a01Smrgcopy_on_change=false
100c35d236eSmrgno_target_directory=
101c35d236eSmrg
102f55e6a01Smrgusage="\
103f55e6a01SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
104c35d236eSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
105c35d236eSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
106c35d236eSmrg   or: $0 [OPTION]... -d DIRECTORIES...
107c35d236eSmrg
108c35d236eSmrgIn the 1st form, copy SRCFILE to DSTFILE.
109c35d236eSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
110c35d236eSmrgIn the 4th, create DIRECTORIES.
111c35d236eSmrg
112c35d236eSmrgOptions:
113f55e6a01Smrg     --help     display this help and exit.
114f55e6a01Smrg     --version  display version info and exit.
115f55e6a01Smrg
116f55e6a01Smrg  -c            (ignored)
117f55e6a01Smrg  -C            install only if different (preserve the last data modification time)
118f55e6a01Smrg  -d            create directories instead of installing files.
119f55e6a01Smrg  -g GROUP      $chgrpprog installed files to GROUP.
120f55e6a01Smrg  -m MODE       $chmodprog installed files to MODE.
121f55e6a01Smrg  -o USER       $chownprog installed files to USER.
122f55e6a01Smrg  -s            $stripprog installed files.
123f55e6a01Smrg  -t DIRECTORY  install into DIRECTORY.
124f55e6a01Smrg  -T            report an error if DSTFILE is a directory.
125c35d236eSmrg
126c35d236eSmrgEnvironment variables override the default commands:
127f55e6a01Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
128f55e6a01Smrg  RMPROG STRIPPROG
129c35d236eSmrg"
130c35d236eSmrg
1314f6cd06fSmrgwhile test $# -ne 0; do
132c35d236eSmrg  case $1 in
133f55e6a01Smrg    -c) ;;
134f55e6a01Smrg
135f55e6a01Smrg    -C) copy_on_change=true;;
136c35d236eSmrg
137f55e6a01Smrg    -d) dir_arg=true;;
138c35d236eSmrg
139c35d236eSmrg    -g) chgrpcmd="$chgrpprog $2"
140f55e6a01Smrg	shift;;
141c35d236eSmrg
142c35d236eSmrg    --help) echo "$usage"; exit $?;;
143c35d236eSmrg
1444f6cd06fSmrg    -m) mode=$2
1454f6cd06fSmrg	case $mode in
1464f6cd06fSmrg	  *' '* | *'	'* | *'
1474f6cd06fSmrg'*	  | *'*'* | *'?'* | *'['*)
1484f6cd06fSmrg	    echo "$0: invalid mode: $mode" >&2
1494f6cd06fSmrg	    exit 1;;
1504f6cd06fSmrg	esac
151f55e6a01Smrg	shift;;
152c35d236eSmrg
153c35d236eSmrg    -o) chowncmd="$chownprog $2"
154f55e6a01Smrg	shift;;
155c35d236eSmrg
156f55e6a01Smrg    -s) stripcmd=$stripprog;;
157c35d236eSmrg
158f55e6a01Smrg    -t) dst_arg=$2
1591fb744b4Smrg	# Protect names problematic for `test' and other utilities.
1601fb744b4Smrg	case $dst_arg in
1611fb744b4Smrg	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
1621fb744b4Smrg	esac
163f55e6a01Smrg	shift;;
164c35d236eSmrg
165f55e6a01Smrg    -T) no_target_directory=true;;
166c35d236eSmrg
167c35d236eSmrg    --version) echo "$0 $scriptversion"; exit $?;;
168c35d236eSmrg
1694f6cd06fSmrg    --)	shift
170c35d236eSmrg	break;;
1714f6cd06fSmrg
1724f6cd06fSmrg    -*)	echo "$0: invalid option: $1" >&2
1734f6cd06fSmrg	exit 1;;
1744f6cd06fSmrg
1754f6cd06fSmrg    *)  break;;
176c35d236eSmrg  esac
177f55e6a01Smrg  shift
178c35d236eSmrgdone
179c35d236eSmrg
180f55e6a01Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1814f6cd06fSmrg  # When -d is used, all remaining arguments are directories to create.
1824f6cd06fSmrg  # When -t is used, the destination is already specified.
1834f6cd06fSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1844f6cd06fSmrg  for arg
1854f6cd06fSmrg  do
186f55e6a01Smrg    if test -n "$dst_arg"; then
1874f6cd06fSmrg      # $@ is not empty: it contains at least $arg.
188f55e6a01Smrg      set fnord "$@" "$dst_arg"
1894f6cd06fSmrg      shift # fnord
1904f6cd06fSmrg    fi
1914f6cd06fSmrg    shift # arg
192f55e6a01Smrg    dst_arg=$arg
1931fb744b4Smrg    # Protect names problematic for `test' and other utilities.
1941fb744b4Smrg    case $dst_arg in
1951fb744b4Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1961fb744b4Smrg    esac
1974f6cd06fSmrg  done
1984f6cd06fSmrgfi
1994f6cd06fSmrg
2004f6cd06fSmrgif test $# -eq 0; then
201c35d236eSmrg  if test -z "$dir_arg"; then
202c35d236eSmrg    echo "$0: no input file specified." >&2
203c35d236eSmrg    exit 1
204c35d236eSmrg  fi
205c35d236eSmrg  # It's OK to call `install-sh -d' without argument.
206c35d236eSmrg  # This can happen when creating conditional directories.
207c35d236eSmrg  exit 0
208c35d236eSmrgfi
209c35d236eSmrg
2104f6cd06fSmrgif test -z "$dir_arg"; then
2111fb744b4Smrg  do_exit='(exit $ret); exit $ret'
2121fb744b4Smrg  trap "ret=129; $do_exit" 1
2131fb744b4Smrg  trap "ret=130; $do_exit" 2
2141fb744b4Smrg  trap "ret=141; $do_exit" 13
2151fb744b4Smrg  trap "ret=143; $do_exit" 15
2164f6cd06fSmrg
2174f6cd06fSmrg  # Set umask so as not to create temps with too-generous modes.
2184f6cd06fSmrg  # However, 'strip' requires both read and write access to temps.
2194f6cd06fSmrg  case $mode in
2204f6cd06fSmrg    # Optimize common cases.
2214f6cd06fSmrg    *644) cp_umask=133;;
2224f6cd06fSmrg    *755) cp_umask=22;;
2234f6cd06fSmrg
2244f6cd06fSmrg    *[0-7])
2254f6cd06fSmrg      if test -z "$stripcmd"; then
2264f6cd06fSmrg	u_plus_rw=
2274f6cd06fSmrg      else
2284f6cd06fSmrg	u_plus_rw='% 200'
2294f6cd06fSmrg      fi
2304f6cd06fSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2314f6cd06fSmrg    *)
2324f6cd06fSmrg      if test -z "$stripcmd"; then
2334f6cd06fSmrg	u_plus_rw=
2344f6cd06fSmrg      else
2354f6cd06fSmrg	u_plus_rw=,u+rw
2364f6cd06fSmrg      fi
2374f6cd06fSmrg      cp_umask=$mode$u_plus_rw;;
2384f6cd06fSmrg  esac
2394f6cd06fSmrgfi
2404f6cd06fSmrg
241c35d236eSmrgfor src
242c35d236eSmrgdo
2431fb744b4Smrg  # Protect names problematic for `test' and other utilities.
244c35d236eSmrg  case $src in
2451fb744b4Smrg    -* | [=\(\)!]) src=./$src;;
246c35d236eSmrg  esac
247c35d236eSmrg
248c35d236eSmrg  if test -n "$dir_arg"; then
249c35d236eSmrg    dst=$src
2504f6cd06fSmrg    dstdir=$dst
2514f6cd06fSmrg    test -d "$dstdir"
2524f6cd06fSmrg    dstdir_status=$?
253c35d236eSmrg  else
2544f6cd06fSmrg
255c35d236eSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
256c35d236eSmrg    # might cause directories to be created, which would be especially bad
257c35d236eSmrg    # if $src (and thus $dsttmp) contains '*'.
258c35d236eSmrg    if test ! -f "$src" && test ! -d "$src"; then
259c35d236eSmrg      echo "$0: $src does not exist." >&2
260c35d236eSmrg      exit 1
261c35d236eSmrg    fi
262c35d236eSmrg
263f55e6a01Smrg    if test -z "$dst_arg"; then
264c35d236eSmrg      echo "$0: no destination specified." >&2
265c35d236eSmrg      exit 1
266c35d236eSmrg    fi
267f55e6a01Smrg    dst=$dst_arg
268c35d236eSmrg
269c35d236eSmrg    # If destination is a directory, append the input filename; won't work
270c35d236eSmrg    # if double slashes aren't ignored.
271c35d236eSmrg    if test -d "$dst"; then
272c35d236eSmrg      if test -n "$no_target_directory"; then
273f55e6a01Smrg	echo "$0: $dst_arg: Is a directory" >&2
274c35d236eSmrg	exit 1
275c35d236eSmrg      fi
2764f6cd06fSmrg      dstdir=$dst
2774f6cd06fSmrg      dst=$dstdir/`basename "$src"`
2784f6cd06fSmrg      dstdir_status=0
2794f6cd06fSmrg    else
2804f6cd06fSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2814f6cd06fSmrg      dstdir=`
2824f6cd06fSmrg	(dirname "$dst") 2>/dev/null ||
2834f6cd06fSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2844f6cd06fSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
2854f6cd06fSmrg	     X"$dst" : 'X\(//\)$' \| \
2864f6cd06fSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2874f6cd06fSmrg	echo X"$dst" |
2884f6cd06fSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2894f6cd06fSmrg		   s//\1/
2904f6cd06fSmrg		   q
2914f6cd06fSmrg		 }
2924f6cd06fSmrg		 /^X\(\/\/\)[^/].*/{
2934f6cd06fSmrg		   s//\1/
2944f6cd06fSmrg		   q
2954f6cd06fSmrg		 }
2964f6cd06fSmrg		 /^X\(\/\/\)$/{
2974f6cd06fSmrg		   s//\1/
2984f6cd06fSmrg		   q
2994f6cd06fSmrg		 }
3004f6cd06fSmrg		 /^X\(\/\).*/{
3014f6cd06fSmrg		   s//\1/
3024f6cd06fSmrg		   q
3034f6cd06fSmrg		 }
3044f6cd06fSmrg		 s/.*/./; q'
3054f6cd06fSmrg      `
3064f6cd06fSmrg
3074f6cd06fSmrg      test -d "$dstdir"
3084f6cd06fSmrg      dstdir_status=$?
309c35d236eSmrg    fi
310c35d236eSmrg  fi
311c35d236eSmrg
3124f6cd06fSmrg  obsolete_mkdir_used=false
3134f6cd06fSmrg
3144f6cd06fSmrg  if test $dstdir_status != 0; then
3154f6cd06fSmrg    case $posix_mkdir in
3164f6cd06fSmrg      '')
3174f6cd06fSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
3184f6cd06fSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
3194f6cd06fSmrg	umask=`umask`
3204f6cd06fSmrg	case $stripcmd.$umask in
3214f6cd06fSmrg	  # Optimize common cases.
3224f6cd06fSmrg	  *[2367][2367]) mkdir_umask=$umask;;
3234f6cd06fSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3244f6cd06fSmrg
3254f6cd06fSmrg	  *[0-7])
3264f6cd06fSmrg	    mkdir_umask=`expr $umask + 22 \
3274f6cd06fSmrg	      - $umask % 100 % 40 + $umask % 20 \
3284f6cd06fSmrg	      - $umask % 10 % 4 + $umask % 2
3294f6cd06fSmrg	    `;;
3304f6cd06fSmrg	  *) mkdir_umask=$umask,go-w;;
3314f6cd06fSmrg	esac
3324f6cd06fSmrg
3334f6cd06fSmrg	# With -d, create the new directory with the user-specified mode.
3344f6cd06fSmrg	# Otherwise, rely on $mkdir_umask.
3354f6cd06fSmrg	if test -n "$dir_arg"; then
3364f6cd06fSmrg	  mkdir_mode=-m$mode
3374f6cd06fSmrg	else
3384f6cd06fSmrg	  mkdir_mode=
3394f6cd06fSmrg	fi
3404f6cd06fSmrg
3414f6cd06fSmrg	posix_mkdir=false
3424f6cd06fSmrg	case $umask in
3434f6cd06fSmrg	  *[123567][0-7][0-7])
3444f6cd06fSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3454f6cd06fSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3464f6cd06fSmrg	    ;;
3474f6cd06fSmrg	  *)
3484f6cd06fSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3494f6cd06fSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3504f6cd06fSmrg
3514f6cd06fSmrg	    if (umask $mkdir_umask &&
3524f6cd06fSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3534f6cd06fSmrg	    then
3544f6cd06fSmrg	      if test -z "$dir_arg" || {
3554f6cd06fSmrg		   # Check for POSIX incompatibilities with -m.
3564f6cd06fSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3574f6cd06fSmrg		   # other-writeable bit of parent directory when it shouldn't.
3584f6cd06fSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3594f6cd06fSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3604f6cd06fSmrg		   case $ls_ld_tmpdir in
3614f6cd06fSmrg		     d????-?r-*) different_mode=700;;
3624f6cd06fSmrg		     d????-?--*) different_mode=755;;
3634f6cd06fSmrg		     *) false;;
3644f6cd06fSmrg		   esac &&
3654f6cd06fSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3664f6cd06fSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3674f6cd06fSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3684f6cd06fSmrg		   }
3694f6cd06fSmrg		 }
3704f6cd06fSmrg	      then posix_mkdir=:
3714f6cd06fSmrg	      fi
3724f6cd06fSmrg	      rmdir "$tmpdir/d" "$tmpdir"
3734f6cd06fSmrg	    else
3744f6cd06fSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
3754f6cd06fSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3764f6cd06fSmrg	    fi
3774f6cd06fSmrg	    trap '' 0;;
3784f6cd06fSmrg	esac;;
3794f6cd06fSmrg    esac
380c35d236eSmrg
3814f6cd06fSmrg    if
3824f6cd06fSmrg      $posix_mkdir && (
3834f6cd06fSmrg	umask $mkdir_umask &&
3844f6cd06fSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3854f6cd06fSmrg      )
3864f6cd06fSmrg    then :
3874f6cd06fSmrg    else
388c35d236eSmrg
3894f6cd06fSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3904f6cd06fSmrg      # or it failed possibly due to a race condition.  Create the
3914f6cd06fSmrg      # directory the slow way, step by step, checking for races as we go.
3924f6cd06fSmrg
3934f6cd06fSmrg      case $dstdir in
394f55e6a01Smrg	/*) prefix='/';;
3951fb744b4Smrg	[-=\(\)!]*) prefix='./';;
396f55e6a01Smrg	*)  prefix='';;
3974f6cd06fSmrg      esac
3984f6cd06fSmrg
399f55e6a01Smrg      eval "$initialize_posix_glob"
4004f6cd06fSmrg
4014f6cd06fSmrg      oIFS=$IFS
4024f6cd06fSmrg      IFS=/
403f55e6a01Smrg      $posix_glob set -f
4044f6cd06fSmrg      set fnord $dstdir
405c35d236eSmrg      shift
406f55e6a01Smrg      $posix_glob set +f
4074f6cd06fSmrg      IFS=$oIFS
4084f6cd06fSmrg
4094f6cd06fSmrg      prefixes=
4104f6cd06fSmrg
4114f6cd06fSmrg      for d
4124f6cd06fSmrg      do
4131fb744b4Smrg	test X"$d" = X && continue
4144f6cd06fSmrg
4154f6cd06fSmrg	prefix=$prefix$d
4164f6cd06fSmrg	if test -d "$prefix"; then
4174f6cd06fSmrg	  prefixes=
4184f6cd06fSmrg	else
4194f6cd06fSmrg	  if $posix_mkdir; then
4204f6cd06fSmrg	    (umask=$mkdir_umask &&
4214f6cd06fSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4224f6cd06fSmrg	    # Don't fail if two instances are running concurrently.
4234f6cd06fSmrg	    test -d "$prefix" || exit 1
4244f6cd06fSmrg	  else
4254f6cd06fSmrg	    case $prefix in
4264f6cd06fSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4274f6cd06fSmrg	      *) qprefix=$prefix;;
4284f6cd06fSmrg	    esac
4294f6cd06fSmrg	    prefixes="$prefixes '$qprefix'"
4304f6cd06fSmrg	  fi
4314f6cd06fSmrg	fi
4324f6cd06fSmrg	prefix=$prefix/
4334f6cd06fSmrg      done
4344f6cd06fSmrg
4354f6cd06fSmrg      if test -n "$prefixes"; then
4364f6cd06fSmrg	# Don't fail if two instances are running concurrently.
4374f6cd06fSmrg	(umask $mkdir_umask &&
4384f6cd06fSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4394f6cd06fSmrg	  test -d "$dstdir" || exit 1
4404f6cd06fSmrg	obsolete_mkdir_used=true
441c35d236eSmrg      fi
4424f6cd06fSmrg    fi
443c35d236eSmrg  fi
444c35d236eSmrg
445c35d236eSmrg  if test -n "$dir_arg"; then
4464f6cd06fSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4474f6cd06fSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4484f6cd06fSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4494f6cd06fSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
450c35d236eSmrg  else
451c35d236eSmrg
452c35d236eSmrg    # Make a couple of temp file names in the proper directory.
453c35d236eSmrg    dsttmp=$dstdir/_inst.$$_
454c35d236eSmrg    rmtmp=$dstdir/_rm.$$_
455c35d236eSmrg
456c35d236eSmrg    # Trap to clean up those temp files at exit.
457c35d236eSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
458c35d236eSmrg
459c35d236eSmrg    # Copy the file name to the temp name.
4604f6cd06fSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
461c35d236eSmrg
462c35d236eSmrg    # and set any options; do chmod last to preserve setuid bits.
463c35d236eSmrg    #
464c35d236eSmrg    # If any of these fail, we abort the whole thing.  If we want to
465c35d236eSmrg    # ignore errors from any of these, just make sure not to ignore
466c35d236eSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
467c35d236eSmrg    #
468f55e6a01Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
469f55e6a01Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
470f55e6a01Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
471f55e6a01Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
472f55e6a01Smrg
473f55e6a01Smrg    # If -C, don't bother to copy if it wouldn't change the file.
474f55e6a01Smrg    if $copy_on_change &&
475f55e6a01Smrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
476f55e6a01Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
477f55e6a01Smrg
478f55e6a01Smrg       eval "$initialize_posix_glob" &&
479f55e6a01Smrg       $posix_glob set -f &&
480f55e6a01Smrg       set X $old && old=:$2:$4:$5:$6 &&
481f55e6a01Smrg       set X $new && new=:$2:$4:$5:$6 &&
482f55e6a01Smrg       $posix_glob set +f &&
483f55e6a01Smrg
484f55e6a01Smrg       test "$old" = "$new" &&
485f55e6a01Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
486f55e6a01Smrg    then
487f55e6a01Smrg      rm -f "$dsttmp"
488f55e6a01Smrg    else
489f55e6a01Smrg      # Rename the file to the real destination.
490f55e6a01Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
491f55e6a01Smrg
492f55e6a01Smrg      # The rename failed, perhaps because mv can't rename something else
493f55e6a01Smrg      # to itself, or perhaps because mv is so ancient that it does not
494f55e6a01Smrg      # support -f.
495f55e6a01Smrg      {
496f55e6a01Smrg	# Now remove or move aside any old file at destination location.
497f55e6a01Smrg	# We try this two ways since rm can't unlink itself on some
498f55e6a01Smrg	# systems and the destination file might be busy for other
499f55e6a01Smrg	# reasons.  In this case, the final cleanup might fail but the new
500f55e6a01Smrg	# file should still install successfully.
501f55e6a01Smrg	{
502f55e6a01Smrg	  test ! -f "$dst" ||
503f55e6a01Smrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
504f55e6a01Smrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
505f55e6a01Smrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
506f55e6a01Smrg	  } ||
507f55e6a01Smrg	  { echo "$0: cannot unlink or rename $dst" >&2
508f55e6a01Smrg	    (exit 1); exit 1
509f55e6a01Smrg	  }
510f55e6a01Smrg	} &&
511f55e6a01Smrg
512f55e6a01Smrg	# Now rename the file to the real destination.
513f55e6a01Smrg	$doit $mvcmd "$dsttmp" "$dst"
514f55e6a01Smrg      }
515f55e6a01Smrg    fi || exit 1
516c35d236eSmrg
5174f6cd06fSmrg    trap '' 0
5184f6cd06fSmrg  fi
5194f6cd06fSmrgdone
520c35d236eSmrg
521c35d236eSmrg# Local variables:
522c35d236eSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
523c35d236eSmrg# time-stamp-start: "scriptversion="
524c35d236eSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
525518bcf38Smrg# time-stamp-time-zone: "UTC"
526518bcf38Smrg# time-stamp-end: "; # UTC"
527c35d236eSmrg# End:
528