xref: /freebsd/contrib/file/install-sh (revision 974b70c47dcfe49bdaed61e28cc0a409effe71df)
175a6cdb3SDavid E. O'Brien#!/bin/sh
275a6cdb3SDavid E. O'Brien# install - install a program, script, or datafile
3d1d50c78SDavid E. O'Brien
4974b70c4SDavid E. O'Brienscriptversion=2006-10-14.15
5d1d50c78SDavid E. O'Brien
6d1d50c78SDavid E. O'Brien# This originates from X11R5 (mit/util/scripts/install.sh), which was
7d1d50c78SDavid E. O'Brien# later released in X11R6 (xc/config/util/install.sh) with the
8d1d50c78SDavid E. O'Brien# following copyright and license.
9a2e8fb4cSDavid E. O'Brien#
10d1d50c78SDavid E. O'Brien# Copyright (C) 1994 X Consortium
11a2e8fb4cSDavid E. O'Brien#
12d1d50c78SDavid E. O'Brien# Permission is hereby granted, free of charge, to any person obtaining a copy
13d1d50c78SDavid E. O'Brien# of this software and associated documentation files (the "Software"), to
14d1d50c78SDavid E. O'Brien# deal in the Software without restriction, including without limitation the
15d1d50c78SDavid E. O'Brien# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16d1d50c78SDavid E. O'Brien# sell copies of the Software, and to permit persons to whom the Software is
17d1d50c78SDavid E. O'Brien# furnished to do so, subject to the following conditions:
18d1d50c78SDavid E. O'Brien#
19d1d50c78SDavid E. O'Brien# The above copyright notice and this permission notice shall be included in
20d1d50c78SDavid E. O'Brien# all copies or substantial portions of the Software.
21d1d50c78SDavid E. O'Brien#
22d1d50c78SDavid E. O'Brien# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23d1d50c78SDavid E. O'Brien# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24d1d50c78SDavid E. O'Brien# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25d1d50c78SDavid E. O'Brien# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26d1d50c78SDavid E. O'Brien# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27d1d50c78SDavid E. O'Brien# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28d1d50c78SDavid E. O'Brien#
29d1d50c78SDavid E. O'Brien# Except as contained in this notice, the name of the X Consortium shall not
30d1d50c78SDavid E. O'Brien# be used in advertising or otherwise to promote the sale, use or other deal-
31d1d50c78SDavid E. O'Brien# ings in this Software without prior written authorization from the X Consor-
32d1d50c78SDavid E. O'Brien# tium.
33d1d50c78SDavid E. O'Brien#
34d1d50c78SDavid E. O'Brien#
35d1d50c78SDavid E. O'Brien# FSF changes to this file are in the public domain.
3675a6cdb3SDavid E. O'Brien#
3775a6cdb3SDavid E. O'Brien# Calling this script install-sh is preferred over install.sh, to prevent
3875a6cdb3SDavid E. O'Brien# `make' implicit rules from creating a file called install from it
3975a6cdb3SDavid E. O'Brien# when there is no Makefile.
4075a6cdb3SDavid E. O'Brien#
4175a6cdb3SDavid E. O'Brien# This script is compatible with the BSD install script, but was written
42974b70c4SDavid E. O'Brien# from scratch.
43974b70c4SDavid E. O'Brien
44974b70c4SDavid E. O'Briennl='
45974b70c4SDavid E. O'Brien'
46974b70c4SDavid E. O'BrienIFS=" ""	$nl"
4775a6cdb3SDavid E. O'Brien
4875a6cdb3SDavid E. O'Brien# set DOITPROG to echo to test this script
4975a6cdb3SDavid E. O'Brien
5075a6cdb3SDavid E. O'Brien# Don't use :- since 4.3BSD and earlier shells don't like it.
5175a6cdb3SDavid E. O'Briendoit="${DOITPROG-}"
52974b70c4SDavid E. O'Brienif test -z "$doit"; then
53974b70c4SDavid E. O'Brien  doit_exec=exec
54974b70c4SDavid E. O'Brienelse
55974b70c4SDavid E. O'Brien  doit_exec=$doit
56974b70c4SDavid E. O'Brienfi
5775a6cdb3SDavid E. O'Brien
58974b70c4SDavid E. O'Brien# Put in absolute file names if you don't have them in your path;
59974b70c4SDavid E. O'Brien# or use environment vars.
6075a6cdb3SDavid E. O'Brien
6175a6cdb3SDavid E. O'Brienmvprog="${MVPROG-mv}"
6275a6cdb3SDavid E. O'Briencpprog="${CPPROG-cp}"
6375a6cdb3SDavid E. O'Brienchmodprog="${CHMODPROG-chmod}"
6475a6cdb3SDavid E. O'Brienchownprog="${CHOWNPROG-chown}"
6575a6cdb3SDavid E. O'Brienchgrpprog="${CHGRPPROG-chgrp}"
6675a6cdb3SDavid E. O'Brienstripprog="${STRIPPROG-strip}"
6775a6cdb3SDavid E. O'Brienrmprog="${RMPROG-rm}"
6875a6cdb3SDavid E. O'Brienmkdirprog="${MKDIRPROG-mkdir}"
6975a6cdb3SDavid E. O'Brien
70974b70c4SDavid E. O'Brienposix_glob=
71974b70c4SDavid E. O'Brienposix_mkdir=
72974b70c4SDavid E. O'Brien
73974b70c4SDavid E. O'Brien# Desired mode of installed file.
74974b70c4SDavid E. O'Brienmode=0755
75974b70c4SDavid E. O'Brien
76974b70c4SDavid E. O'Brienchmodcmd=$chmodprog
77d1d50c78SDavid E. O'Brienchowncmd=
78d1d50c78SDavid E. O'Brienchgrpcmd=
79d1d50c78SDavid E. O'Brienstripcmd=
8075a6cdb3SDavid E. O'Brienrmcmd="$rmprog -f"
8175a6cdb3SDavid E. O'Brienmvcmd="$mvprog"
82d1d50c78SDavid E. O'Briensrc=
83d1d50c78SDavid E. O'Briendst=
84d1d50c78SDavid E. O'Briendir_arg=
85d1d50c78SDavid E. O'Briendstarg=
86d1d50c78SDavid E. O'Brienno_target_directory=
8775a6cdb3SDavid E. O'Brien
88d1d50c78SDavid E. O'Brienusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
89d1d50c78SDavid E. O'Brien   or: $0 [OPTION]... SRCFILES... DIRECTORY
90d1d50c78SDavid E. O'Brien   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
91d1d50c78SDavid E. O'Brien   or: $0 [OPTION]... -d DIRECTORIES...
92d1d50c78SDavid E. O'Brien
93d1d50c78SDavid E. O'BrienIn the 1st form, copy SRCFILE to DSTFILE.
94d1d50c78SDavid E. O'BrienIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
95d1d50c78SDavid E. O'BrienIn the 4th, create DIRECTORIES.
96d1d50c78SDavid E. O'Brien
97d1d50c78SDavid E. O'BrienOptions:
98d1d50c78SDavid E. O'Brien-c         (ignored)
99d1d50c78SDavid E. O'Brien-d         create directories instead of installing files.
100d1d50c78SDavid E. O'Brien-g GROUP   $chgrpprog installed files to GROUP.
101d1d50c78SDavid E. O'Brien-m MODE    $chmodprog installed files to MODE.
102d1d50c78SDavid E. O'Brien-o USER    $chownprog installed files to USER.
103d1d50c78SDavid E. O'Brien-s         $stripprog installed files.
104d1d50c78SDavid E. O'Brien-t DIRECTORY  install into DIRECTORY.
105d1d50c78SDavid E. O'Brien-T         report an error if DSTFILE is a directory.
106d1d50c78SDavid E. O'Brien--help     display this help and exit.
107d1d50c78SDavid E. O'Brien--version  display version info and exit.
108d1d50c78SDavid E. O'Brien
109d1d50c78SDavid E. O'BrienEnvironment variables override the default commands:
110d1d50c78SDavid E. O'Brien  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
111d1d50c78SDavid E. O'Brien"
112d1d50c78SDavid E. O'Brien
113974b70c4SDavid E. O'Brienwhile test $# -ne 0; do
11475a6cdb3SDavid E. O'Brien  case $1 in
115d1d50c78SDavid E. O'Brien    -c) shift
11675a6cdb3SDavid E. O'Brien        continue;;
11775a6cdb3SDavid E. O'Brien
11875a6cdb3SDavid E. O'Brien    -d) dir_arg=true
11975a6cdb3SDavid E. O'Brien        shift
12075a6cdb3SDavid E. O'Brien        continue;;
12175a6cdb3SDavid E. O'Brien
122d1d50c78SDavid E. O'Brien    -g) chgrpcmd="$chgrpprog $2"
123d1d50c78SDavid E. O'Brien        shift
124d1d50c78SDavid E. O'Brien        shift
125d1d50c78SDavid E. O'Brien        continue;;
126d1d50c78SDavid E. O'Brien
127d1d50c78SDavid E. O'Brien    --help) echo "$usage"; exit $?;;
128d1d50c78SDavid E. O'Brien
129974b70c4SDavid E. O'Brien    -m) mode=$2
13075a6cdb3SDavid E. O'Brien        shift
13175a6cdb3SDavid E. O'Brien        shift
132974b70c4SDavid E. O'Brien	case $mode in
133974b70c4SDavid E. O'Brien	  *' '* | *'	'* | *'
134974b70c4SDavid E. O'Brien'*	  | *'*'* | *'?'* | *'['*)
135974b70c4SDavid E. O'Brien	    echo "$0: invalid mode: $mode" >&2
136974b70c4SDavid E. O'Brien	    exit 1;;
137974b70c4SDavid E. O'Brien	esac
13875a6cdb3SDavid E. O'Brien        continue;;
13975a6cdb3SDavid E. O'Brien
14075a6cdb3SDavid E. O'Brien    -o) chowncmd="$chownprog $2"
14175a6cdb3SDavid E. O'Brien        shift
14275a6cdb3SDavid E. O'Brien        shift
14375a6cdb3SDavid E. O'Brien        continue;;
14475a6cdb3SDavid E. O'Brien
145d1d50c78SDavid E. O'Brien    -s) stripcmd=$stripprog
146d1d50c78SDavid E. O'Brien        shift
147d1d50c78SDavid E. O'Brien        continue;;
148d1d50c78SDavid E. O'Brien
149d1d50c78SDavid E. O'Brien    -t) dstarg=$2
15075a6cdb3SDavid E. O'Brien	shift
15175a6cdb3SDavid E. O'Brien	shift
15275a6cdb3SDavid E. O'Brien	continue;;
15375a6cdb3SDavid E. O'Brien
154d1d50c78SDavid E. O'Brien    -T) no_target_directory=true
15575a6cdb3SDavid E. O'Brien	shift
15675a6cdb3SDavid E. O'Brien	continue;;
15775a6cdb3SDavid E. O'Brien
158d1d50c78SDavid E. O'Brien    --version) echo "$0 $scriptversion"; exit $?;;
15975a6cdb3SDavid E. O'Brien
160974b70c4SDavid E. O'Brien    --)	shift
161974b70c4SDavid E. O'Brien	break;;
162974b70c4SDavid E. O'Brien
163974b70c4SDavid E. O'Brien    -*)	echo "$0: invalid option: $1" >&2
164974b70c4SDavid E. O'Brien	exit 1;;
165974b70c4SDavid E. O'Brien
166974b70c4SDavid E. O'Brien    *)  break;;
167974b70c4SDavid E. O'Brien  esac
168974b70c4SDavid E. O'Briendone
169974b70c4SDavid E. O'Brien
170974b70c4SDavid E. O'Brienif test $# -ne 0 && test -z "$dir_arg$dstarg"; then
171974b70c4SDavid E. O'Brien  # When -d is used, all remaining arguments are directories to create.
172d1d50c78SDavid E. O'Brien  # When -t is used, the destination is already specified.
173d1d50c78SDavid E. O'Brien  # Otherwise, the last argument is the destination.  Remove it from $@.
174d1d50c78SDavid E. O'Brien  for arg
175d1d50c78SDavid E. O'Brien  do
176d1d50c78SDavid E. O'Brien    if test -n "$dstarg"; then
177d1d50c78SDavid E. O'Brien      # $@ is not empty: it contains at least $arg.
178d1d50c78SDavid E. O'Brien      set fnord "$@" "$dstarg"
179d1d50c78SDavid E. O'Brien      shift # fnord
18075a6cdb3SDavid E. O'Brien    fi
181d1d50c78SDavid E. O'Brien    shift # arg
182d1d50c78SDavid E. O'Brien    dstarg=$arg
183d1d50c78SDavid E. O'Brien  done
184974b70c4SDavid E. O'Brienfi
18575a6cdb3SDavid E. O'Brien
186974b70c4SDavid E. O'Brienif test $# -eq 0; then
187d1d50c78SDavid E. O'Brien  if test -z "$dir_arg"; then
188d1d50c78SDavid E. O'Brien    echo "$0: no input file specified." >&2
18975a6cdb3SDavid E. O'Brien    exit 1
190d1d50c78SDavid E. O'Brien  fi
191d1d50c78SDavid E. O'Brien  # It's OK to call `install-sh -d' without argument.
192d1d50c78SDavid E. O'Brien  # This can happen when creating conditional directories.
193d1d50c78SDavid E. O'Brien  exit 0
19475a6cdb3SDavid E. O'Brienfi
19575a6cdb3SDavid E. O'Brien
196974b70c4SDavid E. O'Brienif test -z "$dir_arg"; then
197974b70c4SDavid E. O'Brien  trap '(exit $?); exit' 1 2 13 15
198974b70c4SDavid E. O'Brien
199974b70c4SDavid E. O'Brien  # Set umask so as not to create temps with too-generous modes.
200974b70c4SDavid E. O'Brien  # However, 'strip' requires both read and write access to temps.
201974b70c4SDavid E. O'Brien  case $mode in
202974b70c4SDavid E. O'Brien    # Optimize common cases.
203974b70c4SDavid E. O'Brien    *644) cp_umask=133;;
204974b70c4SDavid E. O'Brien    *755) cp_umask=22;;
205974b70c4SDavid E. O'Brien
206974b70c4SDavid E. O'Brien    *[0-7])
207974b70c4SDavid E. O'Brien      if test -z "$stripcmd"; then
208974b70c4SDavid E. O'Brien	u_plus_rw=
209974b70c4SDavid E. O'Brien      else
210974b70c4SDavid E. O'Brien	u_plus_rw='% 200'
211974b70c4SDavid E. O'Brien      fi
212974b70c4SDavid E. O'Brien      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
213974b70c4SDavid E. O'Brien    *)
214974b70c4SDavid E. O'Brien      if test -z "$stripcmd"; then
215974b70c4SDavid E. O'Brien	u_plus_rw=
216974b70c4SDavid E. O'Brien      else
217974b70c4SDavid E. O'Brien	u_plus_rw=,u+rw
218974b70c4SDavid E. O'Brien      fi
219974b70c4SDavid E. O'Brien      cp_umask=$mode$u_plus_rw;;
220974b70c4SDavid E. O'Brien  esac
221974b70c4SDavid E. O'Brienfi
222974b70c4SDavid E. O'Brien
223d1d50c78SDavid E. O'Brienfor src
224d1d50c78SDavid E. O'Briendo
225d1d50c78SDavid E. O'Brien  # Protect names starting with `-'.
226d1d50c78SDavid E. O'Brien  case $src in
227d1d50c78SDavid E. O'Brien    -*) src=./$src ;;
228d1d50c78SDavid E. O'Brien  esac
229d1d50c78SDavid E. O'Brien
230d1d50c78SDavid E. O'Brien  if test -n "$dir_arg"; then
23175a6cdb3SDavid E. O'Brien    dst=$src
232974b70c4SDavid E. O'Brien    dstdir=$dst
233974b70c4SDavid E. O'Brien    test -d "$dstdir"
234974b70c4SDavid E. O'Brien    dstdir_status=$?
235974b70c4SDavid E. O'Brien  else
23675a6cdb3SDavid E. O'Brien
237d1d50c78SDavid E. O'Brien    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
23875a6cdb3SDavid E. O'Brien    # might cause directories to be created, which would be especially bad
23975a6cdb3SDavid E. O'Brien    # if $src (and thus $dsttmp) contains '*'.
240d1d50c78SDavid E. O'Brien    if test ! -f "$src" && test ! -d "$src"; then
241d1d50c78SDavid E. O'Brien      echo "$0: $src does not exist." >&2
24275a6cdb3SDavid E. O'Brien      exit 1
24375a6cdb3SDavid E. O'Brien    fi
24475a6cdb3SDavid E. O'Brien
245d1d50c78SDavid E. O'Brien    if test -z "$dstarg"; then
246d1d50c78SDavid E. O'Brien      echo "$0: no destination specified." >&2
24775a6cdb3SDavid E. O'Brien      exit 1
24875a6cdb3SDavid E. O'Brien    fi
24975a6cdb3SDavid E. O'Brien
250d1d50c78SDavid E. O'Brien    dst=$dstarg
251d1d50c78SDavid E. O'Brien    # Protect names starting with `-'.
252d1d50c78SDavid E. O'Brien    case $dst in
253d1d50c78SDavid E. O'Brien      -*) dst=./$dst ;;
254d1d50c78SDavid E. O'Brien    esac
25575a6cdb3SDavid E. O'Brien
256d1d50c78SDavid E. O'Brien    # If destination is a directory, append the input filename; won't work
257d1d50c78SDavid E. O'Brien    # if double slashes aren't ignored.
258d1d50c78SDavid E. O'Brien    if test -d "$dst"; then
259d1d50c78SDavid E. O'Brien      if test -n "$no_target_directory"; then
260d1d50c78SDavid E. O'Brien	echo "$0: $dstarg: Is a directory" >&2
261d1d50c78SDavid E. O'Brien	exit 1
262d1d50c78SDavid E. O'Brien      fi
263974b70c4SDavid E. O'Brien      dstdir=$dst
264974b70c4SDavid E. O'Brien      dst=$dstdir/`basename "$src"`
265974b70c4SDavid E. O'Brien      dstdir_status=0
266974b70c4SDavid E. O'Brien    else
267974b70c4SDavid E. O'Brien      # Prefer dirname, but fall back on a substitute if dirname fails.
268974b70c4SDavid E. O'Brien      dstdir=`
269974b70c4SDavid E. O'Brien	(dirname "$dst") 2>/dev/null ||
270974b70c4SDavid E. O'Brien	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
271974b70c4SDavid E. O'Brien	     X"$dst" : 'X\(//\)[^/]' \| \
272974b70c4SDavid E. O'Brien	     X"$dst" : 'X\(//\)$' \| \
273974b70c4SDavid E. O'Brien	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
274974b70c4SDavid E. O'Brien	echo X"$dst" |
275974b70c4SDavid E. O'Brien	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
276974b70c4SDavid E. O'Brien		   s//\1/
277974b70c4SDavid E. O'Brien		   q
278974b70c4SDavid E. O'Brien		 }
279974b70c4SDavid E. O'Brien		 /^X\(\/\/\)[^/].*/{
280974b70c4SDavid E. O'Brien		   s//\1/
281974b70c4SDavid E. O'Brien		   q
282974b70c4SDavid E. O'Brien		 }
283974b70c4SDavid E. O'Brien		 /^X\(\/\/\)$/{
284974b70c4SDavid E. O'Brien		   s//\1/
285974b70c4SDavid E. O'Brien		   q
286974b70c4SDavid E. O'Brien		 }
287974b70c4SDavid E. O'Brien		 /^X\(\/\).*/{
288974b70c4SDavid E. O'Brien		   s//\1/
289974b70c4SDavid E. O'Brien		   q
290974b70c4SDavid E. O'Brien		 }
291974b70c4SDavid E. O'Brien		 s/.*/./; q'
292974b70c4SDavid E. O'Brien      `
293974b70c4SDavid E. O'Brien
294974b70c4SDavid E. O'Brien      test -d "$dstdir"
295974b70c4SDavid E. O'Brien      dstdir_status=$?
29675a6cdb3SDavid E. O'Brien    fi
29775a6cdb3SDavid E. O'Brien  fi
29875a6cdb3SDavid E. O'Brien
299974b70c4SDavid E. O'Brien  obsolete_mkdir_used=false
30075a6cdb3SDavid E. O'Brien
301974b70c4SDavid E. O'Brien  if test $dstdir_status != 0; then
302974b70c4SDavid E. O'Brien    case $posix_mkdir in
303974b70c4SDavid E. O'Brien      '')
304974b70c4SDavid E. O'Brien	# Create intermediate dirs using mode 755 as modified by the umask.
305974b70c4SDavid E. O'Brien	# This is like FreeBSD 'install' as of 1997-10-28.
306974b70c4SDavid E. O'Brien	umask=`umask`
307974b70c4SDavid E. O'Brien	case $stripcmd.$umask in
308974b70c4SDavid E. O'Brien	  # Optimize common cases.
309974b70c4SDavid E. O'Brien	  *[2367][2367]) mkdir_umask=$umask;;
310974b70c4SDavid E. O'Brien	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
31175a6cdb3SDavid E. O'Brien
312974b70c4SDavid E. O'Brien	  *[0-7])
313974b70c4SDavid E. O'Brien	    mkdir_umask=`expr $umask + 22 \
314974b70c4SDavid E. O'Brien	      - $umask % 100 % 40 + $umask % 20 \
315974b70c4SDavid E. O'Brien	      - $umask % 10 % 4 + $umask % 2
316974b70c4SDavid E. O'Brien	    `;;
317974b70c4SDavid E. O'Brien	  *) mkdir_umask=$umask,go-w;;
318974b70c4SDavid E. O'Brien	esac
319974b70c4SDavid E. O'Brien
320974b70c4SDavid E. O'Brien	# With -d, create the new directory with the user-specified mode.
321974b70c4SDavid E. O'Brien	# Otherwise, rely on $mkdir_umask.
322974b70c4SDavid E. O'Brien	if test -n "$dir_arg"; then
323974b70c4SDavid E. O'Brien	  mkdir_mode=-m$mode
324974b70c4SDavid E. O'Brien	else
325974b70c4SDavid E. O'Brien	  mkdir_mode=
326974b70c4SDavid E. O'Brien	fi
327974b70c4SDavid E. O'Brien
328974b70c4SDavid E. O'Brien	posix_mkdir=false
329974b70c4SDavid E. O'Brien	case $umask in
330974b70c4SDavid E. O'Brien	  *[123567][0-7][0-7])
331974b70c4SDavid E. O'Brien	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
332974b70c4SDavid E. O'Brien	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
333974b70c4SDavid E. O'Brien	    ;;
334974b70c4SDavid E. O'Brien	  *)
335974b70c4SDavid E. O'Brien	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
336974b70c4SDavid E. O'Brien	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
337974b70c4SDavid E. O'Brien
338974b70c4SDavid E. O'Brien	    if (umask $mkdir_umask &&
339974b70c4SDavid E. O'Brien		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
340974b70c4SDavid E. O'Brien	    then
341974b70c4SDavid E. O'Brien	      if test -z "$dir_arg" || {
342974b70c4SDavid E. O'Brien		   # Check for POSIX incompatibilities with -m.
343974b70c4SDavid E. O'Brien		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
344974b70c4SDavid E. O'Brien		   # other-writeable bit of parent directory when it shouldn't.
345974b70c4SDavid E. O'Brien		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
346974b70c4SDavid E. O'Brien		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
347974b70c4SDavid E. O'Brien		   case $ls_ld_tmpdir in
348974b70c4SDavid E. O'Brien		     d????-?r-*) different_mode=700;;
349974b70c4SDavid E. O'Brien		     d????-?--*) different_mode=755;;
350974b70c4SDavid E. O'Brien		     *) false;;
351974b70c4SDavid E. O'Brien		   esac &&
352974b70c4SDavid E. O'Brien		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
353974b70c4SDavid E. O'Brien		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
354974b70c4SDavid E. O'Brien		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
355974b70c4SDavid E. O'Brien		   }
356974b70c4SDavid E. O'Brien		 }
357974b70c4SDavid E. O'Brien	      then posix_mkdir=:
358974b70c4SDavid E. O'Brien	      fi
359974b70c4SDavid E. O'Brien	      rmdir "$tmpdir/d" "$tmpdir"
360974b70c4SDavid E. O'Brien	    else
361974b70c4SDavid E. O'Brien	      # Remove any dirs left behind by ancient mkdir implementations.
362974b70c4SDavid E. O'Brien	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
363974b70c4SDavid E. O'Brien	    fi
364974b70c4SDavid E. O'Brien	    trap '' 0;;
365974b70c4SDavid E. O'Brien	esac;;
366974b70c4SDavid E. O'Brien    esac
367974b70c4SDavid E. O'Brien
368974b70c4SDavid E. O'Brien    if
369974b70c4SDavid E. O'Brien      $posix_mkdir && (
370974b70c4SDavid E. O'Brien	umask $mkdir_umask &&
371974b70c4SDavid E. O'Brien	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
372974b70c4SDavid E. O'Brien      )
373974b70c4SDavid E. O'Brien    then :
374974b70c4SDavid E. O'Brien    else
375974b70c4SDavid E. O'Brien
376974b70c4SDavid E. O'Brien      # The umask is ridiculous, or mkdir does not conform to POSIX,
377974b70c4SDavid E. O'Brien      # or it failed possibly due to a race condition.  Create the
378974b70c4SDavid E. O'Brien      # directory the slow way, step by step, checking for races as we go.
379974b70c4SDavid E. O'Brien
380974b70c4SDavid E. O'Brien      case $dstdir in
381974b70c4SDavid E. O'Brien	/*) prefix=/ ;;
382974b70c4SDavid E. O'Brien	-*) prefix=./ ;;
383974b70c4SDavid E. O'Brien	*)  prefix= ;;
384974b70c4SDavid E. O'Brien      esac
385974b70c4SDavid E. O'Brien
386974b70c4SDavid E. O'Brien      case $posix_glob in
387974b70c4SDavid E. O'Brien        '')
388974b70c4SDavid E. O'Brien	  if (set -f) 2>/dev/null; then
389974b70c4SDavid E. O'Brien	    posix_glob=true
390974b70c4SDavid E. O'Brien	  else
391974b70c4SDavid E. O'Brien	    posix_glob=false
392974b70c4SDavid E. O'Brien	  fi ;;
393974b70c4SDavid E. O'Brien      esac
39475a6cdb3SDavid E. O'Brien
395d1d50c78SDavid E. O'Brien      oIFS=$IFS
396974b70c4SDavid E. O'Brien      IFS=/
397974b70c4SDavid E. O'Brien      $posix_glob && set -f
398974b70c4SDavid E. O'Brien      set fnord $dstdir
39975a6cdb3SDavid E. O'Brien      shift
400974b70c4SDavid E. O'Brien      $posix_glob && set +f
401d1d50c78SDavid E. O'Brien      IFS=$oIFS
40275a6cdb3SDavid E. O'Brien
403974b70c4SDavid E. O'Brien      prefixes=
404d1d50c78SDavid E. O'Brien
405974b70c4SDavid E. O'Brien      for d
406974b70c4SDavid E. O'Brien      do
407974b70c4SDavid E. O'Brien	test -z "$d" && continue
408974b70c4SDavid E. O'Brien
409974b70c4SDavid E. O'Brien	prefix=$prefix$d
410974b70c4SDavid E. O'Brien	if test -d "$prefix"; then
411974b70c4SDavid E. O'Brien	  prefixes=
412974b70c4SDavid E. O'Brien	else
413974b70c4SDavid E. O'Brien	  if $posix_mkdir; then
414974b70c4SDavid E. O'Brien	    (umask=$mkdir_umask &&
415974b70c4SDavid E. O'Brien	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
416974b70c4SDavid E. O'Brien	    # Don't fail if two instances are running concurrently.
417974b70c4SDavid E. O'Brien	    test -d "$prefix" || exit 1
418974b70c4SDavid E. O'Brien	  else
419974b70c4SDavid E. O'Brien	    case $prefix in
420974b70c4SDavid E. O'Brien	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
421974b70c4SDavid E. O'Brien	      *) qprefix=$prefix;;
422974b70c4SDavid E. O'Brien	    esac
423974b70c4SDavid E. O'Brien	    prefixes="$prefixes '$qprefix'"
42475a6cdb3SDavid E. O'Brien	  fi
425974b70c4SDavid E. O'Brien	fi
426974b70c4SDavid E. O'Brien	prefix=$prefix/
42775a6cdb3SDavid E. O'Brien      done
428974b70c4SDavid E. O'Brien
429974b70c4SDavid E. O'Brien      if test -n "$prefixes"; then
430974b70c4SDavid E. O'Brien	# Don't fail if two instances are running concurrently.
431974b70c4SDavid E. O'Brien	(umask $mkdir_umask &&
432974b70c4SDavid E. O'Brien	 eval "\$doit_exec \$mkdirprog $prefixes") ||
433974b70c4SDavid E. O'Brien	  test -d "$dstdir" || exit 1
434974b70c4SDavid E. O'Brien	obsolete_mkdir_used=true
435974b70c4SDavid E. O'Brien      fi
436974b70c4SDavid E. O'Brien    fi
43775a6cdb3SDavid E. O'Brien  fi
43875a6cdb3SDavid E. O'Brien
439d1d50c78SDavid E. O'Brien  if test -n "$dir_arg"; then
440974b70c4SDavid E. O'Brien    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
441974b70c4SDavid E. O'Brien    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
442974b70c4SDavid E. O'Brien    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
443974b70c4SDavid E. O'Brien      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44475a6cdb3SDavid E. O'Brien  else
44575a6cdb3SDavid E. O'Brien
446d1d50c78SDavid E. O'Brien    # Make a couple of temp file names in the proper directory.
447d1d50c78SDavid E. O'Brien    dsttmp=$dstdir/_inst.$$_
448d1d50c78SDavid E. O'Brien    rmtmp=$dstdir/_rm.$$_
44975a6cdb3SDavid E. O'Brien
450d1d50c78SDavid E. O'Brien    # Trap to clean up those temp files at exit.
451d1d50c78SDavid E. O'Brien    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45275a6cdb3SDavid E. O'Brien
453d1d50c78SDavid E. O'Brien    # Copy the file name to the temp name.
454974b70c4SDavid E. O'Brien    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
45575a6cdb3SDavid E. O'Brien
456d1d50c78SDavid E. O'Brien    # and set any options; do chmod last to preserve setuid bits.
457d1d50c78SDavid E. O'Brien    #
458d1d50c78SDavid E. O'Brien    # If any of these fail, we abort the whole thing.  If we want to
459d1d50c78SDavid E. O'Brien    # ignore errors from any of these, just make sure not to ignore
460d1d50c78SDavid E. O'Brien    # errors from the above "$doit $cpprog $src $dsttmp" command.
461d1d50c78SDavid E. O'Brien    #
462d1d50c78SDavid E. O'Brien    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
463d1d50c78SDavid E. O'Brien      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
464d1d50c78SDavid E. O'Brien      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
465974b70c4SDavid E. O'Brien      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
466d1d50c78SDavid E. O'Brien
467d1d50c78SDavid E. O'Brien    # Now rename the file to the real destination.
468974b70c4SDavid E. O'Brien    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
469d1d50c78SDavid E. O'Brien      || {
470d1d50c78SDavid E. O'Brien	   # The rename failed, perhaps because mv can't rename something else
471d1d50c78SDavid E. O'Brien	   # to itself, or perhaps because mv is so ancient that it does not
472d1d50c78SDavid E. O'Brien	   # support -f.
473d1d50c78SDavid E. O'Brien
474d1d50c78SDavid E. O'Brien	   # Now remove or move aside any old file at destination location.
475d1d50c78SDavid E. O'Brien	   # We try this two ways since rm can't unlink itself on some
476d1d50c78SDavid E. O'Brien	   # systems and the destination file might be busy for other
477d1d50c78SDavid E. O'Brien	   # reasons.  In this case, the final cleanup might fail but the new
478d1d50c78SDavid E. O'Brien	   # file should still install successfully.
479d1d50c78SDavid E. O'Brien	   {
480974b70c4SDavid E. O'Brien	     if test -f "$dst"; then
481974b70c4SDavid E. O'Brien	       $doit $rmcmd -f "$dst" 2>/dev/null \
482974b70c4SDavid E. O'Brien	       || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
483974b70c4SDavid E. O'Brien		     && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
484d1d50c78SDavid E. O'Brien	       || {
485974b70c4SDavid E. O'Brien		 echo "$0: cannot unlink or rename $dst" >&2
486d1d50c78SDavid E. O'Brien		 (exit 1); exit 1
487d1d50c78SDavid E. O'Brien	       }
48875a6cdb3SDavid E. O'Brien	     else
489a2e8fb4cSDavid E. O'Brien	       :
49075a6cdb3SDavid E. O'Brien	     fi
491d1d50c78SDavid E. O'Brien	   } &&
49275a6cdb3SDavid E. O'Brien
49375a6cdb3SDavid E. O'Brien	   # Now rename the file to the real destination.
494974b70c4SDavid E. O'Brien	   $doit $mvcmd "$dsttmp" "$dst"
495d1d50c78SDavid E. O'Brien	 }
496974b70c4SDavid E. O'Brien    } || exit 1
49775a6cdb3SDavid E. O'Brien
498974b70c4SDavid E. O'Brien    trap '' 0
499974b70c4SDavid E. O'Brien  fi
500974b70c4SDavid E. O'Briendone
50175a6cdb3SDavid E. O'Brien
502d1d50c78SDavid E. O'Brien# Local variables:
503d1d50c78SDavid E. O'Brien# eval: (add-hook 'write-file-hooks 'time-stamp)
504d1d50c78SDavid E. O'Brien# time-stamp-start: "scriptversion="
505d1d50c78SDavid E. O'Brien# time-stamp-format: "%:y-%02m-%02d.%02H"
506d1d50c78SDavid E. O'Brien# time-stamp-end: "$"
507d1d50c78SDavid E. O'Brien# End:
508