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