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