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