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