xref: /iperf/config/install-sh (revision aa8a3f4f)
1e34c20c8SJon Dugan#!/bin/sh
2e34c20c8SJon Dugan# install - install a program, script, or datafile
3e34c20c8SJon Dugan
4*aa8a3f4fSBruce A. Mahscriptversion=2020-11-14.01; # UTC
5e34c20c8SJon Dugan
6e34c20c8SJon Dugan# This originates from X11R5 (mit/util/scripts/install.sh), which was
7e34c20c8SJon Dugan# later released in X11R6 (xc/config/util/install.sh) with the
8e34c20c8SJon Dugan# following copyright and license.
9e34c20c8SJon Dugan#
10e34c20c8SJon Dugan# Copyright (C) 1994 X Consortium
11e34c20c8SJon Dugan#
12e34c20c8SJon Dugan# Permission is hereby granted, free of charge, to any person obtaining a copy
13e34c20c8SJon Dugan# of this software and associated documentation files (the "Software"), to
14e34c20c8SJon Dugan# deal in the Software without restriction, including without limitation the
15e34c20c8SJon Dugan# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16e34c20c8SJon Dugan# sell copies of the Software, and to permit persons to whom the Software is
17e34c20c8SJon Dugan# furnished to do so, subject to the following conditions:
18e34c20c8SJon Dugan#
19e34c20c8SJon Dugan# The above copyright notice and this permission notice shall be included in
20e34c20c8SJon Dugan# all copies or substantial portions of the Software.
21e34c20c8SJon Dugan#
22e34c20c8SJon Dugan# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23e34c20c8SJon Dugan# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24e34c20c8SJon Dugan# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25e34c20c8SJon Dugan# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26e34c20c8SJon Dugan# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27e34c20c8SJon Dugan# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28e34c20c8SJon Dugan#
29e34c20c8SJon Dugan# Except as contained in this notice, the name of the X Consortium shall not
30e34c20c8SJon Dugan# be used in advertising or otherwise to promote the sale, use or other deal-
31e34c20c8SJon Dugan# ings in this Software without prior written authorization from the X Consor-
32e34c20c8SJon Dugan# tium.
33e34c20c8SJon Dugan#
34e34c20c8SJon Dugan#
35e34c20c8SJon Dugan# FSF changes to this file are in the public domain.
36e34c20c8SJon Dugan#
37e34c20c8SJon Dugan# Calling this script install-sh is preferred over install.sh, to prevent
38487ee810SBruce A. Mah# 'make' implicit rules from creating a file called install from it
39e34c20c8SJon Dugan# when there is no Makefile.
40e34c20c8SJon Dugan#
41e34c20c8SJon Dugan# This script is compatible with the BSD install script, but was written
42487ee810SBruce A. Mah# from scratch.
43487ee810SBruce A. Mah
44*aa8a3f4fSBruce A. Mahtab='	'
45487ee810SBruce A. Mahnl='
46487ee810SBruce A. Mah'
47*aa8a3f4fSBruce A. MahIFS=" $tab$nl"
48e34c20c8SJon Dugan
49*aa8a3f4fSBruce A. Mah# Set DOITPROG to "echo" to test this script.
50e34c20c8SJon Dugan
51487ee810SBruce A. Mahdoit=${DOITPROG-}
52*aa8a3f4fSBruce A. Mahdoit_exec=${doit:-exec}
53e34c20c8SJon Dugan
54487ee810SBruce A. Mah# Put in absolute file names if you don't have them in your path;
55487ee810SBruce A. Mah# or use environment vars.
56e34c20c8SJon Dugan
57487ee810SBruce A. Mahchgrpprog=${CHGRPPROG-chgrp}
58487ee810SBruce A. Mahchmodprog=${CHMODPROG-chmod}
59487ee810SBruce A. Mahchownprog=${CHOWNPROG-chown}
60487ee810SBruce A. Mahcmpprog=${CMPPROG-cmp}
61487ee810SBruce A. Mahcpprog=${CPPROG-cp}
62487ee810SBruce A. Mahmkdirprog=${MKDIRPROG-mkdir}
63487ee810SBruce A. Mahmvprog=${MVPROG-mv}
64487ee810SBruce A. Mahrmprog=${RMPROG-rm}
65487ee810SBruce A. Mahstripprog=${STRIPPROG-strip}
66e34c20c8SJon Dugan
67487ee810SBruce A. Mahposix_mkdir=
68487ee810SBruce A. Mah
69487ee810SBruce A. Mah# Desired mode of installed file.
70487ee810SBruce A. Mahmode=0755
71487ee810SBruce A. Mah
72*aa8a3f4fSBruce A. Mah# Create dirs (including intermediate dirs) using mode 755.
73*aa8a3f4fSBruce A. Mah# This is like GNU 'install' as of coreutils 8.32 (2020).
74*aa8a3f4fSBruce A. Mahmkdir_umask=22
75*aa8a3f4fSBruce A. Mah
76*aa8a3f4fSBruce A. Mahbackupsuffix=
7756a97f93Sjefchgrpcmd=
78487ee810SBruce A. Mahchmodcmd=$chmodprog
79487ee810SBruce A. Mahchowncmd=
80487ee810SBruce A. Mahmvcmd=$mvprog
8156a97f93Sjefrmcmd="$rmprog -f"
82487ee810SBruce A. Mahstripcmd=
83487ee810SBruce A. Mah
84e34c20c8SJon Dugansrc=
85e34c20c8SJon Dugandst=
86e34c20c8SJon Dugandir_arg=
87487ee810SBruce A. Mahdst_arg=
88487ee810SBruce A. Mah
89487ee810SBruce A. Mahcopy_on_change=false
90*aa8a3f4fSBruce A. Mahis_target_a_directory=possibly
91e34c20c8SJon Dugan
92487ee810SBruce A. Mahusage="\
93487ee810SBruce A. MahUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
94e34c20c8SJon Dugan   or: $0 [OPTION]... SRCFILES... DIRECTORY
95e34c20c8SJon Dugan   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
96e34c20c8SJon Dugan   or: $0 [OPTION]... -d DIRECTORIES...
97e34c20c8SJon Dugan
98e34c20c8SJon DuganIn the 1st form, copy SRCFILE to DSTFILE.
99e34c20c8SJon DuganIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
100e34c20c8SJon DuganIn the 4th, create DIRECTORIES.
101e34c20c8SJon Dugan
102e34c20c8SJon DuganOptions:
103487ee810SBruce A. Mah     --help     display this help and exit.
104487ee810SBruce A. Mah     --version  display version info and exit.
105487ee810SBruce A. Mah
106e34c20c8SJon Dugan  -c            (ignored)
107*aa8a3f4fSBruce A. Mah  -C            install only if different (preserve data modification time)
108e34c20c8SJon Dugan  -d            create directories instead of installing files.
109e34c20c8SJon Dugan  -g GROUP      $chgrpprog installed files to GROUP.
110e34c20c8SJon Dugan  -m MODE       $chmodprog installed files to MODE.
111e34c20c8SJon Dugan  -o USER       $chownprog installed files to USER.
112*aa8a3f4fSBruce A. Mah  -p            pass -p to $cpprog.
113e34c20c8SJon Dugan  -s            $stripprog installed files.
114*aa8a3f4fSBruce A. Mah  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
115e34c20c8SJon Dugan  -t DIRECTORY  install into DIRECTORY.
116e34c20c8SJon Dugan  -T            report an error if DSTFILE is a directory.
117e34c20c8SJon Dugan
118e34c20c8SJon DuganEnvironment variables override the default commands:
119487ee810SBruce A. Mah  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
120487ee810SBruce A. Mah  RMPROG STRIPPROG
121*aa8a3f4fSBruce A. Mah
122*aa8a3f4fSBruce A. MahBy default, rm is invoked with -f; when overridden with RMPROG,
123*aa8a3f4fSBruce A. Mahit's up to you to specify -f if you want it.
124*aa8a3f4fSBruce A. Mah
125*aa8a3f4fSBruce A. MahIf -S is not specified, no backups are attempted.
126*aa8a3f4fSBruce A. Mah
127*aa8a3f4fSBruce A. MahEmail bug reports to [email protected].
128*aa8a3f4fSBruce A. MahAutomake home page: https://www.gnu.org/software/automake/
129e34c20c8SJon Dugan"
130e34c20c8SJon Dugan
131487ee810SBruce A. Mahwhile test $# -ne 0; do
132e34c20c8SJon Dugan  case $1 in
133487ee810SBruce A. Mah    -c) ;;
134e34c20c8SJon Dugan
135487ee810SBruce A. Mah    -C) copy_on_change=true;;
136487ee810SBruce A. Mah
137487ee810SBruce A. Mah    -d) dir_arg=true;;
138e34c20c8SJon Dugan
139e34c20c8SJon Dugan    -g) chgrpcmd="$chgrpprog $2"
140487ee810SBruce A. Mah        shift;;
141e34c20c8SJon Dugan
142e34c20c8SJon Dugan    --help) echo "$usage"; exit $?;;
143e34c20c8SJon Dugan
144487ee810SBruce A. Mah    -m) mode=$2
145487ee810SBruce A. Mah        case $mode in
146*aa8a3f4fSBruce A. Mah          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
147487ee810SBruce A. Mah            echo "$0: invalid mode: $mode" >&2
148487ee810SBruce A. Mah            exit 1;;
149487ee810SBruce A. Mah        esac
150487ee810SBruce A. Mah        shift;;
151e34c20c8SJon Dugan
152e34c20c8SJon Dugan    -o) chowncmd="$chownprog $2"
153487ee810SBruce A. Mah        shift;;
154e34c20c8SJon Dugan
155*aa8a3f4fSBruce A. Mah    -p) cpprog="$cpprog -p";;
156*aa8a3f4fSBruce A. Mah
157487ee810SBruce A. Mah    -s) stripcmd=$stripprog;;
158e34c20c8SJon Dugan
159*aa8a3f4fSBruce A. Mah    -S) backupsuffix="$2"
160*aa8a3f4fSBruce A. Mah        shift;;
161*aa8a3f4fSBruce A. Mah
162*aa8a3f4fSBruce A. Mah    -t)
163*aa8a3f4fSBruce A. Mah        is_target_a_directory=always
164*aa8a3f4fSBruce A. Mah        dst_arg=$2
165487ee810SBruce A. Mah        # Protect names problematic for 'test' and other utilities.
166487ee810SBruce A. Mah        case $dst_arg in
167487ee810SBruce A. Mah          -* | [=\(\)!]) dst_arg=./$dst_arg;;
168487ee810SBruce A. Mah        esac
169487ee810SBruce A. Mah        shift;;
170e34c20c8SJon Dugan
171*aa8a3f4fSBruce A. Mah    -T) is_target_a_directory=never;;
172e34c20c8SJon Dugan
173e34c20c8SJon Dugan    --version) echo "$0 $scriptversion"; exit $?;;
174e34c20c8SJon Dugan
175487ee810SBruce A. Mah    --) shift
176487ee810SBruce A. Mah        break;;
177487ee810SBruce A. Mah
178487ee810SBruce A. Mah    -*) echo "$0: invalid option: $1" >&2
179487ee810SBruce A. Mah        exit 1;;
180487ee810SBruce A. Mah
181487ee810SBruce A. Mah    *)  break;;
182487ee810SBruce A. Mah  esac
183487ee810SBruce A. Mah  shift
184487ee810SBruce A. Mahdone
185487ee810SBruce A. Mah
186*aa8a3f4fSBruce A. Mah# We allow the use of options -d and -T together, by making -d
187*aa8a3f4fSBruce A. Mah# take the precedence; this is for compatibility with GNU install.
188*aa8a3f4fSBruce A. Mah
189*aa8a3f4fSBruce A. Mahif test -n "$dir_arg"; then
190*aa8a3f4fSBruce A. Mah  if test -n "$dst_arg"; then
191*aa8a3f4fSBruce A. Mah    echo "$0: target directory not allowed when installing a directory." >&2
192*aa8a3f4fSBruce A. Mah    exit 1
193*aa8a3f4fSBruce A. Mah  fi
194*aa8a3f4fSBruce A. Mahfi
195*aa8a3f4fSBruce A. Mah
196487ee810SBruce A. Mahif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
197487ee810SBruce A. Mah  # When -d is used, all remaining arguments are directories to create.
198e34c20c8SJon Dugan  # When -t is used, the destination is already specified.
199e34c20c8SJon Dugan  # Otherwise, the last argument is the destination.  Remove it from $@.
200e34c20c8SJon Dugan  for arg
201e34c20c8SJon Dugan  do
202487ee810SBruce A. Mah    if test -n "$dst_arg"; then
203e34c20c8SJon Dugan      # $@ is not empty: it contains at least $arg.
204487ee810SBruce A. Mah      set fnord "$@" "$dst_arg"
205e34c20c8SJon Dugan      shift # fnord
206e34c20c8SJon Dugan    fi
207e34c20c8SJon Dugan    shift # arg
208487ee810SBruce A. Mah    dst_arg=$arg
209487ee810SBruce A. Mah    # Protect names problematic for 'test' and other utilities.
210487ee810SBruce A. Mah    case $dst_arg in
211487ee810SBruce A. Mah      -* | [=\(\)!]) dst_arg=./$dst_arg;;
21256a97f93Sjef    esac
21356a97f93Sjef  done
214487ee810SBruce A. Mahfi
215e34c20c8SJon Dugan
216487ee810SBruce A. Mahif test $# -eq 0; then
217e34c20c8SJon Dugan  if test -z "$dir_arg"; then
218e34c20c8SJon Dugan    echo "$0: no input file specified." >&2
219e34c20c8SJon Dugan    exit 1
220e34c20c8SJon Dugan  fi
221487ee810SBruce A. Mah  # It's OK to call 'install-sh -d' without argument.
222e34c20c8SJon Dugan  # This can happen when creating conditional directories.
223e34c20c8SJon Dugan  exit 0
224e34c20c8SJon Duganfi
225e34c20c8SJon Dugan
226487ee810SBruce A. Mahif test -z "$dir_arg"; then
227*aa8a3f4fSBruce A. Mah  if test $# -gt 1 || test "$is_target_a_directory" = always; then
228*aa8a3f4fSBruce A. Mah    if test ! -d "$dst_arg"; then
229*aa8a3f4fSBruce A. Mah      echo "$0: $dst_arg: Is not a directory." >&2
230*aa8a3f4fSBruce A. Mah      exit 1
231*aa8a3f4fSBruce A. Mah    fi
232*aa8a3f4fSBruce A. Mah  fi
233*aa8a3f4fSBruce A. Mahfi
234*aa8a3f4fSBruce A. Mah
235*aa8a3f4fSBruce A. Mahif test -z "$dir_arg"; then
236487ee810SBruce A. Mah  do_exit='(exit $ret); exit $ret'
237487ee810SBruce A. Mah  trap "ret=129; $do_exit" 1
238487ee810SBruce A. Mah  trap "ret=130; $do_exit" 2
239487ee810SBruce A. Mah  trap "ret=141; $do_exit" 13
240487ee810SBruce A. Mah  trap "ret=143; $do_exit" 15
241487ee810SBruce A. Mah
242487ee810SBruce A. Mah  # Set umask so as not to create temps with too-generous modes.
243487ee810SBruce A. Mah  # However, 'strip' requires both read and write access to temps.
244487ee810SBruce A. Mah  case $mode in
245487ee810SBruce A. Mah    # Optimize common cases.
246487ee810SBruce A. Mah    *644) cp_umask=133;;
247487ee810SBruce A. Mah    *755) cp_umask=22;;
248487ee810SBruce A. Mah
249487ee810SBruce A. Mah    *[0-7])
250487ee810SBruce A. Mah      if test -z "$stripcmd"; then
251487ee810SBruce A. Mah        u_plus_rw=
252487ee810SBruce A. Mah      else
253487ee810SBruce A. Mah        u_plus_rw='% 200'
254487ee810SBruce A. Mah      fi
255487ee810SBruce A. Mah      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
256487ee810SBruce A. Mah    *)
257487ee810SBruce A. Mah      if test -z "$stripcmd"; then
258487ee810SBruce A. Mah        u_plus_rw=
259487ee810SBruce A. Mah      else
260487ee810SBruce A. Mah        u_plus_rw=,u+rw
261487ee810SBruce A. Mah      fi
262487ee810SBruce A. Mah      cp_umask=$mode$u_plus_rw;;
263487ee810SBruce A. Mah  esac
264487ee810SBruce A. Mahfi
265487ee810SBruce A. Mah
266e34c20c8SJon Duganfor src
267e34c20c8SJon Dugando
268487ee810SBruce A. Mah  # Protect names problematic for 'test' and other utilities.
269e34c20c8SJon Dugan  case $src in
270487ee810SBruce A. Mah    -* | [=\(\)!]) src=./$src;;
271e34c20c8SJon Dugan  esac
272e34c20c8SJon Dugan
273e34c20c8SJon Dugan  if test -n "$dir_arg"; then
274e34c20c8SJon Dugan    dst=$src
275487ee810SBruce A. Mah    dstdir=$dst
276487ee810SBruce A. Mah    test -d "$dstdir"
277487ee810SBruce A. Mah    dstdir_status=$?
278*aa8a3f4fSBruce A. Mah    # Don't chown directories that already exist.
279*aa8a3f4fSBruce A. Mah    if test $dstdir_status = 0; then
280*aa8a3f4fSBruce A. Mah      chowncmd=""
281*aa8a3f4fSBruce A. Mah    fi
282487ee810SBruce A. Mah  else
283e34c20c8SJon Dugan
284e34c20c8SJon Dugan    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
285e34c20c8SJon Dugan    # might cause directories to be created, which would be especially bad
286e34c20c8SJon Dugan    # if $src (and thus $dsttmp) contains '*'.
287e34c20c8SJon Dugan    if test ! -f "$src" && test ! -d "$src"; then
288e34c20c8SJon Dugan      echo "$0: $src does not exist." >&2
289e34c20c8SJon Dugan      exit 1
290e34c20c8SJon Dugan    fi
291e34c20c8SJon Dugan
292487ee810SBruce A. Mah    if test -z "$dst_arg"; then
293e34c20c8SJon Dugan      echo "$0: no destination specified." >&2
294e34c20c8SJon Dugan      exit 1
295e34c20c8SJon Dugan    fi
296487ee810SBruce A. Mah    dst=$dst_arg
297e34c20c8SJon Dugan
298*aa8a3f4fSBruce A. Mah    # If destination is a directory, append the input filename.
299e34c20c8SJon Dugan    if test -d "$dst"; then
300*aa8a3f4fSBruce A. Mah      if test "$is_target_a_directory" = never; then
301487ee810SBruce A. Mah        echo "$0: $dst_arg: Is a directory" >&2
302e34c20c8SJon Dugan        exit 1
303e34c20c8SJon Dugan      fi
304487ee810SBruce A. Mah      dstdir=$dst
305*aa8a3f4fSBruce A. Mah      dstbase=`basename "$src"`
306*aa8a3f4fSBruce A. Mah      case $dst in
307*aa8a3f4fSBruce A. Mah	*/) dst=$dst$dstbase;;
308*aa8a3f4fSBruce A. Mah	*)  dst=$dst/$dstbase;;
309*aa8a3f4fSBruce A. Mah      esac
310487ee810SBruce A. Mah      dstdir_status=0
311487ee810SBruce A. Mah    else
312*aa8a3f4fSBruce A. Mah      dstdir=`dirname "$dst"`
313487ee810SBruce A. Mah      test -d "$dstdir"
314487ee810SBruce A. Mah      dstdir_status=$?
315e34c20c8SJon Dugan    fi
316e34c20c8SJon Dugan  fi
317e34c20c8SJon Dugan
318*aa8a3f4fSBruce A. Mah  case $dstdir in
319*aa8a3f4fSBruce A. Mah    */) dstdirslash=$dstdir;;
320*aa8a3f4fSBruce A. Mah    *)  dstdirslash=$dstdir/;;
321*aa8a3f4fSBruce A. Mah  esac
322*aa8a3f4fSBruce A. Mah
323487ee810SBruce A. Mah  obsolete_mkdir_used=false
324e34c20c8SJon Dugan
325487ee810SBruce A. Mah  if test $dstdir_status != 0; then
326487ee810SBruce A. Mah    case $posix_mkdir in
327487ee810SBruce A. Mah      '')
328487ee810SBruce A. Mah        # With -d, create the new directory with the user-specified mode.
329487ee810SBruce A. Mah        # Otherwise, rely on $mkdir_umask.
330487ee810SBruce A. Mah        if test -n "$dir_arg"; then
331487ee810SBruce A. Mah          mkdir_mode=-m$mode
332487ee810SBruce A. Mah        else
333487ee810SBruce A. Mah          mkdir_mode=
334487ee810SBruce A. Mah        fi
335487ee810SBruce A. Mah
336487ee810SBruce A. Mah        posix_mkdir=false
337*aa8a3f4fSBruce A. Mah	# The $RANDOM variable is not portable (e.g., dash).  Use it
338*aa8a3f4fSBruce A. Mah	# here however when possible just to lower collision chance.
339487ee810SBruce A. Mah	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
340487ee810SBruce A. Mah
341*aa8a3f4fSBruce A. Mah	trap '
342*aa8a3f4fSBruce A. Mah	  ret=$?
343*aa8a3f4fSBruce A. Mah	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
344*aa8a3f4fSBruce A. Mah	  exit $ret
345*aa8a3f4fSBruce A. Mah	' 0
346*aa8a3f4fSBruce A. Mah
347*aa8a3f4fSBruce A. Mah	# Because "mkdir -p" follows existing symlinks and we likely work
348*aa8a3f4fSBruce A. Mah	# directly in world-writeable /tmp, make sure that the '$tmpdir'
349*aa8a3f4fSBruce A. Mah	# directory is successfully created first before we actually test
350*aa8a3f4fSBruce A. Mah	# 'mkdir -p'.
351487ee810SBruce A. Mah	if (umask $mkdir_umask &&
352*aa8a3f4fSBruce A. Mah	    $mkdirprog $mkdir_mode "$tmpdir" &&
353*aa8a3f4fSBruce A. Mah	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
354487ee810SBruce A. Mah	then
355487ee810SBruce A. Mah	  if test -z "$dir_arg" || {
356487ee810SBruce A. Mah	       # Check for POSIX incompatibilities with -m.
357487ee810SBruce A. Mah	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
358487ee810SBruce A. Mah	       # other-writable bit of parent directory when it shouldn't.
359487ee810SBruce A. Mah	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
360*aa8a3f4fSBruce A. Mah	       test_tmpdir="$tmpdir/a"
361*aa8a3f4fSBruce A. Mah	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
362487ee810SBruce A. Mah	       case $ls_ld_tmpdir in
363487ee810SBruce A. Mah		 d????-?r-*) different_mode=700;;
364487ee810SBruce A. Mah		 d????-?--*) different_mode=755;;
365487ee810SBruce A. Mah		 *) false;;
366487ee810SBruce A. Mah	       esac &&
367*aa8a3f4fSBruce A. Mah	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
368*aa8a3f4fSBruce A. Mah		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
369487ee810SBruce A. Mah		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
370487ee810SBruce A. Mah	       }
371487ee810SBruce A. Mah	     }
372487ee810SBruce A. Mah	  then posix_mkdir=:
373487ee810SBruce A. Mah	  fi
374*aa8a3f4fSBruce A. Mah	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
375487ee810SBruce A. Mah	else
376487ee810SBruce A. Mah	  # Remove any dirs left behind by ancient mkdir implementations.
377*aa8a3f4fSBruce A. Mah	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
378487ee810SBruce A. Mah	fi
379487ee810SBruce A. Mah	trap '' 0;;
380487ee810SBruce A. Mah    esac
381487ee810SBruce A. Mah
382487ee810SBruce A. Mah    if
383487ee810SBruce A. Mah      $posix_mkdir && (
384487ee810SBruce A. Mah        umask $mkdir_umask &&
385487ee810SBruce A. Mah        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
386487ee810SBruce A. Mah      )
387487ee810SBruce A. Mah    then :
388487ee810SBruce A. Mah    else
389487ee810SBruce A. Mah
390*aa8a3f4fSBruce A. Mah      # mkdir does not conform to POSIX,
391487ee810SBruce A. Mah      # or it failed possibly due to a race condition.  Create the
392487ee810SBruce A. Mah      # directory the slow way, step by step, checking for races as we go.
393487ee810SBruce A. Mah
394487ee810SBruce A. Mah      case $dstdir in
395487ee810SBruce A. Mah        /*) prefix='/';;
396487ee810SBruce A. Mah        [-=\(\)!]*) prefix='./';;
397487ee810SBruce A. Mah        *)  prefix='';;
398487ee810SBruce A. Mah      esac
399487ee810SBruce A. Mah
400e34c20c8SJon Dugan      oIFS=$IFS
401487ee810SBruce A. Mah      IFS=/
402*aa8a3f4fSBruce A. Mah      set -f
403487ee810SBruce A. Mah      set fnord $dstdir
404e34c20c8SJon Dugan      shift
405*aa8a3f4fSBruce A. Mah      set +f
406e34c20c8SJon Dugan      IFS=$oIFS
407e34c20c8SJon Dugan
408487ee810SBruce A. Mah      prefixes=
409e34c20c8SJon Dugan
410487ee810SBruce A. Mah      for d
411487ee810SBruce A. Mah      do
412487ee810SBruce A. Mah        test X"$d" = X && continue
413487ee810SBruce A. Mah
414487ee810SBruce A. Mah        prefix=$prefix$d
415487ee810SBruce A. Mah        if test -d "$prefix"; then
416487ee810SBruce A. Mah          prefixes=
417487ee810SBruce A. Mah        else
418487ee810SBruce A. Mah          if $posix_mkdir; then
419*aa8a3f4fSBruce A. Mah            (umask $mkdir_umask &&
420487ee810SBruce A. Mah             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
421487ee810SBruce A. Mah            # Don't fail if two instances are running concurrently.
422487ee810SBruce A. Mah            test -d "$prefix" || exit 1
423487ee810SBruce A. Mah          else
424487ee810SBruce A. Mah            case $prefix in
425487ee810SBruce A. Mah              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
426487ee810SBruce A. Mah              *) qprefix=$prefix;;
427487ee810SBruce A. Mah            esac
428487ee810SBruce A. Mah            prefixes="$prefixes '$qprefix'"
429e34c20c8SJon Dugan          fi
430487ee810SBruce A. Mah        fi
431487ee810SBruce A. Mah        prefix=$prefix/
432e34c20c8SJon Dugan      done
433487ee810SBruce A. Mah
434487ee810SBruce A. Mah      if test -n "$prefixes"; then
435487ee810SBruce A. Mah        # Don't fail if two instances are running concurrently.
436487ee810SBruce A. Mah        (umask $mkdir_umask &&
437487ee810SBruce A. Mah         eval "\$doit_exec \$mkdirprog $prefixes") ||
438487ee810SBruce A. Mah          test -d "$dstdir" || exit 1
439487ee810SBruce A. Mah        obsolete_mkdir_used=true
440487ee810SBruce A. Mah      fi
441487ee810SBruce A. Mah    fi
442e34c20c8SJon Dugan  fi
443e34c20c8SJon Dugan
444e34c20c8SJon Dugan  if test -n "$dir_arg"; then
445487ee810SBruce A. Mah    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
446487ee810SBruce A. Mah    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
447487ee810SBruce A. Mah    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
448487ee810SBruce A. Mah      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
449e34c20c8SJon Dugan  else
450e34c20c8SJon Dugan
451e34c20c8SJon Dugan    # Make a couple of temp file names in the proper directory.
452*aa8a3f4fSBruce A. Mah    dsttmp=${dstdirslash}_inst.$$_
453*aa8a3f4fSBruce A. Mah    rmtmp=${dstdirslash}_rm.$$_
454e34c20c8SJon Dugan
455e34c20c8SJon Dugan    # Trap to clean up those temp files at exit.
456e34c20c8SJon Dugan    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
457e34c20c8SJon Dugan
458e34c20c8SJon Dugan    # Copy the file name to the temp name.
459*aa8a3f4fSBruce A. Mah    (umask $cp_umask &&
460*aa8a3f4fSBruce A. Mah     { test -z "$stripcmd" || {
461*aa8a3f4fSBruce A. Mah	 # Create $dsttmp read-write so that cp doesn't create it read-only,
462*aa8a3f4fSBruce A. Mah	 # which would cause strip to fail.
463*aa8a3f4fSBruce A. Mah	 if test -z "$doit"; then
464*aa8a3f4fSBruce A. Mah	   : >"$dsttmp" # No need to fork-exec 'touch'.
465*aa8a3f4fSBruce A. Mah	 else
466*aa8a3f4fSBruce A. Mah	   $doit touch "$dsttmp"
467*aa8a3f4fSBruce A. Mah	 fi
468*aa8a3f4fSBruce A. Mah       }
469*aa8a3f4fSBruce A. Mah     } &&
470*aa8a3f4fSBruce A. Mah     $doit_exec $cpprog "$src" "$dsttmp") &&
471e34c20c8SJon Dugan
472e34c20c8SJon Dugan    # and set any options; do chmod last to preserve setuid bits.
473e34c20c8SJon Dugan    #
474e34c20c8SJon Dugan    # If any of these fail, we abort the whole thing.  If we want to
475e34c20c8SJon Dugan    # ignore errors from any of these, just make sure not to ignore
476e34c20c8SJon Dugan    # errors from the above "$doit $cpprog $src $dsttmp" command.
477e34c20c8SJon Dugan    #
478487ee810SBruce A. Mah    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
479487ee810SBruce A. Mah    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
480487ee810SBruce A. Mah    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
481487ee810SBruce A. Mah    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
482e34c20c8SJon Dugan
483487ee810SBruce A. Mah    # If -C, don't bother to copy if it wouldn't change the file.
484487ee810SBruce A. Mah    if $copy_on_change &&
485487ee810SBruce A. Mah       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
486487ee810SBruce A. Mah       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
487*aa8a3f4fSBruce A. Mah       set -f &&
488487ee810SBruce A. Mah       set X $old && old=:$2:$4:$5:$6 &&
489487ee810SBruce A. Mah       set X $new && new=:$2:$4:$5:$6 &&
490*aa8a3f4fSBruce A. Mah       set +f &&
491487ee810SBruce A. Mah       test "$old" = "$new" &&
492487ee810SBruce A. Mah       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
493487ee810SBruce A. Mah    then
494487ee810SBruce A. Mah      rm -f "$dsttmp"
495487ee810SBruce A. Mah    else
496*aa8a3f4fSBruce A. Mah      # If $backupsuffix is set, and the file being installed
497*aa8a3f4fSBruce A. Mah      # already exists, attempt a backup.  Don't worry if it fails,
498*aa8a3f4fSBruce A. Mah      # e.g., if mv doesn't support -f.
499*aa8a3f4fSBruce A. Mah      if test -n "$backupsuffix" && test -f "$dst"; then
500*aa8a3f4fSBruce A. Mah        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
501*aa8a3f4fSBruce A. Mah      fi
502*aa8a3f4fSBruce A. Mah
503487ee810SBruce A. Mah      # Rename the file to the real destination.
504487ee810SBruce A. Mah      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
505487ee810SBruce A. Mah
506e34c20c8SJon Dugan      # The rename failed, perhaps because mv can't rename something else
507e34c20c8SJon Dugan      # to itself, or perhaps because mv is so ancient that it does not
508e34c20c8SJon Dugan      # support -f.
509487ee810SBruce A. Mah      {
510e34c20c8SJon Dugan        # Now remove or move aside any old file at destination location.
511e34c20c8SJon Dugan        # We try this two ways since rm can't unlink itself on some
512e34c20c8SJon Dugan        # systems and the destination file might be busy for other
513e34c20c8SJon Dugan        # reasons.  In this case, the final cleanup might fail but the new
514e34c20c8SJon Dugan        # file should still install successfully.
515e34c20c8SJon Dugan        {
516487ee810SBruce A. Mah          test ! -f "$dst" ||
517*aa8a3f4fSBruce A. Mah          $doit $rmcmd "$dst" 2>/dev/null ||
518487ee810SBruce A. Mah          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
519*aa8a3f4fSBruce A. Mah            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
520487ee810SBruce A. Mah          } ||
521487ee810SBruce A. Mah          { echo "$0: cannot unlink or rename $dst" >&2
522e34c20c8SJon Dugan            (exit 1); exit 1
523e34c20c8SJon Dugan          }
524e34c20c8SJon Dugan        } &&
525e34c20c8SJon Dugan
526e34c20c8SJon Dugan        # Now rename the file to the real destination.
527487ee810SBruce A. Mah        $doit $mvcmd "$dsttmp" "$dst"
528e34c20c8SJon Dugan      }
529487ee810SBruce A. Mah    fi || exit 1
530e34c20c8SJon Dugan
531487ee810SBruce A. Mah    trap '' 0
532487ee810SBruce A. Mah  fi
533487ee810SBruce A. Mahdone
53456a97f93Sjef
535e34c20c8SJon Dugan# Local variables:
536*aa8a3f4fSBruce A. Mah# eval: (add-hook 'before-save-hook 'time-stamp)
537e34c20c8SJon Dugan# time-stamp-start: "scriptversion="
538e34c20c8SJon Dugan# time-stamp-format: "%:y-%02m-%02d.%02H"
539*aa8a3f4fSBruce A. Mah# time-stamp-time-zone: "UTC0"
540487ee810SBruce A. Mah# time-stamp-end: "; # UTC"
541e34c20c8SJon Dugan# End:
542