188cd5fc2Smrg#!/bin/sh
288cd5fc2Smrg# install - install a program, script, or datafile
388cd5fc2Smrg
4a33c354dSmrgscriptversion=2020-11-14.01; # UTC
588cd5fc2Smrg
688cd5fc2Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
788cd5fc2Smrg# later released in X11R6 (xc/config/util/install.sh) with the
888cd5fc2Smrg# following copyright and license.
988cd5fc2Smrg#
1088cd5fc2Smrg# Copyright (C) 1994 X Consortium
1188cd5fc2Smrg#
1288cd5fc2Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1388cd5fc2Smrg# of this software and associated documentation files (the "Software"), to
1488cd5fc2Smrg# deal in the Software without restriction, including without limitation the
1588cd5fc2Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1688cd5fc2Smrg# sell copies of the Software, and to permit persons to whom the Software is
1788cd5fc2Smrg# furnished to do so, subject to the following conditions:
1888cd5fc2Smrg#
1988cd5fc2Smrg# The above copyright notice and this permission notice shall be included in
2088cd5fc2Smrg# all copies or substantial portions of the Software.
2188cd5fc2Smrg#
2288cd5fc2Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2388cd5fc2Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2488cd5fc2Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2588cd5fc2Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2688cd5fc2Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2788cd5fc2Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2888cd5fc2Smrg#
2988cd5fc2Smrg# Except as contained in this notice, the name of the X Consortium shall not
3088cd5fc2Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3188cd5fc2Smrg# ings in this Software without prior written authorization from the X Consor-
3288cd5fc2Smrg# tium.
3388cd5fc2Smrg#
3488cd5fc2Smrg#
3588cd5fc2Smrg# FSF changes to this file are in the public domain.
3688cd5fc2Smrg#
3788cd5fc2Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3888cd5fc2Smrg# 'make' implicit rules from creating a file called install from it
3988cd5fc2Smrg# when there is no Makefile.
4088cd5fc2Smrg#
4188cd5fc2Smrg# This script is compatible with the BSD install script, but was written
4288cd5fc2Smrg# from scratch.
4388cd5fc2Smrg
44a33c354dSmrgtab='	'
4588cd5fc2Smrgnl='
4688cd5fc2Smrg'
47a33c354dSmrgIFS=" $tab$nl"
4888cd5fc2Smrg
49a33c354dSmrg# Set DOITPROG to "echo" to test this script.
5088cd5fc2Smrg
5188cd5fc2Smrgdoit=${DOITPROG-}
52a33c354dSmrgdoit_exec=${doit:-exec}
5388cd5fc2Smrg
5488cd5fc2Smrg# Put in absolute file names if you don't have them in your path;
5588cd5fc2Smrg# or use environment vars.
5688cd5fc2Smrg
5788cd5fc2Smrgchgrpprog=${CHGRPPROG-chgrp}
5888cd5fc2Smrgchmodprog=${CHMODPROG-chmod}
5988cd5fc2Smrgchownprog=${CHOWNPROG-chown}
6088cd5fc2Smrgcmpprog=${CMPPROG-cmp}
6188cd5fc2Smrgcpprog=${CPPROG-cp}
6288cd5fc2Smrgmkdirprog=${MKDIRPROG-mkdir}
6388cd5fc2Smrgmvprog=${MVPROG-mv}
6488cd5fc2Smrgrmprog=${RMPROG-rm}
6588cd5fc2Smrgstripprog=${STRIPPROG-strip}
6688cd5fc2Smrg
6788cd5fc2Smrgposix_mkdir=
6888cd5fc2Smrg
6988cd5fc2Smrg# Desired mode of installed file.
7088cd5fc2Smrgmode=0755
7188cd5fc2Smrg
72a33c354dSmrg# Create dirs (including intermediate dirs) using mode 755.
73a33c354dSmrg# This is like GNU 'install' as of coreutils 8.32 (2020).
74a33c354dSmrgmkdir_umask=22
75a33c354dSmrg
76a33c354dSmrgbackupsuffix=
7788cd5fc2Smrgchgrpcmd=
7888cd5fc2Smrgchmodcmd=$chmodprog
7988cd5fc2Smrgchowncmd=
8088cd5fc2Smrgmvcmd=$mvprog
8188cd5fc2Smrgrmcmd="$rmprog -f"
8288cd5fc2Smrgstripcmd=
8388cd5fc2Smrg
8488cd5fc2Smrgsrc=
8588cd5fc2Smrgdst=
8688cd5fc2Smrgdir_arg=
8788cd5fc2Smrgdst_arg=
8888cd5fc2Smrg
8988cd5fc2Smrgcopy_on_change=false
90a33c354dSmrgis_target_a_directory=possibly
9188cd5fc2Smrg
9288cd5fc2Smrgusage="\
9388cd5fc2SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
9488cd5fc2Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9588cd5fc2Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9688cd5fc2Smrg   or: $0 [OPTION]... -d DIRECTORIES...
9788cd5fc2Smrg
9888cd5fc2SmrgIn the 1st form, copy SRCFILE to DSTFILE.
9988cd5fc2SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
10088cd5fc2SmrgIn the 4th, create DIRECTORIES.
10188cd5fc2Smrg
10288cd5fc2SmrgOptions:
10388cd5fc2Smrg     --help     display this help and exit.
10488cd5fc2Smrg     --version  display version info and exit.
10588cd5fc2Smrg
10688cd5fc2Smrg  -c            (ignored)
107a33c354dSmrg  -C            install only if different (preserve data modification time)
10888cd5fc2Smrg  -d            create directories instead of installing files.
10988cd5fc2Smrg  -g GROUP      $chgrpprog installed files to GROUP.
11088cd5fc2Smrg  -m MODE       $chmodprog installed files to MODE.
11188cd5fc2Smrg  -o USER       $chownprog installed files to USER.
112a33c354dSmrg  -p            pass -p to $cpprog.
11388cd5fc2Smrg  -s            $stripprog installed files.
114a33c354dSmrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
11588cd5fc2Smrg  -t DIRECTORY  install into DIRECTORY.
11688cd5fc2Smrg  -T            report an error if DSTFILE is a directory.
11788cd5fc2Smrg
11888cd5fc2SmrgEnvironment variables override the default commands:
11988cd5fc2Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
12088cd5fc2Smrg  RMPROG STRIPPROG
121a33c354dSmrg
122a33c354dSmrgBy default, rm is invoked with -f; when overridden with RMPROG,
123a33c354dSmrgit's up to you to specify -f if you want it.
124a33c354dSmrg
125a33c354dSmrgIf -S is not specified, no backups are attempted.
126a33c354dSmrg
127a33c354dSmrgEmail bug reports to bug-automake@gnu.org.
128a33c354dSmrgAutomake home page: https://www.gnu.org/software/automake/
12988cd5fc2Smrg"
13088cd5fc2Smrg
13188cd5fc2Smrgwhile test $# -ne 0; do
13288cd5fc2Smrg  case $1 in
13388cd5fc2Smrg    -c) ;;
13488cd5fc2Smrg
13588cd5fc2Smrg    -C) copy_on_change=true;;
13688cd5fc2Smrg
13788cd5fc2Smrg    -d) dir_arg=true;;
13888cd5fc2Smrg
13988cd5fc2Smrg    -g) chgrpcmd="$chgrpprog $2"
140a33c354dSmrg        shift;;
14188cd5fc2Smrg
14288cd5fc2Smrg    --help) echo "$usage"; exit $?;;
14388cd5fc2Smrg
14488cd5fc2Smrg    -m) mode=$2
145a33c354dSmrg        case $mode in
146a33c354dSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
147a33c354dSmrg            echo "$0: invalid mode: $mode" >&2
148a33c354dSmrg            exit 1;;
149a33c354dSmrg        esac
150a33c354dSmrg        shift;;
15188cd5fc2Smrg
15288cd5fc2Smrg    -o) chowncmd="$chownprog $2"
153a33c354dSmrg        shift;;
154a33c354dSmrg
155a33c354dSmrg    -p) cpprog="$cpprog -p";;
15688cd5fc2Smrg
15788cd5fc2Smrg    -s) stripcmd=$stripprog;;
15888cd5fc2Smrg
159a33c354dSmrg    -S) backupsuffix="$2"
160a33c354dSmrg        shift;;
16188cd5fc2Smrg
162a33c354dSmrg    -t)
163a33c354dSmrg        is_target_a_directory=always
164a33c354dSmrg        dst_arg=$2
165a33c354dSmrg        # Protect names problematic for 'test' and other utilities.
166a33c354dSmrg        case $dst_arg in
167a33c354dSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
168a33c354dSmrg        esac
169a33c354dSmrg        shift;;
170a33c354dSmrg
171a33c354dSmrg    -T) is_target_a_directory=never;;
17288cd5fc2Smrg
17388cd5fc2Smrg    --version) echo "$0 $scriptversion"; exit $?;;
17488cd5fc2Smrg
175a33c354dSmrg    --) shift
176a33c354dSmrg        break;;
17788cd5fc2Smrg
178a33c354dSmrg    -*) echo "$0: invalid option: $1" >&2
179a33c354dSmrg        exit 1;;
18088cd5fc2Smrg
18188cd5fc2Smrg    *)  break;;
18288cd5fc2Smrg  esac
18388cd5fc2Smrg  shift
18488cd5fc2Smrgdone
18588cd5fc2Smrg
186a33c354dSmrg# We allow the use of options -d and -T together, by making -d
187a33c354dSmrg# take the precedence; this is for compatibility with GNU install.
188a33c354dSmrg
189a33c354dSmrgif test -n "$dir_arg"; then
190a33c354dSmrg  if test -n "$dst_arg"; then
191a33c354dSmrg    echo "$0: target directory not allowed when installing a directory." >&2
192a33c354dSmrg    exit 1
193a33c354dSmrg  fi
194a33c354dSmrgfi
195a33c354dSmrg
19688cd5fc2Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
19788cd5fc2Smrg  # When -d is used, all remaining arguments are directories to create.
19888cd5fc2Smrg  # When -t is used, the destination is already specified.
19988cd5fc2Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
20088cd5fc2Smrg  for arg
20188cd5fc2Smrg  do
20288cd5fc2Smrg    if test -n "$dst_arg"; then
20388cd5fc2Smrg      # $@ is not empty: it contains at least $arg.
20488cd5fc2Smrg      set fnord "$@" "$dst_arg"
20588cd5fc2Smrg      shift # fnord
20688cd5fc2Smrg    fi
20788cd5fc2Smrg    shift # arg
20888cd5fc2Smrg    dst_arg=$arg
20988cd5fc2Smrg    # Protect names problematic for 'test' and other utilities.
21088cd5fc2Smrg    case $dst_arg in
21188cd5fc2Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
21288cd5fc2Smrg    esac
21388cd5fc2Smrg  done
21488cd5fc2Smrgfi
21588cd5fc2Smrg
21688cd5fc2Smrgif test $# -eq 0; then
21788cd5fc2Smrg  if test -z "$dir_arg"; then
21888cd5fc2Smrg    echo "$0: no input file specified." >&2
21988cd5fc2Smrg    exit 1
22088cd5fc2Smrg  fi
22188cd5fc2Smrg  # It's OK to call 'install-sh -d' without argument.
22288cd5fc2Smrg  # This can happen when creating conditional directories.
22388cd5fc2Smrg  exit 0
22488cd5fc2Smrgfi
22588cd5fc2Smrg
226a33c354dSmrgif test -z "$dir_arg"; then
227a33c354dSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
228a33c354dSmrg    if test ! -d "$dst_arg"; then
229a33c354dSmrg      echo "$0: $dst_arg: Is not a directory." >&2
230a33c354dSmrg      exit 1
231a33c354dSmrg    fi
232a33c354dSmrg  fi
233a33c354dSmrgfi
234a33c354dSmrg
23588cd5fc2Smrgif test -z "$dir_arg"; then
23688cd5fc2Smrg  do_exit='(exit $ret); exit $ret'
23788cd5fc2Smrg  trap "ret=129; $do_exit" 1
23888cd5fc2Smrg  trap "ret=130; $do_exit" 2
23988cd5fc2Smrg  trap "ret=141; $do_exit" 13
24088cd5fc2Smrg  trap "ret=143; $do_exit" 15
24188cd5fc2Smrg
24288cd5fc2Smrg  # Set umask so as not to create temps with too-generous modes.
24388cd5fc2Smrg  # However, 'strip' requires both read and write access to temps.
24488cd5fc2Smrg  case $mode in
24588cd5fc2Smrg    # Optimize common cases.
24688cd5fc2Smrg    *644) cp_umask=133;;
24788cd5fc2Smrg    *755) cp_umask=22;;
24888cd5fc2Smrg
24988cd5fc2Smrg    *[0-7])
25088cd5fc2Smrg      if test -z "$stripcmd"; then
251a33c354dSmrg        u_plus_rw=
25288cd5fc2Smrg      else
253a33c354dSmrg        u_plus_rw='% 200'
25488cd5fc2Smrg      fi
25588cd5fc2Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
25688cd5fc2Smrg    *)
25788cd5fc2Smrg      if test -z "$stripcmd"; then
258a33c354dSmrg        u_plus_rw=
25988cd5fc2Smrg      else
260a33c354dSmrg        u_plus_rw=,u+rw
26188cd5fc2Smrg      fi
26288cd5fc2Smrg      cp_umask=$mode$u_plus_rw;;
26388cd5fc2Smrg  esac
26488cd5fc2Smrgfi
26588cd5fc2Smrg
26688cd5fc2Smrgfor src
26788cd5fc2Smrgdo
26888cd5fc2Smrg  # Protect names problematic for 'test' and other utilities.
26988cd5fc2Smrg  case $src in
27088cd5fc2Smrg    -* | [=\(\)!]) src=./$src;;
27188cd5fc2Smrg  esac
27288cd5fc2Smrg
27388cd5fc2Smrg  if test -n "$dir_arg"; then
27488cd5fc2Smrg    dst=$src
27588cd5fc2Smrg    dstdir=$dst
27688cd5fc2Smrg    test -d "$dstdir"
27788cd5fc2Smrg    dstdir_status=$?
278a33c354dSmrg    # Don't chown directories that already exist.
279a33c354dSmrg    if test $dstdir_status = 0; then
280a33c354dSmrg      chowncmd=""
281a33c354dSmrg    fi
28288cd5fc2Smrg  else
28388cd5fc2Smrg
28488cd5fc2Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
28588cd5fc2Smrg    # might cause directories to be created, which would be especially bad
28688cd5fc2Smrg    # if $src (and thus $dsttmp) contains '*'.
28788cd5fc2Smrg    if test ! -f "$src" && test ! -d "$src"; then
28888cd5fc2Smrg      echo "$0: $src does not exist." >&2
28988cd5fc2Smrg      exit 1
29088cd5fc2Smrg    fi
29188cd5fc2Smrg
29288cd5fc2Smrg    if test -z "$dst_arg"; then
29388cd5fc2Smrg      echo "$0: no destination specified." >&2
29488cd5fc2Smrg      exit 1
29588cd5fc2Smrg    fi
29688cd5fc2Smrg    dst=$dst_arg
29788cd5fc2Smrg
298a33c354dSmrg    # If destination is a directory, append the input filename.
29988cd5fc2Smrg    if test -d "$dst"; then
300a33c354dSmrg      if test "$is_target_a_directory" = never; then
301a33c354dSmrg        echo "$0: $dst_arg: Is a directory" >&2
302a33c354dSmrg        exit 1
30388cd5fc2Smrg      fi
30488cd5fc2Smrg      dstdir=$dst
305a33c354dSmrg      dstbase=`basename "$src"`
306a33c354dSmrg      case $dst in
307a33c354dSmrg	*/) dst=$dst$dstbase;;
308a33c354dSmrg	*)  dst=$dst/$dstbase;;
309a33c354dSmrg      esac
31088cd5fc2Smrg      dstdir_status=0
31188cd5fc2Smrg    else
312a33c354dSmrg      dstdir=`dirname "$dst"`
31388cd5fc2Smrg      test -d "$dstdir"
31488cd5fc2Smrg      dstdir_status=$?
31588cd5fc2Smrg    fi
31688cd5fc2Smrg  fi
31788cd5fc2Smrg
318a33c354dSmrg  case $dstdir in
319a33c354dSmrg    */) dstdirslash=$dstdir;;
320a33c354dSmrg    *)  dstdirslash=$dstdir/;;
321a33c354dSmrg  esac
322a33c354dSmrg
32388cd5fc2Smrg  obsolete_mkdir_used=false
32488cd5fc2Smrg
32588cd5fc2Smrg  if test $dstdir_status != 0; then
32688cd5fc2Smrg    case $posix_mkdir in
32788cd5fc2Smrg      '')
328a33c354dSmrg        # With -d, create the new directory with the user-specified mode.
329a33c354dSmrg        # Otherwise, rely on $mkdir_umask.
330a33c354dSmrg        if test -n "$dir_arg"; then
331a33c354dSmrg          mkdir_mode=-m$mode
332a33c354dSmrg        else
333a33c354dSmrg          mkdir_mode=
334a33c354dSmrg        fi
335a33c354dSmrg
336a33c354dSmrg        posix_mkdir=false
337a33c354dSmrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
338a33c354dSmrg	# here however when possible just to lower collision chance.
339a33c354dSmrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
340a33c354dSmrg
341a33c354dSmrg	trap '
342a33c354dSmrg	  ret=$?
343a33c354dSmrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
344a33c354dSmrg	  exit $ret
345a33c354dSmrg	' 0
346a33c354dSmrg
347a33c354dSmrg	# Because "mkdir -p" follows existing symlinks and we likely work
348a33c354dSmrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
349a33c354dSmrg	# directory is successfully created first before we actually test
350a33c354dSmrg	# 'mkdir -p'.
351a33c354dSmrg	if (umask $mkdir_umask &&
352a33c354dSmrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
353a33c354dSmrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
354a33c354dSmrg	then
355a33c354dSmrg	  if test -z "$dir_arg" || {
356a33c354dSmrg	       # Check for POSIX incompatibilities with -m.
357a33c354dSmrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
358a33c354dSmrg	       # other-writable bit of parent directory when it shouldn't.
359a33c354dSmrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
360a33c354dSmrg	       test_tmpdir="$tmpdir/a"
361a33c354dSmrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
362a33c354dSmrg	       case $ls_ld_tmpdir in
363a33c354dSmrg		 d????-?r-*) different_mode=700;;
364a33c354dSmrg		 d????-?--*) different_mode=755;;
365a33c354dSmrg		 *) false;;
366a33c354dSmrg	       esac &&
367a33c354dSmrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
368a33c354dSmrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
369a33c354dSmrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
370a33c354dSmrg	       }
371a33c354dSmrg	     }
372a33c354dSmrg	  then posix_mkdir=:
373a33c354dSmrg	  fi
374a33c354dSmrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
37588cd5fc2Smrg	else
376a33c354dSmrg	  # Remove any dirs left behind by ancient mkdir implementations.
377a33c354dSmrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
37888cd5fc2Smrg	fi
379a33c354dSmrg	trap '' 0;;
38088cd5fc2Smrg    esac
38188cd5fc2Smrg
38288cd5fc2Smrg    if
38388cd5fc2Smrg      $posix_mkdir && (
384a33c354dSmrg        umask $mkdir_umask &&
385a33c354dSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
38688cd5fc2Smrg      )
38788cd5fc2Smrg    then :
38888cd5fc2Smrg    else
38988cd5fc2Smrg
390a33c354dSmrg      # mkdir does not conform to POSIX,
39188cd5fc2Smrg      # or it failed possibly due to a race condition.  Create the
39288cd5fc2Smrg      # directory the slow way, step by step, checking for races as we go.
39388cd5fc2Smrg
39488cd5fc2Smrg      case $dstdir in
395a33c354dSmrg        /*) prefix='/';;
396a33c354dSmrg        [-=\(\)!]*) prefix='./';;
397a33c354dSmrg        *)  prefix='';;
39888cd5fc2Smrg      esac
39988cd5fc2Smrg
40088cd5fc2Smrg      oIFS=$IFS
40188cd5fc2Smrg      IFS=/
402a33c354dSmrg      set -f
40388cd5fc2Smrg      set fnord $dstdir
40488cd5fc2Smrg      shift
405a33c354dSmrg      set +f
40688cd5fc2Smrg      IFS=$oIFS
40788cd5fc2Smrg
40888cd5fc2Smrg      prefixes=
40988cd5fc2Smrg
41088cd5fc2Smrg      for d
41188cd5fc2Smrg      do
412a33c354dSmrg        test X"$d" = X && continue
413a33c354dSmrg
414a33c354dSmrg        prefix=$prefix$d
415a33c354dSmrg        if test -d "$prefix"; then
416a33c354dSmrg          prefixes=
417a33c354dSmrg        else
418a33c354dSmrg          if $posix_mkdir; then
419a33c354dSmrg            (umask $mkdir_umask &&
420a33c354dSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
421a33c354dSmrg            # Don't fail if two instances are running concurrently.
422a33c354dSmrg            test -d "$prefix" || exit 1
423a33c354dSmrg          else
424a33c354dSmrg            case $prefix in
425a33c354dSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
426a33c354dSmrg              *) qprefix=$prefix;;
427a33c354dSmrg            esac
428a33c354dSmrg            prefixes="$prefixes '$qprefix'"
429a33c354dSmrg          fi
430a33c354dSmrg        fi
431a33c354dSmrg        prefix=$prefix/
43288cd5fc2Smrg      done
43388cd5fc2Smrg
43488cd5fc2Smrg      if test -n "$prefixes"; then
435a33c354dSmrg        # Don't fail if two instances are running concurrently.
436a33c354dSmrg        (umask $mkdir_umask &&
437a33c354dSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
438a33c354dSmrg          test -d "$dstdir" || exit 1
439a33c354dSmrg        obsolete_mkdir_used=true
44088cd5fc2Smrg      fi
44188cd5fc2Smrg    fi
44288cd5fc2Smrg  fi
44388cd5fc2Smrg
44488cd5fc2Smrg  if test -n "$dir_arg"; then
44588cd5fc2Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
44688cd5fc2Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
44788cd5fc2Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
44888cd5fc2Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44988cd5fc2Smrg  else
45088cd5fc2Smrg
45188cd5fc2Smrg    # Make a couple of temp file names in the proper directory.
452a33c354dSmrg    dsttmp=${dstdirslash}_inst.$$_
453a33c354dSmrg    rmtmp=${dstdirslash}_rm.$$_
45488cd5fc2Smrg
45588cd5fc2Smrg    # Trap to clean up those temp files at exit.
45688cd5fc2Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45788cd5fc2Smrg
45888cd5fc2Smrg    # Copy the file name to the temp name.
459a33c354dSmrg    (umask $cp_umask &&
460a33c354dSmrg     { test -z "$stripcmd" || {
461a33c354dSmrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
462a33c354dSmrg	 # which would cause strip to fail.
463a33c354dSmrg	 if test -z "$doit"; then
464a33c354dSmrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
465a33c354dSmrg	 else
466a33c354dSmrg	   $doit touch "$dsttmp"
467a33c354dSmrg	 fi
468a33c354dSmrg       }
469a33c354dSmrg     } &&
470a33c354dSmrg     $doit_exec $cpprog "$src" "$dsttmp") &&
47188cd5fc2Smrg
47288cd5fc2Smrg    # and set any options; do chmod last to preserve setuid bits.
47388cd5fc2Smrg    #
47488cd5fc2Smrg    # If any of these fail, we abort the whole thing.  If we want to
47588cd5fc2Smrg    # ignore errors from any of these, just make sure not to ignore
47688cd5fc2Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
47788cd5fc2Smrg    #
47888cd5fc2Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
47988cd5fc2Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
48088cd5fc2Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
48188cd5fc2Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
48288cd5fc2Smrg
48388cd5fc2Smrg    # If -C, don't bother to copy if it wouldn't change the file.
48488cd5fc2Smrg    if $copy_on_change &&
485a33c354dSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
486a33c354dSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
487a33c354dSmrg       set -f &&
48888cd5fc2Smrg       set X $old && old=:$2:$4:$5:$6 &&
48988cd5fc2Smrg       set X $new && new=:$2:$4:$5:$6 &&
490a33c354dSmrg       set +f &&
49188cd5fc2Smrg       test "$old" = "$new" &&
49288cd5fc2Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
49388cd5fc2Smrg    then
49488cd5fc2Smrg      rm -f "$dsttmp"
49588cd5fc2Smrg    else
496a33c354dSmrg      # If $backupsuffix is set, and the file being installed
497a33c354dSmrg      # already exists, attempt a backup.  Don't worry if it fails,
498a33c354dSmrg      # e.g., if mv doesn't support -f.
499a33c354dSmrg      if test -n "$backupsuffix" && test -f "$dst"; then
500a33c354dSmrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
501a33c354dSmrg      fi
502a33c354dSmrg
50388cd5fc2Smrg      # Rename the file to the real destination.
50488cd5fc2Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
50588cd5fc2Smrg
50688cd5fc2Smrg      # The rename failed, perhaps because mv can't rename something else
50788cd5fc2Smrg      # to itself, or perhaps because mv is so ancient that it does not
50888cd5fc2Smrg      # support -f.
50988cd5fc2Smrg      {
510a33c354dSmrg        # Now remove or move aside any old file at destination location.
511a33c354dSmrg        # We try this two ways since rm can't unlink itself on some
512a33c354dSmrg        # systems and the destination file might be busy for other
513a33c354dSmrg        # reasons.  In this case, the final cleanup might fail but the new
514a33c354dSmrg        # file should still install successfully.
515a33c354dSmrg        {
516a33c354dSmrg          test ! -f "$dst" ||
517a33c354dSmrg          $doit $rmcmd "$dst" 2>/dev/null ||
518a33c354dSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
519a33c354dSmrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
520a33c354dSmrg          } ||
521a33c354dSmrg          { echo "$0: cannot unlink or rename $dst" >&2
522a33c354dSmrg            (exit 1); exit 1
523a33c354dSmrg          }
524a33c354dSmrg        } &&
525a33c354dSmrg
526a33c354dSmrg        # Now rename the file to the real destination.
527a33c354dSmrg        $doit $mvcmd "$dsttmp" "$dst"
52888cd5fc2Smrg      }
52988cd5fc2Smrg    fi || exit 1
53088cd5fc2Smrg
53188cd5fc2Smrg    trap '' 0
53288cd5fc2Smrg  fi
53388cd5fc2Smrgdone
53488cd5fc2Smrg
53588cd5fc2Smrg# Local variables:
536a33c354dSmrg# eval: (add-hook 'before-save-hook 'time-stamp)
53788cd5fc2Smrg# time-stamp-start: "scriptversion="
53888cd5fc2Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
539a33c354dSmrg# time-stamp-time-zone: "UTC0"
54088cd5fc2Smrg# time-stamp-end: "; # UTC"
54188cd5fc2Smrg# End:
542