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