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