install-sh revision 909209ee
102be438aSmrg#!/bin/sh
202be438aSmrg# install - install a program, script, or datafile
302be438aSmrg
4909209eeSmrgscriptversion=2011-01-19.21; # UTC
502be438aSmrg
602be438aSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
702be438aSmrg# later released in X11R6 (xc/config/util/install.sh) with the
802be438aSmrg# following copyright and license.
902be438aSmrg#
1002be438aSmrg# Copyright (C) 1994 X Consortium
1102be438aSmrg#
1202be438aSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1302be438aSmrg# of this software and associated documentation files (the "Software"), to
1402be438aSmrg# deal in the Software without restriction, including without limitation the
1502be438aSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1602be438aSmrg# sell copies of the Software, and to permit persons to whom the Software is
1702be438aSmrg# furnished to do so, subject to the following conditions:
1802be438aSmrg#
1902be438aSmrg# The above copyright notice and this permission notice shall be included in
2002be438aSmrg# all copies or substantial portions of the Software.
2102be438aSmrg#
2202be438aSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2302be438aSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2402be438aSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2502be438aSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2602be438aSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2702be438aSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2802be438aSmrg#
2902be438aSmrg# Except as contained in this notice, the name of the X Consortium shall not
3002be438aSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
3102be438aSmrg# ings in this Software without prior written authorization from the X Consor-
3202be438aSmrg# tium.
3302be438aSmrg#
3402be438aSmrg#
3502be438aSmrg# FSF changes to this file are in the public domain.
3602be438aSmrg#
3702be438aSmrg# Calling this script install-sh is preferred over install.sh, to prevent
3802be438aSmrg# `make' implicit rules from creating a file called install from it
3902be438aSmrg# when there is no Makefile.
4002be438aSmrg#
4102be438aSmrg# This script is compatible with the BSD install script, but was written
42880ed95aSmrg# from scratch.
43880ed95aSmrg
44880ed95aSmrgnl='
45880ed95aSmrg'
46880ed95aSmrgIFS=" ""	$nl"
4702be438aSmrg
4802be438aSmrg# set DOITPROG to echo to test this script
4902be438aSmrg
5002be438aSmrg# Don't use :- since 4.3BSD and earlier shells don't like it.
51880ed95aSmrgdoit=${DOITPROG-}
52880ed95aSmrgif test -z "$doit"; then
53880ed95aSmrg  doit_exec=exec
54880ed95aSmrgelse
55880ed95aSmrg  doit_exec=$doit
56880ed95aSmrgfi
5702be438aSmrg
58880ed95aSmrg# Put in absolute file names if you don't have them in your path;
59880ed95aSmrg# or use environment vars.
60880ed95aSmrg
61880ed95aSmrgchgrpprog=${CHGRPPROG-chgrp}
62880ed95aSmrgchmodprog=${CHMODPROG-chmod}
63880ed95aSmrgchownprog=${CHOWNPROG-chown}
64880ed95aSmrgcmpprog=${CMPPROG-cmp}
65880ed95aSmrgcpprog=${CPPROG-cp}
66880ed95aSmrgmkdirprog=${MKDIRPROG-mkdir}
67880ed95aSmrgmvprog=${MVPROG-mv}
68880ed95aSmrgrmprog=${RMPROG-rm}
69880ed95aSmrgstripprog=${STRIPPROG-strip}
70880ed95aSmrg
71880ed95aSmrgposix_glob='?'
72880ed95aSmrginitialize_posix_glob='
73880ed95aSmrg  test "$posix_glob" != "?" || {
74880ed95aSmrg    if (set -f) 2>/dev/null; then
75880ed95aSmrg      posix_glob=
76880ed95aSmrg    else
77880ed95aSmrg      posix_glob=:
78880ed95aSmrg    fi
79880ed95aSmrg  }
80880ed95aSmrg'
8102be438aSmrg
82880ed95aSmrgposix_mkdir=
83880ed95aSmrg
84880ed95aSmrg# Desired mode of installed file.
85880ed95aSmrgmode=0755
8602be438aSmrg
8702be438aSmrgchgrpcmd=
88880ed95aSmrgchmodcmd=$chmodprog
89880ed95aSmrgchowncmd=
90880ed95aSmrgmvcmd=$mvprog
9102be438aSmrgrmcmd="$rmprog -f"
92880ed95aSmrgstripcmd=
93880ed95aSmrg
9402be438aSmrgsrc=
9502be438aSmrgdst=
9602be438aSmrgdir_arg=
97880ed95aSmrgdst_arg=
98880ed95aSmrg
99880ed95aSmrgcopy_on_change=false
10002be438aSmrgno_target_directory=
10102be438aSmrg
102880ed95aSmrgusage="\
103880ed95aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
10402be438aSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
10502be438aSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
10602be438aSmrg   or: $0 [OPTION]... -d DIRECTORIES...
10702be438aSmrg
10802be438aSmrgIn the 1st form, copy SRCFILE to DSTFILE.
10902be438aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
11002be438aSmrgIn the 4th, create DIRECTORIES.
11102be438aSmrg
11202be438aSmrgOptions:
113880ed95aSmrg     --help     display this help and exit.
114880ed95aSmrg     --version  display version info and exit.
115880ed95aSmrg
116880ed95aSmrg  -c            (ignored)
117880ed95aSmrg  -C            install only if different (preserve the last data modification time)
118880ed95aSmrg  -d            create directories instead of installing files.
119880ed95aSmrg  -g GROUP      $chgrpprog installed files to GROUP.
120880ed95aSmrg  -m MODE       $chmodprog installed files to MODE.
121880ed95aSmrg  -o USER       $chownprog installed files to USER.
122880ed95aSmrg  -s            $stripprog installed files.
123880ed95aSmrg  -t DIRECTORY  install into DIRECTORY.
124880ed95aSmrg  -T            report an error if DSTFILE is a directory.
12502be438aSmrg
12602be438aSmrgEnvironment variables override the default commands:
127880ed95aSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
128880ed95aSmrg  RMPROG STRIPPROG
12902be438aSmrg"
13002be438aSmrg
131880ed95aSmrgwhile test $# -ne 0; do
13202be438aSmrg  case $1 in
133880ed95aSmrg    -c) ;;
134880ed95aSmrg
135880ed95aSmrg    -C) copy_on_change=true;;
13602be438aSmrg
137880ed95aSmrg    -d) dir_arg=true;;
13802be438aSmrg
13902be438aSmrg    -g) chgrpcmd="$chgrpprog $2"
140880ed95aSmrg	shift;;
14102be438aSmrg
14202be438aSmrg    --help) echo "$usage"; exit $?;;
14302be438aSmrg
144880ed95aSmrg    -m) mode=$2
145880ed95aSmrg	case $mode in
146880ed95aSmrg	  *' '* | *'	'* | *'
147880ed95aSmrg'*	  | *'*'* | *'?'* | *'['*)
148880ed95aSmrg	    echo "$0: invalid mode: $mode" >&2
149880ed95aSmrg	    exit 1;;
150880ed95aSmrg	esac
151880ed95aSmrg	shift;;
15202be438aSmrg
15302be438aSmrg    -o) chowncmd="$chownprog $2"
154880ed95aSmrg	shift;;
15502be438aSmrg
156880ed95aSmrg    -s) stripcmd=$stripprog;;
15702be438aSmrg
158880ed95aSmrg    -t) dst_arg=$2
159909209eeSmrg	# Protect names problematic for `test' and other utilities.
160909209eeSmrg	case $dst_arg in
161909209eeSmrg	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
162909209eeSmrg	esac
163880ed95aSmrg	shift;;
16402be438aSmrg
165880ed95aSmrg    -T) no_target_directory=true;;
16602be438aSmrg
16702be438aSmrg    --version) echo "$0 $scriptversion"; exit $?;;
16802be438aSmrg
169880ed95aSmrg    --)	shift
17002be438aSmrg	break;;
171880ed95aSmrg
172880ed95aSmrg    -*)	echo "$0: invalid option: $1" >&2
173880ed95aSmrg	exit 1;;
174880ed95aSmrg
175880ed95aSmrg    *)  break;;
17602be438aSmrg  esac
177880ed95aSmrg  shift
17802be438aSmrgdone
17902be438aSmrg
180880ed95aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
181880ed95aSmrg  # When -d is used, all remaining arguments are directories to create.
182880ed95aSmrg  # When -t is used, the destination is already specified.
183880ed95aSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
184880ed95aSmrg  for arg
185880ed95aSmrg  do
186880ed95aSmrg    if test -n "$dst_arg"; then
187880ed95aSmrg      # $@ is not empty: it contains at least $arg.
188880ed95aSmrg      set fnord "$@" "$dst_arg"
189880ed95aSmrg      shift # fnord
190880ed95aSmrg    fi
191880ed95aSmrg    shift # arg
192880ed95aSmrg    dst_arg=$arg
193909209eeSmrg    # Protect names problematic for `test' and other utilities.
194909209eeSmrg    case $dst_arg in
195909209eeSmrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
196909209eeSmrg    esac
197880ed95aSmrg  done
198880ed95aSmrgfi
199880ed95aSmrg
200880ed95aSmrgif test $# -eq 0; then
20102be438aSmrg  if test -z "$dir_arg"; then
20202be438aSmrg    echo "$0: no input file specified." >&2
20302be438aSmrg    exit 1
20402be438aSmrg  fi
20502be438aSmrg  # It's OK to call `install-sh -d' without argument.
20602be438aSmrg  # This can happen when creating conditional directories.
20702be438aSmrg  exit 0
20802be438aSmrgfi
20902be438aSmrg
210880ed95aSmrgif test -z "$dir_arg"; then
211909209eeSmrg  do_exit='(exit $ret); exit $ret'
212909209eeSmrg  trap "ret=129; $do_exit" 1
213909209eeSmrg  trap "ret=130; $do_exit" 2
214909209eeSmrg  trap "ret=141; $do_exit" 13
215909209eeSmrg  trap "ret=143; $do_exit" 15
216880ed95aSmrg
217880ed95aSmrg  # Set umask so as not to create temps with too-generous modes.
218880ed95aSmrg  # However, 'strip' requires both read and write access to temps.
219880ed95aSmrg  case $mode in
220880ed95aSmrg    # Optimize common cases.
221880ed95aSmrg    *644) cp_umask=133;;
222880ed95aSmrg    *755) cp_umask=22;;
223880ed95aSmrg
224880ed95aSmrg    *[0-7])
225880ed95aSmrg      if test -z "$stripcmd"; then
226880ed95aSmrg	u_plus_rw=
227880ed95aSmrg      else
228880ed95aSmrg	u_plus_rw='% 200'
229880ed95aSmrg      fi
230880ed95aSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
231880ed95aSmrg    *)
232880ed95aSmrg      if test -z "$stripcmd"; then
233880ed95aSmrg	u_plus_rw=
234880ed95aSmrg      else
235880ed95aSmrg	u_plus_rw=,u+rw
236880ed95aSmrg      fi
237880ed95aSmrg      cp_umask=$mode$u_plus_rw;;
238880ed95aSmrg  esac
239880ed95aSmrgfi
240880ed95aSmrg
24102be438aSmrgfor src
24202be438aSmrgdo
243909209eeSmrg  # Protect names problematic for `test' and other utilities.
24402be438aSmrg  case $src in
245909209eeSmrg    -* | [=\(\)!]) src=./$src;;
24602be438aSmrg  esac
24702be438aSmrg
24802be438aSmrg  if test -n "$dir_arg"; then
24902be438aSmrg    dst=$src
250880ed95aSmrg    dstdir=$dst
251880ed95aSmrg    test -d "$dstdir"
252880ed95aSmrg    dstdir_status=$?
25302be438aSmrg  else
254880ed95aSmrg
25502be438aSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
25602be438aSmrg    # might cause directories to be created, which would be especially bad
25702be438aSmrg    # if $src (and thus $dsttmp) contains '*'.
25802be438aSmrg    if test ! -f "$src" && test ! -d "$src"; then
25902be438aSmrg      echo "$0: $src does not exist." >&2
26002be438aSmrg      exit 1
26102be438aSmrg    fi
26202be438aSmrg
263880ed95aSmrg    if test -z "$dst_arg"; then
26402be438aSmrg      echo "$0: no destination specified." >&2
26502be438aSmrg      exit 1
26602be438aSmrg    fi
267880ed95aSmrg    dst=$dst_arg
26802be438aSmrg
26902be438aSmrg    # If destination is a directory, append the input filename; won't work
27002be438aSmrg    # if double slashes aren't ignored.
27102be438aSmrg    if test -d "$dst"; then
27202be438aSmrg      if test -n "$no_target_directory"; then
273880ed95aSmrg	echo "$0: $dst_arg: Is a directory" >&2
27402be438aSmrg	exit 1
27502be438aSmrg      fi
276880ed95aSmrg      dstdir=$dst
277880ed95aSmrg      dst=$dstdir/`basename "$src"`
278880ed95aSmrg      dstdir_status=0
279880ed95aSmrg    else
280880ed95aSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
281880ed95aSmrg      dstdir=`
282880ed95aSmrg	(dirname "$dst") 2>/dev/null ||
283880ed95aSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
284880ed95aSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
285880ed95aSmrg	     X"$dst" : 'X\(//\)$' \| \
286880ed95aSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
287880ed95aSmrg	echo X"$dst" |
288880ed95aSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
289880ed95aSmrg		   s//\1/
290880ed95aSmrg		   q
291880ed95aSmrg		 }
292880ed95aSmrg		 /^X\(\/\/\)[^/].*/{
293880ed95aSmrg		   s//\1/
294880ed95aSmrg		   q
295880ed95aSmrg		 }
296880ed95aSmrg		 /^X\(\/\/\)$/{
297880ed95aSmrg		   s//\1/
298880ed95aSmrg		   q
299880ed95aSmrg		 }
300880ed95aSmrg		 /^X\(\/\).*/{
301880ed95aSmrg		   s//\1/
302880ed95aSmrg		   q
303880ed95aSmrg		 }
304880ed95aSmrg		 s/.*/./; q'
305880ed95aSmrg      `
306880ed95aSmrg
307880ed95aSmrg      test -d "$dstdir"
308880ed95aSmrg      dstdir_status=$?
30902be438aSmrg    fi
31002be438aSmrg  fi
31102be438aSmrg
312880ed95aSmrg  obsolete_mkdir_used=false
313880ed95aSmrg
314880ed95aSmrg  if test $dstdir_status != 0; then
315880ed95aSmrg    case $posix_mkdir in
316880ed95aSmrg      '')
317880ed95aSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
318880ed95aSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
319880ed95aSmrg	umask=`umask`
320880ed95aSmrg	case $stripcmd.$umask in
321880ed95aSmrg	  # Optimize common cases.
322880ed95aSmrg	  *[2367][2367]) mkdir_umask=$umask;;
323880ed95aSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
324880ed95aSmrg
325880ed95aSmrg	  *[0-7])
326880ed95aSmrg	    mkdir_umask=`expr $umask + 22 \
327880ed95aSmrg	      - $umask % 100 % 40 + $umask % 20 \
328880ed95aSmrg	      - $umask % 10 % 4 + $umask % 2
329880ed95aSmrg	    `;;
330880ed95aSmrg	  *) mkdir_umask=$umask,go-w;;
331880ed95aSmrg	esac
332880ed95aSmrg
333880ed95aSmrg	# With -d, create the new directory with the user-specified mode.
334880ed95aSmrg	# Otherwise, rely on $mkdir_umask.
335880ed95aSmrg	if test -n "$dir_arg"; then
336880ed95aSmrg	  mkdir_mode=-m$mode
337880ed95aSmrg	else
338880ed95aSmrg	  mkdir_mode=
339880ed95aSmrg	fi
340880ed95aSmrg
341880ed95aSmrg	posix_mkdir=false
342880ed95aSmrg	case $umask in
343880ed95aSmrg	  *[123567][0-7][0-7])
344880ed95aSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
345880ed95aSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
346880ed95aSmrg	    ;;
347880ed95aSmrg	  *)
348880ed95aSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
349880ed95aSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
350880ed95aSmrg
351880ed95aSmrg	    if (umask $mkdir_umask &&
352880ed95aSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
353880ed95aSmrg	    then
354880ed95aSmrg	      if test -z "$dir_arg" || {
355880ed95aSmrg		   # Check for POSIX incompatibilities with -m.
356880ed95aSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
357880ed95aSmrg		   # other-writeable bit of parent directory when it shouldn't.
358880ed95aSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
359880ed95aSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
360880ed95aSmrg		   case $ls_ld_tmpdir in
361880ed95aSmrg		     d????-?r-*) different_mode=700;;
362880ed95aSmrg		     d????-?--*) different_mode=755;;
363880ed95aSmrg		     *) false;;
364880ed95aSmrg		   esac &&
365880ed95aSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
366880ed95aSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
367880ed95aSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
368880ed95aSmrg		   }
369880ed95aSmrg		 }
370880ed95aSmrg	      then posix_mkdir=:
371880ed95aSmrg	      fi
372880ed95aSmrg	      rmdir "$tmpdir/d" "$tmpdir"
373880ed95aSmrg	    else
374880ed95aSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
375880ed95aSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
376880ed95aSmrg	    fi
377880ed95aSmrg	    trap '' 0;;
378880ed95aSmrg	esac;;
379880ed95aSmrg    esac
38002be438aSmrg
381880ed95aSmrg    if
382880ed95aSmrg      $posix_mkdir && (
383880ed95aSmrg	umask $mkdir_umask &&
384880ed95aSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
385880ed95aSmrg      )
386880ed95aSmrg    then :
387880ed95aSmrg    else
38802be438aSmrg
389880ed95aSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
390880ed95aSmrg      # or it failed possibly due to a race condition.  Create the
391880ed95aSmrg      # directory the slow way, step by step, checking for races as we go.
39202be438aSmrg
393880ed95aSmrg      case $dstdir in
394880ed95aSmrg	/*) prefix='/';;
395909209eeSmrg	[-=\(\)!]*) prefix='./';;
396880ed95aSmrg	*)  prefix='';;
397880ed95aSmrg      esac
39802be438aSmrg
399880ed95aSmrg      eval "$initialize_posix_glob"
40002be438aSmrg
401880ed95aSmrg      oIFS=$IFS
402880ed95aSmrg      IFS=/
403880ed95aSmrg      $posix_glob set -f
404880ed95aSmrg      set fnord $dstdir
40502be438aSmrg      shift
406880ed95aSmrg      $posix_glob set +f
407880ed95aSmrg      IFS=$oIFS
408880ed95aSmrg
409880ed95aSmrg      prefixes=
410880ed95aSmrg
411880ed95aSmrg      for d
412880ed95aSmrg      do
413909209eeSmrg	test X"$d" = X && continue
414880ed95aSmrg
415880ed95aSmrg	prefix=$prefix$d
416880ed95aSmrg	if test -d "$prefix"; then
417880ed95aSmrg	  prefixes=
418880ed95aSmrg	else
419880ed95aSmrg	  if $posix_mkdir; then
420880ed95aSmrg	    (umask=$mkdir_umask &&
421880ed95aSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
422880ed95aSmrg	    # Don't fail if two instances are running concurrently.
423880ed95aSmrg	    test -d "$prefix" || exit 1
424880ed95aSmrg	  else
425880ed95aSmrg	    case $prefix in
426880ed95aSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
427880ed95aSmrg	      *) qprefix=$prefix;;
428880ed95aSmrg	    esac
429880ed95aSmrg	    prefixes="$prefixes '$qprefix'"
430880ed95aSmrg	  fi
431880ed95aSmrg	fi
432880ed95aSmrg	prefix=$prefix/
433880ed95aSmrg      done
434880ed95aSmrg
435880ed95aSmrg      if test -n "$prefixes"; then
436880ed95aSmrg	# Don't fail if two instances are running concurrently.
437880ed95aSmrg	(umask $mkdir_umask &&
438880ed95aSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
439880ed95aSmrg	  test -d "$dstdir" || exit 1
440880ed95aSmrg	obsolete_mkdir_used=true
44102be438aSmrg      fi
442880ed95aSmrg    fi
44302be438aSmrg  fi
44402be438aSmrg
44502be438aSmrg  if test -n "$dir_arg"; then
446880ed95aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
447880ed95aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
448880ed95aSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
449880ed95aSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
45002be438aSmrg  else
45102be438aSmrg
45202be438aSmrg    # Make a couple of temp file names in the proper directory.
45302be438aSmrg    dsttmp=$dstdir/_inst.$$_
45402be438aSmrg    rmtmp=$dstdir/_rm.$$_
45502be438aSmrg
45602be438aSmrg    # Trap to clean up those temp files at exit.
45702be438aSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45802be438aSmrg
45902be438aSmrg    # Copy the file name to the temp name.
460880ed95aSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
46102be438aSmrg
46202be438aSmrg    # and set any options; do chmod last to preserve setuid bits.
46302be438aSmrg    #
46402be438aSmrg    # If any of these fail, we abort the whole thing.  If we want to
46502be438aSmrg    # ignore errors from any of these, just make sure not to ignore
46602be438aSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
46702be438aSmrg    #
468880ed95aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
469880ed95aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
470880ed95aSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
471880ed95aSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
472880ed95aSmrg
473880ed95aSmrg    # If -C, don't bother to copy if it wouldn't change the file.
474880ed95aSmrg    if $copy_on_change &&
475880ed95aSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
476880ed95aSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
477880ed95aSmrg
478880ed95aSmrg       eval "$initialize_posix_glob" &&
479880ed95aSmrg       $posix_glob set -f &&
480880ed95aSmrg       set X $old && old=:$2:$4:$5:$6 &&
481880ed95aSmrg       set X $new && new=:$2:$4:$5:$6 &&
482880ed95aSmrg       $posix_glob set +f &&
483880ed95aSmrg
484880ed95aSmrg       test "$old" = "$new" &&
485880ed95aSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
486880ed95aSmrg    then
487880ed95aSmrg      rm -f "$dsttmp"
488880ed95aSmrg    else
489880ed95aSmrg      # Rename the file to the real destination.
490880ed95aSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
491880ed95aSmrg
492880ed95aSmrg      # The rename failed, perhaps because mv can't rename something else
493880ed95aSmrg      # to itself, or perhaps because mv is so ancient that it does not
494880ed95aSmrg      # support -f.
495880ed95aSmrg      {
496880ed95aSmrg	# Now remove or move aside any old file at destination location.
497880ed95aSmrg	# We try this two ways since rm can't unlink itself on some
498880ed95aSmrg	# systems and the destination file might be busy for other
499880ed95aSmrg	# reasons.  In this case, the final cleanup might fail but the new
500880ed95aSmrg	# file should still install successfully.
501880ed95aSmrg	{
502880ed95aSmrg	  test ! -f "$dst" ||
503880ed95aSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
504880ed95aSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
505880ed95aSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
506880ed95aSmrg	  } ||
507880ed95aSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
508880ed95aSmrg	    (exit 1); exit 1
509880ed95aSmrg	  }
510880ed95aSmrg	} &&
511880ed95aSmrg
512880ed95aSmrg	# Now rename the file to the real destination.
513880ed95aSmrg	$doit $mvcmd "$dsttmp" "$dst"
514880ed95aSmrg      }
515880ed95aSmrg    fi || exit 1
516880ed95aSmrg
517880ed95aSmrg    trap '' 0
518880ed95aSmrg  fi
51902be438aSmrgdone
52002be438aSmrg
52102be438aSmrg# Local variables:
52202be438aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
52302be438aSmrg# time-stamp-start: "scriptversion="
52402be438aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
52561dc2d86Smrg# time-stamp-time-zone: "UTC"
52661dc2d86Smrg# time-stamp-end: "; # UTC"
52702be438aSmrg# End:
528