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