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