1f7ec340bSmacallan#!/bin/sh
2f7ec340bSmacallan# install - install a program, script, or datafile
3f7ec340bSmacallan
466ab3337Smrgscriptversion=2020-11-14.01; # UTC
5f7ec340bSmacallan
6f7ec340bSmacallan# This originates from X11R5 (mit/util/scripts/install.sh), which was
7f7ec340bSmacallan# later released in X11R6 (xc/config/util/install.sh) with the
8f7ec340bSmacallan# following copyright and license.
9f7ec340bSmacallan#
10f7ec340bSmacallan# Copyright (C) 1994 X Consortium
11f7ec340bSmacallan#
12f7ec340bSmacallan# Permission is hereby granted, free of charge, to any person obtaining a copy
13f7ec340bSmacallan# of this software and associated documentation files (the "Software"), to
14f7ec340bSmacallan# deal in the Software without restriction, including without limitation the
15f7ec340bSmacallan# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16f7ec340bSmacallan# sell copies of the Software, and to permit persons to whom the Software is
17f7ec340bSmacallan# furnished to do so, subject to the following conditions:
18f7ec340bSmacallan#
19f7ec340bSmacallan# The above copyright notice and this permission notice shall be included in
20f7ec340bSmacallan# all copies or substantial portions of the Software.
21f7ec340bSmacallan#
22f7ec340bSmacallan# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23f7ec340bSmacallan# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24f7ec340bSmacallan# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25f7ec340bSmacallan# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26f7ec340bSmacallan# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27f7ec340bSmacallan# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28f7ec340bSmacallan#
29f7ec340bSmacallan# Except as contained in this notice, the name of the X Consortium shall not
30f7ec340bSmacallan# be used in advertising or otherwise to promote the sale, use or other deal-
31f7ec340bSmacallan# ings in this Software without prior written authorization from the X Consor-
32f7ec340bSmacallan# tium.
33f7ec340bSmacallan#
34f7ec340bSmacallan#
35f7ec340bSmacallan# FSF changes to this file are in the public domain.
36f7ec340bSmacallan#
37f7ec340bSmacallan# Calling this script install-sh is preferred over install.sh, to prevent
382a75d1c4Smrg# 'make' implicit rules from creating a file called install from it
39f7ec340bSmacallan# when there is no Makefile.
40f7ec340bSmacallan#
41f7ec340bSmacallan# This script is compatible with the BSD install script, but was written
427ce7e03cSmrg# from scratch.
437ce7e03cSmrg
4466ab3337Smrgtab='	'
457ce7e03cSmrgnl='
467ce7e03cSmrg'
4766ab3337SmrgIFS=" $tab$nl"
48f7ec340bSmacallan
4966ab3337Smrg# Set DOITPROG to "echo" to test this script.
50f7ec340bSmacallan
517ce7e03cSmrgdoit=${DOITPROG-}
5266ab3337Smrgdoit_exec=${doit:-exec}
53f7ec340bSmacallan
547ce7e03cSmrg# Put in absolute file names if you don't have them in your path;
557ce7e03cSmrg# or use environment vars.
567ce7e03cSmrg
577ce7e03cSmrgchgrpprog=${CHGRPPROG-chgrp}
587ce7e03cSmrgchmodprog=${CHMODPROG-chmod}
597ce7e03cSmrgchownprog=${CHOWNPROG-chown}
607ce7e03cSmrgcmpprog=${CMPPROG-cmp}
617ce7e03cSmrgcpprog=${CPPROG-cp}
627ce7e03cSmrgmkdirprog=${MKDIRPROG-mkdir}
637ce7e03cSmrgmvprog=${MVPROG-mv}
647ce7e03cSmrgrmprog=${RMPROG-rm}
657ce7e03cSmrgstripprog=${STRIPPROG-strip}
667ce7e03cSmrg
677ce7e03cSmrgposix_mkdir=
687ce7e03cSmrg
697ce7e03cSmrg# Desired mode of installed file.
707ce7e03cSmrgmode=0755
71f7ec340bSmacallan
7266ab3337Smrg# Create dirs (including intermediate dirs) using mode 755.
7366ab3337Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
7466ab3337Smrgmkdir_umask=22
7566ab3337Smrg
7666ab3337Smrgbackupsuffix=
77f7ec340bSmacallanchgrpcmd=
787ce7e03cSmrgchmodcmd=$chmodprog
797ce7e03cSmrgchowncmd=
807ce7e03cSmrgmvcmd=$mvprog
81f7ec340bSmacallanrmcmd="$rmprog -f"
827ce7e03cSmrgstripcmd=
837ce7e03cSmrg
84f7ec340bSmacallansrc=
85f7ec340bSmacallandst=
86f7ec340bSmacallandir_arg=
877ce7e03cSmrgdst_arg=
887ce7e03cSmrg
897ce7e03cSmrgcopy_on_change=false
9066ab3337Smrgis_target_a_directory=possibly
91f7ec340bSmacallan
927ce7e03cSmrgusage="\
937ce7e03cSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
94f7ec340bSmacallan   or: $0 [OPTION]... SRCFILES... DIRECTORY
95f7ec340bSmacallan   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
96f7ec340bSmacallan   or: $0 [OPTION]... -d DIRECTORIES...
97f7ec340bSmacallan
98f7ec340bSmacallanIn the 1st form, copy SRCFILE to DSTFILE.
99f7ec340bSmacallanIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
100f7ec340bSmacallanIn the 4th, create DIRECTORIES.
101f7ec340bSmacallan
102f7ec340bSmacallanOptions:
1037ce7e03cSmrg     --help     display this help and exit.
1047ce7e03cSmrg     --version  display version info and exit.
1057ce7e03cSmrg
1067ce7e03cSmrg  -c            (ignored)
10766ab3337Smrg  -C            install only if different (preserve data modification time)
1087ce7e03cSmrg  -d            create directories instead of installing files.
1097ce7e03cSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1107ce7e03cSmrg  -m MODE       $chmodprog installed files to MODE.
1117ce7e03cSmrg  -o USER       $chownprog installed files to USER.
11266ab3337Smrg  -p            pass -p to $cpprog.
1137ce7e03cSmrg  -s            $stripprog installed files.
11466ab3337Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
1157ce7e03cSmrg  -t DIRECTORY  install into DIRECTORY.
1167ce7e03cSmrg  -T            report an error if DSTFILE is a directory.
117f7ec340bSmacallan
118f7ec340bSmacallanEnvironment variables override the default commands:
1197ce7e03cSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1207ce7e03cSmrg  RMPROG STRIPPROG
12166ab3337Smrg
12266ab3337SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
12366ab3337Smrgit's up to you to specify -f if you want it.
12466ab3337Smrg
12566ab3337SmrgIf -S is not specified, no backups are attempted.
12666ab3337Smrg
12766ab3337SmrgEmail bug reports to bug-automake@gnu.org.
12866ab3337SmrgAutomake home page: https://www.gnu.org/software/automake/
129f7ec340bSmacallan"
130f7ec340bSmacallan
1317ce7e03cSmrgwhile test $# -ne 0; do
132f7ec340bSmacallan  case $1 in
1337ce7e03cSmrg    -c) ;;
1347ce7e03cSmrg
1357ce7e03cSmrg    -C) copy_on_change=true;;
136f7ec340bSmacallan
1377ce7e03cSmrg    -d) dir_arg=true;;
138f7ec340bSmacallan
139f7ec340bSmacallan    -g) chgrpcmd="$chgrpprog $2"
14066ab3337Smrg        shift;;
141f7ec340bSmacallan
142f7ec340bSmacallan    --help) echo "$usage"; exit $?;;
143f7ec340bSmacallan
1447ce7e03cSmrg    -m) mode=$2
14566ab3337Smrg        case $mode in
14666ab3337Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
14766ab3337Smrg            echo "$0: invalid mode: $mode" >&2
14866ab3337Smrg            exit 1;;
14966ab3337Smrg        esac
15066ab3337Smrg        shift;;
151f7ec340bSmacallan
152f7ec340bSmacallan    -o) chowncmd="$chownprog $2"
15366ab3337Smrg        shift;;
15466ab3337Smrg
15566ab3337Smrg    -p) cpprog="$cpprog -p";;
156f7ec340bSmacallan
1577ce7e03cSmrg    -s) stripcmd=$stripprog;;
158f7ec340bSmacallan
15966ab3337Smrg    -S) backupsuffix="$2"
16066ab3337Smrg        shift;;
161f7ec340bSmacallan
16266ab3337Smrg    -t)
16366ab3337Smrg        is_target_a_directory=always
16466ab3337Smrg        dst_arg=$2
16566ab3337Smrg        # Protect names problematic for 'test' and other utilities.
16666ab3337Smrg        case $dst_arg in
16766ab3337Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
16866ab3337Smrg        esac
16966ab3337Smrg        shift;;
17066ab3337Smrg
17166ab3337Smrg    -T) is_target_a_directory=never;;
172f7ec340bSmacallan
173f7ec340bSmacallan    --version) echo "$0 $scriptversion"; exit $?;;
174f7ec340bSmacallan
17566ab3337Smrg    --) shift
17666ab3337Smrg        break;;
1777ce7e03cSmrg
17866ab3337Smrg    -*) echo "$0: invalid option: $1" >&2
17966ab3337Smrg        exit 1;;
1807ce7e03cSmrg
1817ce7e03cSmrg    *)  break;;
182f7ec340bSmacallan  esac
1837ce7e03cSmrg  shift
184f7ec340bSmacallandone
185f7ec340bSmacallan
18666ab3337Smrg# We allow the use of options -d and -T together, by making -d
18766ab3337Smrg# take the precedence; this is for compatibility with GNU install.
18866ab3337Smrg
18966ab3337Smrgif test -n "$dir_arg"; then
19066ab3337Smrg  if test -n "$dst_arg"; then
19166ab3337Smrg    echo "$0: target directory not allowed when installing a directory." >&2
19266ab3337Smrg    exit 1
19366ab3337Smrg  fi
19466ab3337Smrgfi
19566ab3337Smrg
1967ce7e03cSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1977ce7e03cSmrg  # When -d is used, all remaining arguments are directories to create.
1987ce7e03cSmrg  # When -t is used, the destination is already specified.
1997ce7e03cSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
2007ce7e03cSmrg  for arg
2017ce7e03cSmrg  do
2027ce7e03cSmrg    if test -n "$dst_arg"; then
2037ce7e03cSmrg      # $@ is not empty: it contains at least $arg.
2047ce7e03cSmrg      set fnord "$@" "$dst_arg"
2057ce7e03cSmrg      shift # fnord
2067ce7e03cSmrg    fi
2077ce7e03cSmrg    shift # arg
2087ce7e03cSmrg    dst_arg=$arg
2092a75d1c4Smrg    # Protect names problematic for 'test' and other utilities.
2102a75d1c4Smrg    case $dst_arg in
2112a75d1c4Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
2122a75d1c4Smrg    esac
2137ce7e03cSmrg  done
2147ce7e03cSmrgfi
2157ce7e03cSmrg
2167ce7e03cSmrgif test $# -eq 0; then
217f7ec340bSmacallan  if test -z "$dir_arg"; then
218f7ec340bSmacallan    echo "$0: no input file specified." >&2
219f7ec340bSmacallan    exit 1
220f7ec340bSmacallan  fi
2212a75d1c4Smrg  # It's OK to call 'install-sh -d' without argument.
222f7ec340bSmacallan  # This can happen when creating conditional directories.
223f7ec340bSmacallan  exit 0
224f7ec340bSmacallanfi
225f7ec340bSmacallan
22666ab3337Smrgif test -z "$dir_arg"; then
22766ab3337Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
22866ab3337Smrg    if test ! -d "$dst_arg"; then
22966ab3337Smrg      echo "$0: $dst_arg: Is not a directory." >&2
23066ab3337Smrg      exit 1
23166ab3337Smrg    fi
23266ab3337Smrg  fi
23366ab3337Smrgfi
23466ab3337Smrg
2357ce7e03cSmrgif test -z "$dir_arg"; then
2362a75d1c4Smrg  do_exit='(exit $ret); exit $ret'
2372a75d1c4Smrg  trap "ret=129; $do_exit" 1
2382a75d1c4Smrg  trap "ret=130; $do_exit" 2
2392a75d1c4Smrg  trap "ret=141; $do_exit" 13
2402a75d1c4Smrg  trap "ret=143; $do_exit" 15
2417ce7e03cSmrg
2427ce7e03cSmrg  # Set umask so as not to create temps with too-generous modes.
2437ce7e03cSmrg  # However, 'strip' requires both read and write access to temps.
2447ce7e03cSmrg  case $mode in
2457ce7e03cSmrg    # Optimize common cases.
2467ce7e03cSmrg    *644) cp_umask=133;;
2477ce7e03cSmrg    *755) cp_umask=22;;
2487ce7e03cSmrg
2497ce7e03cSmrg    *[0-7])
2507ce7e03cSmrg      if test -z "$stripcmd"; then
25166ab3337Smrg        u_plus_rw=
2527ce7e03cSmrg      else
25366ab3337Smrg        u_plus_rw='% 200'
2547ce7e03cSmrg      fi
2557ce7e03cSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2567ce7e03cSmrg    *)
2577ce7e03cSmrg      if test -z "$stripcmd"; then
25866ab3337Smrg        u_plus_rw=
2597ce7e03cSmrg      else
26066ab3337Smrg        u_plus_rw=,u+rw
2617ce7e03cSmrg      fi
2627ce7e03cSmrg      cp_umask=$mode$u_plus_rw;;
2637ce7e03cSmrg  esac
2647ce7e03cSmrgfi
2657ce7e03cSmrg
266f7ec340bSmacallanfor src
267f7ec340bSmacallando
2682a75d1c4Smrg  # Protect names problematic for 'test' and other utilities.
269f7ec340bSmacallan  case $src in
2702a75d1c4Smrg    -* | [=\(\)!]) src=./$src;;
271f7ec340bSmacallan  esac
272f7ec340bSmacallan
273f7ec340bSmacallan  if test -n "$dir_arg"; then
274f7ec340bSmacallan    dst=$src
2757ce7e03cSmrg    dstdir=$dst
2767ce7e03cSmrg    test -d "$dstdir"
2777ce7e03cSmrg    dstdir_status=$?
27866ab3337Smrg    # Don't chown directories that already exist.
27966ab3337Smrg    if test $dstdir_status = 0; then
28066ab3337Smrg      chowncmd=""
28166ab3337Smrg    fi
282f7ec340bSmacallan  else
2837ce7e03cSmrg
284f7ec340bSmacallan    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
285f7ec340bSmacallan    # might cause directories to be created, which would be especially bad
286f7ec340bSmacallan    # if $src (and thus $dsttmp) contains '*'.
287f7ec340bSmacallan    if test ! -f "$src" && test ! -d "$src"; then
288f7ec340bSmacallan      echo "$0: $src does not exist." >&2
289f7ec340bSmacallan      exit 1
290f7ec340bSmacallan    fi
291f7ec340bSmacallan
2927ce7e03cSmrg    if test -z "$dst_arg"; then
293f7ec340bSmacallan      echo "$0: no destination specified." >&2
294f7ec340bSmacallan      exit 1
295f7ec340bSmacallan    fi
2967ce7e03cSmrg    dst=$dst_arg
297f7ec340bSmacallan
29866ab3337Smrg    # If destination is a directory, append the input filename.
299f7ec340bSmacallan    if test -d "$dst"; then
30066ab3337Smrg      if test "$is_target_a_directory" = never; then
30166ab3337Smrg        echo "$0: $dst_arg: Is a directory" >&2
30266ab3337Smrg        exit 1
303f7ec340bSmacallan      fi
3047ce7e03cSmrg      dstdir=$dst
30566ab3337Smrg      dstbase=`basename "$src"`
30666ab3337Smrg      case $dst in
30766ab3337Smrg	*/) dst=$dst$dstbase;;
30866ab3337Smrg	*)  dst=$dst/$dstbase;;
30966ab3337Smrg      esac
3107ce7e03cSmrg      dstdir_status=0
3117ce7e03cSmrg    else
31266ab3337Smrg      dstdir=`dirname "$dst"`
3137ce7e03cSmrg      test -d "$dstdir"
3147ce7e03cSmrg      dstdir_status=$?
315f7ec340bSmacallan    fi
316f7ec340bSmacallan  fi
317f7ec340bSmacallan
31866ab3337Smrg  case $dstdir in
31966ab3337Smrg    */) dstdirslash=$dstdir;;
32066ab3337Smrg    *)  dstdirslash=$dstdir/;;
32166ab3337Smrg  esac
32266ab3337Smrg
3237ce7e03cSmrg  obsolete_mkdir_used=false
3247ce7e03cSmrg
3257ce7e03cSmrg  if test $dstdir_status != 0; then
3267ce7e03cSmrg    case $posix_mkdir in
3277ce7e03cSmrg      '')
32866ab3337Smrg        # With -d, create the new directory with the user-specified mode.
32966ab3337Smrg        # Otherwise, rely on $mkdir_umask.
33066ab3337Smrg        if test -n "$dir_arg"; then
33166ab3337Smrg          mkdir_mode=-m$mode
33266ab3337Smrg        else
33366ab3337Smrg          mkdir_mode=
33466ab3337Smrg        fi
33566ab3337Smrg
33666ab3337Smrg        posix_mkdir=false
33766ab3337Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
33866ab3337Smrg	# here however when possible just to lower collision chance.
33966ab3337Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34066ab3337Smrg
34166ab3337Smrg	trap '
34266ab3337Smrg	  ret=$?
34366ab3337Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
34466ab3337Smrg	  exit $ret
34566ab3337Smrg	' 0
34666ab3337Smrg
34766ab3337Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
34866ab3337Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
34966ab3337Smrg	# directory is successfully created first before we actually test
35066ab3337Smrg	# 'mkdir -p'.
35166ab3337Smrg	if (umask $mkdir_umask &&
35266ab3337Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
35366ab3337Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
35466ab3337Smrg	then
35566ab3337Smrg	  if test -z "$dir_arg" || {
35666ab3337Smrg	       # Check for POSIX incompatibilities with -m.
35766ab3337Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35866ab3337Smrg	       # other-writable bit of parent directory when it shouldn't.
35966ab3337Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
36066ab3337Smrg	       test_tmpdir="$tmpdir/a"
36166ab3337Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
36266ab3337Smrg	       case $ls_ld_tmpdir in
36366ab3337Smrg		 d????-?r-*) different_mode=700;;
36466ab3337Smrg		 d????-?--*) different_mode=755;;
36566ab3337Smrg		 *) false;;
36666ab3337Smrg	       esac &&
36766ab3337Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
36866ab3337Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
36966ab3337Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
37066ab3337Smrg	       }
37166ab3337Smrg	     }
37266ab3337Smrg	  then posix_mkdir=:
37366ab3337Smrg	  fi
37466ab3337Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
3757ce7e03cSmrg	else
37666ab3337Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
37766ab3337Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
3787ce7e03cSmrg	fi
37966ab3337Smrg	trap '' 0;;
3807ce7e03cSmrg    esac
381f7ec340bSmacallan
3827ce7e03cSmrg    if
3837ce7e03cSmrg      $posix_mkdir && (
38466ab3337Smrg        umask $mkdir_umask &&
38566ab3337Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3867ce7e03cSmrg      )
3877ce7e03cSmrg    then :
3887ce7e03cSmrg    else
389f7ec340bSmacallan
39066ab3337Smrg      # mkdir does not conform to POSIX,
3917ce7e03cSmrg      # or it failed possibly due to a race condition.  Create the
3927ce7e03cSmrg      # directory the slow way, step by step, checking for races as we go.
393f7ec340bSmacallan
3947ce7e03cSmrg      case $dstdir in
39566ab3337Smrg        /*) prefix='/';;
39666ab3337Smrg        [-=\(\)!]*) prefix='./';;
39766ab3337Smrg        *)  prefix='';;
3987ce7e03cSmrg      esac
399f7ec340bSmacallan
4007ce7e03cSmrg      oIFS=$IFS
4017ce7e03cSmrg      IFS=/
40266ab3337Smrg      set -f
4037ce7e03cSmrg      set fnord $dstdir
404f7ec340bSmacallan      shift
40566ab3337Smrg      set +f
4067ce7e03cSmrg      IFS=$oIFS
4077ce7e03cSmrg
4087ce7e03cSmrg      prefixes=
4097ce7e03cSmrg
4107ce7e03cSmrg      for d
4117ce7e03cSmrg      do
41266ab3337Smrg        test X"$d" = X && continue
41366ab3337Smrg
41466ab3337Smrg        prefix=$prefix$d
41566ab3337Smrg        if test -d "$prefix"; then
41666ab3337Smrg          prefixes=
41766ab3337Smrg        else
41866ab3337Smrg          if $posix_mkdir; then
41966ab3337Smrg            (umask $mkdir_umask &&
42066ab3337Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
42166ab3337Smrg            # Don't fail if two instances are running concurrently.
42266ab3337Smrg            test -d "$prefix" || exit 1
42366ab3337Smrg          else
42466ab3337Smrg            case $prefix in
42566ab3337Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42666ab3337Smrg              *) qprefix=$prefix;;
42766ab3337Smrg            esac
42866ab3337Smrg            prefixes="$prefixes '$qprefix'"
42966ab3337Smrg          fi
43066ab3337Smrg        fi
43166ab3337Smrg        prefix=$prefix/
4327ce7e03cSmrg      done
4337ce7e03cSmrg
4347ce7e03cSmrg      if test -n "$prefixes"; then
43566ab3337Smrg        # Don't fail if two instances are running concurrently.
43666ab3337Smrg        (umask $mkdir_umask &&
43766ab3337Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
43866ab3337Smrg          test -d "$dstdir" || exit 1
43966ab3337Smrg        obsolete_mkdir_used=true
440f7ec340bSmacallan      fi
4417ce7e03cSmrg    fi
442f7ec340bSmacallan  fi
443f7ec340bSmacallan
444f7ec340bSmacallan  if test -n "$dir_arg"; then
4457ce7e03cSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4467ce7e03cSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4477ce7e03cSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4487ce7e03cSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
449f7ec340bSmacallan  else
450f7ec340bSmacallan
451f7ec340bSmacallan    # Make a couple of temp file names in the proper directory.
45266ab3337Smrg    dsttmp=${dstdirslash}_inst.$$_
45366ab3337Smrg    rmtmp=${dstdirslash}_rm.$$_
454f7ec340bSmacallan
455f7ec340bSmacallan    # Trap to clean up those temp files at exit.
456f7ec340bSmacallan    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
457f7ec340bSmacallan
458f7ec340bSmacallan    # Copy the file name to the temp name.
45966ab3337Smrg    (umask $cp_umask &&
46066ab3337Smrg     { test -z "$stripcmd" || {
46166ab3337Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
46266ab3337Smrg	 # which would cause strip to fail.
46366ab3337Smrg	 if test -z "$doit"; then
46466ab3337Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
46566ab3337Smrg	 else
46666ab3337Smrg	   $doit touch "$dsttmp"
46766ab3337Smrg	 fi
46866ab3337Smrg       }
46966ab3337Smrg     } &&
47066ab3337Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
471f7ec340bSmacallan
472f7ec340bSmacallan    # and set any options; do chmod last to preserve setuid bits.
473f7ec340bSmacallan    #
474f7ec340bSmacallan    # If any of these fail, we abort the whole thing.  If we want to
475f7ec340bSmacallan    # ignore errors from any of these, just make sure not to ignore
476f7ec340bSmacallan    # errors from the above "$doit $cpprog $src $dsttmp" command.
477f7ec340bSmacallan    #
4787ce7e03cSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4797ce7e03cSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4807ce7e03cSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4817ce7e03cSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4827ce7e03cSmrg
4837ce7e03cSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4847ce7e03cSmrg    if $copy_on_change &&
48566ab3337Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
48666ab3337Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
48766ab3337Smrg       set -f &&
4887ce7e03cSmrg       set X $old && old=:$2:$4:$5:$6 &&
4897ce7e03cSmrg       set X $new && new=:$2:$4:$5:$6 &&
49066ab3337Smrg       set +f &&
4917ce7e03cSmrg       test "$old" = "$new" &&
4927ce7e03cSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4937ce7e03cSmrg    then
4947ce7e03cSmrg      rm -f "$dsttmp"
4957ce7e03cSmrg    else
49666ab3337Smrg      # If $backupsuffix is set, and the file being installed
49766ab3337Smrg      # already exists, attempt a backup.  Don't worry if it fails,
49866ab3337Smrg      # e.g., if mv doesn't support -f.
49966ab3337Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
50066ab3337Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
50166ab3337Smrg      fi
50266ab3337Smrg
5037ce7e03cSmrg      # Rename the file to the real destination.
5047ce7e03cSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
5057ce7e03cSmrg
5067ce7e03cSmrg      # The rename failed, perhaps because mv can't rename something else
5077ce7e03cSmrg      # to itself, or perhaps because mv is so ancient that it does not
5087ce7e03cSmrg      # support -f.
5097ce7e03cSmrg      {
51066ab3337Smrg        # Now remove or move aside any old file at destination location.
51166ab3337Smrg        # We try this two ways since rm can't unlink itself on some
51266ab3337Smrg        # systems and the destination file might be busy for other
51366ab3337Smrg        # reasons.  In this case, the final cleanup might fail but the new
51466ab3337Smrg        # file should still install successfully.
51566ab3337Smrg        {
51666ab3337Smrg          test ! -f "$dst" ||
51766ab3337Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
51866ab3337Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
51966ab3337Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
52066ab3337Smrg          } ||
52166ab3337Smrg          { echo "$0: cannot unlink or rename $dst" >&2
52266ab3337Smrg            (exit 1); exit 1
52366ab3337Smrg          }
52466ab3337Smrg        } &&
52566ab3337Smrg
52666ab3337Smrg        # Now rename the file to the real destination.
52766ab3337Smrg        $doit $mvcmd "$dsttmp" "$dst"
5287ce7e03cSmrg      }
5297ce7e03cSmrg    fi || exit 1
5307ce7e03cSmrg
5317ce7e03cSmrg    trap '' 0
5327ce7e03cSmrg  fi
533f7ec340bSmacallandone
534f7ec340bSmacallan
535f7ec340bSmacallan# Local variables:
53666ab3337Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
537f7ec340bSmacallan# time-stamp-start: "scriptversion="
538f7ec340bSmacallan# time-stamp-format: "%:y-%02m-%02d.%02H"
53966ab3337Smrg# time-stamp-time-zone: "UTC0"
5402a75d1c4Smrg# time-stamp-end: "; # UTC"
541f7ec340bSmacallan# End:
542