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