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