install-sh revision b9bb67cb
11cc8c64fSmrg#!/bin/sh
21cc8c64fSmrg# install - install a program, script, or datafile
3b9bb67cbSmrg
4b9bb67cbSmrgscriptversion=2009-04-28.21; # UTC
5b9bb67cbSmrg
61cc8c64fSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
71cc8c64fSmrg# later released in X11R6 (xc/config/util/install.sh) with the
81cc8c64fSmrg# following copyright and license.
91cc8c64fSmrg#
101cc8c64fSmrg# Copyright (C) 1994 X Consortium
111cc8c64fSmrg#
121cc8c64fSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
131cc8c64fSmrg# of this software and associated documentation files (the "Software"), to
141cc8c64fSmrg# deal in the Software without restriction, including without limitation the
151cc8c64fSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
161cc8c64fSmrg# sell copies of the Software, and to permit persons to whom the Software is
171cc8c64fSmrg# furnished to do so, subject to the following conditions:
181cc8c64fSmrg#
191cc8c64fSmrg# The above copyright notice and this permission notice shall be included in
201cc8c64fSmrg# all copies or substantial portions of the Software.
211cc8c64fSmrg#
221cc8c64fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
231cc8c64fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
241cc8c64fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
251cc8c64fSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
261cc8c64fSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
271cc8c64fSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
281cc8c64fSmrg#
291cc8c64fSmrg# Except as contained in this notice, the name of the X Consortium shall not
301cc8c64fSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
311cc8c64fSmrg# ings in this Software without prior written authorization from the X Consor-
321cc8c64fSmrg# tium.
331cc8c64fSmrg#
341cc8c64fSmrg#
351cc8c64fSmrg# FSF changes to this file are in the public domain.
361cc8c64fSmrg#
371cc8c64fSmrg# Calling this script install-sh is preferred over install.sh, to prevent
381cc8c64fSmrg# `make' implicit rules from creating a file called install from it
391cc8c64fSmrg# when there is no Makefile.
401cc8c64fSmrg#
411cc8c64fSmrg# This script is compatible with the BSD install script, but was written
42b9bb67cbSmrg# from scratch.
431cc8c64fSmrg
44b9bb67cbSmrgnl='
45b9bb67cbSmrg'
46b9bb67cbSmrgIFS=" ""	$nl"
471cc8c64fSmrg
481cc8c64fSmrg# set DOITPROG to echo to test this script
491cc8c64fSmrg
501cc8c64fSmrg# Don't use :- since 4.3BSD and earlier shells don't like it.
51b9bb67cbSmrgdoit=${DOITPROG-}
52b9bb67cbSmrgif test -z "$doit"; then
53b9bb67cbSmrg  doit_exec=exec
541cc8c64fSmrgelse
55b9bb67cbSmrg  doit_exec=$doit
561cc8c64fSmrgfi
571cc8c64fSmrg
58b9bb67cbSmrg# Put in absolute file names if you don't have them in your path;
59b9bb67cbSmrg# or use environment vars.
60b9bb67cbSmrg
61b9bb67cbSmrgchgrpprog=${CHGRPPROG-chgrp}
62b9bb67cbSmrgchmodprog=${CHMODPROG-chmod}
63b9bb67cbSmrgchownprog=${CHOWNPROG-chown}
64b9bb67cbSmrgcmpprog=${CMPPROG-cmp}
65b9bb67cbSmrgcpprog=${CPPROG-cp}
66b9bb67cbSmrgmkdirprog=${MKDIRPROG-mkdir}
67b9bb67cbSmrgmvprog=${MVPROG-mv}
68b9bb67cbSmrgrmprog=${RMPROG-rm}
69b9bb67cbSmrgstripprog=${STRIPPROG-strip}
70b9bb67cbSmrg
71b9bb67cbSmrgposix_glob='?'
72b9bb67cbSmrginitialize_posix_glob='
73b9bb67cbSmrg  test "$posix_glob" != "?" || {
74b9bb67cbSmrg    if (set -f) 2>/dev/null; then
75b9bb67cbSmrg      posix_glob=
76b9bb67cbSmrg    else
77b9bb67cbSmrg      posix_glob=:
78b9bb67cbSmrg    fi
79b9bb67cbSmrg  }
80b9bb67cbSmrg'
81b9bb67cbSmrg
82b9bb67cbSmrgposix_mkdir=
83b9bb67cbSmrg
84b9bb67cbSmrg# Desired mode of installed file.
85b9bb67cbSmrgmode=0755
86b9bb67cbSmrg
87b9bb67cbSmrgchgrpcmd=
88b9bb67cbSmrgchmodcmd=$chmodprog
89b9bb67cbSmrgchowncmd=
90b9bb67cbSmrgmvcmd=$mvprog
91b9bb67cbSmrgrmcmd="$rmprog -f"
92b9bb67cbSmrgstripcmd=
931cc8c64fSmrg
94b9bb67cbSmrgsrc=
95b9bb67cbSmrgdst=
96b9bb67cbSmrgdir_arg=
97b9bb67cbSmrgdst_arg=
981cc8c64fSmrg
99b9bb67cbSmrgcopy_on_change=false
100b9bb67cbSmrgno_target_directory=
1011cc8c64fSmrg
102b9bb67cbSmrgusage="\
103b9bb67cbSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
104b9bb67cbSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
105b9bb67cbSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
106b9bb67cbSmrg   or: $0 [OPTION]... -d DIRECTORIES...
1071cc8c64fSmrg
108b9bb67cbSmrgIn the 1st form, copy SRCFILE to DSTFILE.
109b9bb67cbSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
110b9bb67cbSmrgIn the 4th, create DIRECTORIES.
1111cc8c64fSmrg
112b9bb67cbSmrgOptions:
113b9bb67cbSmrg     --help     display this help and exit.
114b9bb67cbSmrg     --version  display version info and exit.
1151cc8c64fSmrg
116b9bb67cbSmrg  -c            (ignored)
117b9bb67cbSmrg  -C            install only if different (preserve the last data modification time)
118b9bb67cbSmrg  -d            create directories instead of installing files.
119b9bb67cbSmrg  -g GROUP      $chgrpprog installed files to GROUP.
120b9bb67cbSmrg  -m MODE       $chmodprog installed files to MODE.
121b9bb67cbSmrg  -o USER       $chownprog installed files to USER.
122b9bb67cbSmrg  -s            $stripprog installed files.
123b9bb67cbSmrg  -t DIRECTORY  install into DIRECTORY.
124b9bb67cbSmrg  -T            report an error if DSTFILE is a directory.
1251cc8c64fSmrg
126b9bb67cbSmrgEnvironment variables override the default commands:
127b9bb67cbSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
128b9bb67cbSmrg  RMPROG STRIPPROG
129b9bb67cbSmrg"
1301cc8c64fSmrg
131b9bb67cbSmrgwhile test $# -ne 0; do
132b9bb67cbSmrg  case $1 in
133b9bb67cbSmrg    -c) ;;
1341cc8c64fSmrg
135b9bb67cbSmrg    -C) copy_on_change=true;;
1361cc8c64fSmrg
137b9bb67cbSmrg    -d) dir_arg=true;;
1381cc8c64fSmrg
139b9bb67cbSmrg    -g) chgrpcmd="$chgrpprog $2"
140b9bb67cbSmrg	shift;;
1411cc8c64fSmrg
142b9bb67cbSmrg    --help) echo "$usage"; exit $?;;
1431cc8c64fSmrg
144b9bb67cbSmrg    -m) mode=$2
145b9bb67cbSmrg	case $mode in
146b9bb67cbSmrg	  *' '* | *'	'* | *'
147b9bb67cbSmrg'*	  | *'*'* | *'?'* | *'['*)
148b9bb67cbSmrg	    echo "$0: invalid mode: $mode" >&2
149b9bb67cbSmrg	    exit 1;;
150b9bb67cbSmrg	esac
151b9bb67cbSmrg	shift;;
1521cc8c64fSmrg
153b9bb67cbSmrg    -o) chowncmd="$chownprog $2"
154b9bb67cbSmrg	shift;;
1551cc8c64fSmrg
156b9bb67cbSmrg    -s) stripcmd=$stripprog;;
1571cc8c64fSmrg
158b9bb67cbSmrg    -t) dst_arg=$2
159b9bb67cbSmrg	shift;;
1601cc8c64fSmrg
161b9bb67cbSmrg    -T) no_target_directory=true;;
1621cc8c64fSmrg
163b9bb67cbSmrg    --version) echo "$0 $scriptversion"; exit $?;;
1641cc8c64fSmrg
165b9bb67cbSmrg    --)	shift
166b9bb67cbSmrg	break;;
1671cc8c64fSmrg
168b9bb67cbSmrg    -*)	echo "$0: invalid option: $1" >&2
169b9bb67cbSmrg	exit 1;;
1701cc8c64fSmrg
171b9bb67cbSmrg    *)  break;;
172b9bb67cbSmrg  esac
173b9bb67cbSmrg  shift
174b9bb67cbSmrgdone
1751cc8c64fSmrg
176b9bb67cbSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
177b9bb67cbSmrg  # When -d is used, all remaining arguments are directories to create.
178b9bb67cbSmrg  # When -t is used, the destination is already specified.
179b9bb67cbSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
180b9bb67cbSmrg  for arg
181b9bb67cbSmrg  do
182b9bb67cbSmrg    if test -n "$dst_arg"; then
183b9bb67cbSmrg      # $@ is not empty: it contains at least $arg.
184b9bb67cbSmrg      set fnord "$@" "$dst_arg"
185b9bb67cbSmrg      shift # fnord
186b9bb67cbSmrg    fi
187b9bb67cbSmrg    shift # arg
188b9bb67cbSmrg    dst_arg=$arg
189b9bb67cbSmrg  done
190b9bb67cbSmrgfi
1911cc8c64fSmrg
192b9bb67cbSmrgif test $# -eq 0; then
193b9bb67cbSmrg  if test -z "$dir_arg"; then
194b9bb67cbSmrg    echo "$0: no input file specified." >&2
195b9bb67cbSmrg    exit 1
196b9bb67cbSmrg  fi
197b9bb67cbSmrg  # It's OK to call `install-sh -d' without argument.
198b9bb67cbSmrg  # This can happen when creating conditional directories.
199b9bb67cbSmrg  exit 0
200b9bb67cbSmrgfi
2011cc8c64fSmrg
202b9bb67cbSmrgif test -z "$dir_arg"; then
203b9bb67cbSmrg  trap '(exit $?); exit' 1 2 13 15
204b9bb67cbSmrg
205b9bb67cbSmrg  # Set umask so as not to create temps with too-generous modes.
206b9bb67cbSmrg  # However, 'strip' requires both read and write access to temps.
207b9bb67cbSmrg  case $mode in
208b9bb67cbSmrg    # Optimize common cases.
209b9bb67cbSmrg    *644) cp_umask=133;;
210b9bb67cbSmrg    *755) cp_umask=22;;
211b9bb67cbSmrg
212b9bb67cbSmrg    *[0-7])
213b9bb67cbSmrg      if test -z "$stripcmd"; then
214b9bb67cbSmrg	u_plus_rw=
215b9bb67cbSmrg      else
216b9bb67cbSmrg	u_plus_rw='% 200'
217b9bb67cbSmrg      fi
218b9bb67cbSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
219b9bb67cbSmrg    *)
220b9bb67cbSmrg      if test -z "$stripcmd"; then
221b9bb67cbSmrg	u_plus_rw=
222b9bb67cbSmrg      else
223b9bb67cbSmrg	u_plus_rw=,u+rw
224b9bb67cbSmrg      fi
225b9bb67cbSmrg      cp_umask=$mode$u_plus_rw;;
226b9bb67cbSmrg  esac
227b9bb67cbSmrgfi
2281cc8c64fSmrg
229b9bb67cbSmrgfor src
230b9bb67cbSmrgdo
231b9bb67cbSmrg  # Protect names starting with `-'.
232b9bb67cbSmrg  case $src in
233b9bb67cbSmrg    -*) src=./$src;;
234b9bb67cbSmrg  esac
235b9bb67cbSmrg
236b9bb67cbSmrg  if test -n "$dir_arg"; then
237b9bb67cbSmrg    dst=$src
238b9bb67cbSmrg    dstdir=$dst
239b9bb67cbSmrg    test -d "$dstdir"
240b9bb67cbSmrg    dstdir_status=$?
241b9bb67cbSmrg  else
242b9bb67cbSmrg
243b9bb67cbSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
244b9bb67cbSmrg    # might cause directories to be created, which would be especially bad
245b9bb67cbSmrg    # if $src (and thus $dsttmp) contains '*'.
246b9bb67cbSmrg    if test ! -f "$src" && test ! -d "$src"; then
247b9bb67cbSmrg      echo "$0: $src does not exist." >&2
248b9bb67cbSmrg      exit 1
249b9bb67cbSmrg    fi
250b9bb67cbSmrg
251b9bb67cbSmrg    if test -z "$dst_arg"; then
252b9bb67cbSmrg      echo "$0: no destination specified." >&2
253b9bb67cbSmrg      exit 1
254b9bb67cbSmrg    fi
255b9bb67cbSmrg
256b9bb67cbSmrg    dst=$dst_arg
257b9bb67cbSmrg    # Protect names starting with `-'.
258b9bb67cbSmrg    case $dst in
259b9bb67cbSmrg      -*) dst=./$dst;;
260b9bb67cbSmrg    esac
2611cc8c64fSmrg
262b9bb67cbSmrg    # If destination is a directory, append the input filename; won't work
263b9bb67cbSmrg    # if double slashes aren't ignored.
264b9bb67cbSmrg    if test -d "$dst"; then
265b9bb67cbSmrg      if test -n "$no_target_directory"; then
266b9bb67cbSmrg	echo "$0: $dst_arg: Is a directory" >&2
267b9bb67cbSmrg	exit 1
268b9bb67cbSmrg      fi
269b9bb67cbSmrg      dstdir=$dst
270b9bb67cbSmrg      dst=$dstdir/`basename "$src"`
271b9bb67cbSmrg      dstdir_status=0
272b9bb67cbSmrg    else
273b9bb67cbSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
274b9bb67cbSmrg      dstdir=`
275b9bb67cbSmrg	(dirname "$dst") 2>/dev/null ||
276b9bb67cbSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
277b9bb67cbSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
278b9bb67cbSmrg	     X"$dst" : 'X\(//\)$' \| \
279b9bb67cbSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
280b9bb67cbSmrg	echo X"$dst" |
281b9bb67cbSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
282b9bb67cbSmrg		   s//\1/
283b9bb67cbSmrg		   q
284b9bb67cbSmrg		 }
285b9bb67cbSmrg		 /^X\(\/\/\)[^/].*/{
286b9bb67cbSmrg		   s//\1/
287b9bb67cbSmrg		   q
288b9bb67cbSmrg		 }
289b9bb67cbSmrg		 /^X\(\/\/\)$/{
290b9bb67cbSmrg		   s//\1/
291b9bb67cbSmrg		   q
292b9bb67cbSmrg		 }
293b9bb67cbSmrg		 /^X\(\/\).*/{
294b9bb67cbSmrg		   s//\1/
295b9bb67cbSmrg		   q
296b9bb67cbSmrg		 }
297b9bb67cbSmrg		 s/.*/./; q'
298b9bb67cbSmrg      `
299b9bb67cbSmrg
300b9bb67cbSmrg      test -d "$dstdir"
301b9bb67cbSmrg      dstdir_status=$?
302b9bb67cbSmrg    fi
303b9bb67cbSmrg  fi
304b9bb67cbSmrg
305b9bb67cbSmrg  obsolete_mkdir_used=false
306b9bb67cbSmrg
307b9bb67cbSmrg  if test $dstdir_status != 0; then
308b9bb67cbSmrg    case $posix_mkdir in
309b9bb67cbSmrg      '')
310b9bb67cbSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
311b9bb67cbSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
312b9bb67cbSmrg	umask=`umask`
313b9bb67cbSmrg	case $stripcmd.$umask in
314b9bb67cbSmrg	  # Optimize common cases.
315b9bb67cbSmrg	  *[2367][2367]) mkdir_umask=$umask;;
316b9bb67cbSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
317b9bb67cbSmrg
318b9bb67cbSmrg	  *[0-7])
319b9bb67cbSmrg	    mkdir_umask=`expr $umask + 22 \
320b9bb67cbSmrg	      - $umask % 100 % 40 + $umask % 20 \
321b9bb67cbSmrg	      - $umask % 10 % 4 + $umask % 2
322b9bb67cbSmrg	    `;;
323b9bb67cbSmrg	  *) mkdir_umask=$umask,go-w;;
324b9bb67cbSmrg	esac
325b9bb67cbSmrg
326b9bb67cbSmrg	# With -d, create the new directory with the user-specified mode.
327b9bb67cbSmrg	# Otherwise, rely on $mkdir_umask.
328b9bb67cbSmrg	if test -n "$dir_arg"; then
329b9bb67cbSmrg	  mkdir_mode=-m$mode
3301cc8c64fSmrg	else
331b9bb67cbSmrg	  mkdir_mode=
3321cc8c64fSmrg	fi
3331cc8c64fSmrg
334b9bb67cbSmrg	posix_mkdir=false
335b9bb67cbSmrg	case $umask in
336b9bb67cbSmrg	  *[123567][0-7][0-7])
337b9bb67cbSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
338b9bb67cbSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
339b9bb67cbSmrg	    ;;
340b9bb67cbSmrg	  *)
341b9bb67cbSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
342b9bb67cbSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
343b9bb67cbSmrg
344b9bb67cbSmrg	    if (umask $mkdir_umask &&
345b9bb67cbSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
346b9bb67cbSmrg	    then
347b9bb67cbSmrg	      if test -z "$dir_arg" || {
348b9bb67cbSmrg		   # Check for POSIX incompatibilities with -m.
349b9bb67cbSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
350b9bb67cbSmrg		   # other-writeable bit of parent directory when it shouldn't.
351b9bb67cbSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
352b9bb67cbSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
353b9bb67cbSmrg		   case $ls_ld_tmpdir in
354b9bb67cbSmrg		     d????-?r-*) different_mode=700;;
355b9bb67cbSmrg		     d????-?--*) different_mode=755;;
356b9bb67cbSmrg		     *) false;;
357b9bb67cbSmrg		   esac &&
358b9bb67cbSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
359b9bb67cbSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
360b9bb67cbSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
361b9bb67cbSmrg		   }
362b9bb67cbSmrg		 }
363b9bb67cbSmrg	      then posix_mkdir=:
364b9bb67cbSmrg	      fi
365b9bb67cbSmrg	      rmdir "$tmpdir/d" "$tmpdir"
366b9bb67cbSmrg	    else
367b9bb67cbSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
368b9bb67cbSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
369b9bb67cbSmrg	    fi
370b9bb67cbSmrg	    trap '' 0;;
371b9bb67cbSmrg	esac;;
372b9bb67cbSmrg    esac
3731cc8c64fSmrg
374b9bb67cbSmrg    if
375b9bb67cbSmrg      $posix_mkdir && (
376b9bb67cbSmrg	umask $mkdir_umask &&
377b9bb67cbSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
378b9bb67cbSmrg      )
379b9bb67cbSmrg    then :
380b9bb67cbSmrg    else
381b9bb67cbSmrg
382b9bb67cbSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
383b9bb67cbSmrg      # or it failed possibly due to a race condition.  Create the
384b9bb67cbSmrg      # directory the slow way, step by step, checking for races as we go.
385b9bb67cbSmrg
386b9bb67cbSmrg      case $dstdir in
387b9bb67cbSmrg	/*) prefix='/';;
388b9bb67cbSmrg	-*) prefix='./';;
389b9bb67cbSmrg	*)  prefix='';;
390b9bb67cbSmrg      esac
391b9bb67cbSmrg
392b9bb67cbSmrg      eval "$initialize_posix_glob"
393b9bb67cbSmrg
394b9bb67cbSmrg      oIFS=$IFS
395b9bb67cbSmrg      IFS=/
396b9bb67cbSmrg      $posix_glob set -f
397b9bb67cbSmrg      set fnord $dstdir
398b9bb67cbSmrg      shift
399b9bb67cbSmrg      $posix_glob set +f
400b9bb67cbSmrg      IFS=$oIFS
401b9bb67cbSmrg
402b9bb67cbSmrg      prefixes=
403b9bb67cbSmrg
404b9bb67cbSmrg      for d
405b9bb67cbSmrg      do
406b9bb67cbSmrg	test -z "$d" && continue
407b9bb67cbSmrg
408b9bb67cbSmrg	prefix=$prefix$d
409b9bb67cbSmrg	if test -d "$prefix"; then
410b9bb67cbSmrg	  prefixes=
411b9bb67cbSmrg	else
412b9bb67cbSmrg	  if $posix_mkdir; then
413b9bb67cbSmrg	    (umask=$mkdir_umask &&
414b9bb67cbSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
415b9bb67cbSmrg	    # Don't fail if two instances are running concurrently.
416b9bb67cbSmrg	    test -d "$prefix" || exit 1
417b9bb67cbSmrg	  else
418b9bb67cbSmrg	    case $prefix in
419b9bb67cbSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
420b9bb67cbSmrg	      *) qprefix=$prefix;;
421b9bb67cbSmrg	    esac
422b9bb67cbSmrg	    prefixes="$prefixes '$qprefix'"
423b9bb67cbSmrg	  fi
424b9bb67cbSmrg	fi
425b9bb67cbSmrg	prefix=$prefix/
426b9bb67cbSmrg      done
427b9bb67cbSmrg
428b9bb67cbSmrg      if test -n "$prefixes"; then
429b9bb67cbSmrg	# Don't fail if two instances are running concurrently.
430b9bb67cbSmrg	(umask $mkdir_umask &&
431b9bb67cbSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
432b9bb67cbSmrg	  test -d "$dstdir" || exit 1
433b9bb67cbSmrg	obsolete_mkdir_used=true
434b9bb67cbSmrg      fi
435b9bb67cbSmrg    fi
436b9bb67cbSmrg  fi
437b9bb67cbSmrg
438b9bb67cbSmrg  if test -n "$dir_arg"; then
439b9bb67cbSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
440b9bb67cbSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
441b9bb67cbSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
442b9bb67cbSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
443b9bb67cbSmrg  else
444b9bb67cbSmrg
445b9bb67cbSmrg    # Make a couple of temp file names in the proper directory.
446b9bb67cbSmrg    dsttmp=$dstdir/_inst.$$_
447b9bb67cbSmrg    rmtmp=$dstdir/_rm.$$_
448b9bb67cbSmrg
449b9bb67cbSmrg    # Trap to clean up those temp files at exit.
450b9bb67cbSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
451b9bb67cbSmrg
452b9bb67cbSmrg    # Copy the file name to the temp name.
453b9bb67cbSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
454b9bb67cbSmrg
455b9bb67cbSmrg    # and set any options; do chmod last to preserve setuid bits.
456b9bb67cbSmrg    #
457b9bb67cbSmrg    # If any of these fail, we abort the whole thing.  If we want to
458b9bb67cbSmrg    # ignore errors from any of these, just make sure not to ignore
459b9bb67cbSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
460b9bb67cbSmrg    #
461b9bb67cbSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
462b9bb67cbSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
463b9bb67cbSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
464b9bb67cbSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
465b9bb67cbSmrg
466b9bb67cbSmrg    # If -C, don't bother to copy if it wouldn't change the file.
467b9bb67cbSmrg    if $copy_on_change &&
468b9bb67cbSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
469b9bb67cbSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
470b9bb67cbSmrg
471b9bb67cbSmrg       eval "$initialize_posix_glob" &&
472b9bb67cbSmrg       $posix_glob set -f &&
473b9bb67cbSmrg       set X $old && old=:$2:$4:$5:$6 &&
474b9bb67cbSmrg       set X $new && new=:$2:$4:$5:$6 &&
475b9bb67cbSmrg       $posix_glob set +f &&
476b9bb67cbSmrg
477b9bb67cbSmrg       test "$old" = "$new" &&
478b9bb67cbSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
479b9bb67cbSmrg    then
480b9bb67cbSmrg      rm -f "$dsttmp"
481b9bb67cbSmrg    else
482b9bb67cbSmrg      # Rename the file to the real destination.
483b9bb67cbSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
484b9bb67cbSmrg
485b9bb67cbSmrg      # The rename failed, perhaps because mv can't rename something else
486b9bb67cbSmrg      # to itself, or perhaps because mv is so ancient that it does not
487b9bb67cbSmrg      # support -f.
488b9bb67cbSmrg      {
489b9bb67cbSmrg	# Now remove or move aside any old file at destination location.
490b9bb67cbSmrg	# We try this two ways since rm can't unlink itself on some
491b9bb67cbSmrg	# systems and the destination file might be busy for other
492b9bb67cbSmrg	# reasons.  In this case, the final cleanup might fail but the new
493b9bb67cbSmrg	# file should still install successfully.
494b9bb67cbSmrg	{
495b9bb67cbSmrg	  test ! -f "$dst" ||
496b9bb67cbSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
497b9bb67cbSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
498b9bb67cbSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
499b9bb67cbSmrg	  } ||
500b9bb67cbSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
501b9bb67cbSmrg	    (exit 1); exit 1
502b9bb67cbSmrg	  }
503b9bb67cbSmrg	} &&
504b9bb67cbSmrg
505b9bb67cbSmrg	# Now rename the file to the real destination.
506b9bb67cbSmrg	$doit $mvcmd "$dsttmp" "$dst"
507b9bb67cbSmrg      }
508b9bb67cbSmrg    fi || exit 1
509b9bb67cbSmrg
510b9bb67cbSmrg    trap '' 0
511b9bb67cbSmrg  fi
512b9bb67cbSmrgdone
5131cc8c64fSmrg
514b9bb67cbSmrg# Local variables:
515b9bb67cbSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
516b9bb67cbSmrg# time-stamp-start: "scriptversion="
517b9bb67cbSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
518b9bb67cbSmrg# time-stamp-time-zone: "UTC"
519b9bb67cbSmrg# time-stamp-end: "; # UTC"
520b9bb67cbSmrg# End:
521