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