104007ebaSmrg#!/bin/sh
204007ebaSmrg# install - install a program, script, or datafile
304007ebaSmrg
479d5fcd7Smrgscriptversion=2020-11-14.01; # UTC
504007ebaSmrg
604007ebaSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
704007ebaSmrg# later released in X11R6 (xc/config/util/install.sh) with the
804007ebaSmrg# following copyright and license.
904007ebaSmrg#
1004007ebaSmrg# Copyright (C) 1994 X Consortium
1104007ebaSmrg#
1204007ebaSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1304007ebaSmrg# of this software and associated documentation files (the "Software"), to
1404007ebaSmrg# deal in the Software without restriction, including without limitation the
1504007ebaSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1604007ebaSmrg# sell copies of the Software, and to permit persons to whom the Software is
1704007ebaSmrg# furnished to do so, subject to the following conditions:
1804007ebaSmrg#
1904007ebaSmrg# The above copyright notice and this permission notice shall be included in
2004007ebaSmrg# all copies or substantial portions of the Software.
2104007ebaSmrg#
2204007ebaSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2304007ebaSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2404007ebaSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2504007ebaSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2604007ebaSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2704007ebaSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2804007ebaSmrg#
2904007ebaSmrg# Except as contained in this notice, the name of the X Consortium shall not
3004007ebaSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
3104007ebaSmrg# ings in this Software without prior written authorization from the X Consor-
3204007ebaSmrg# tium.
3304007ebaSmrg#
3404007ebaSmrg#
3504007ebaSmrg# FSF changes to this file are in the public domain.
3604007ebaSmrg#
3704007ebaSmrg# Calling this script install-sh is preferred over install.sh, to prevent
3804007ebaSmrg# 'make' implicit rules from creating a file called install from it
3904007ebaSmrg# when there is no Makefile.
4004007ebaSmrg#
4104007ebaSmrg# This script is compatible with the BSD install script, but was written
4204007ebaSmrg# from scratch.
4304007ebaSmrg
4405cf1079Smrgtab='	'
4504007ebaSmrgnl='
4604007ebaSmrg'
4705cf1079SmrgIFS=" $tab$nl"
4804007ebaSmrg
4905cf1079Smrg# Set DOITPROG to "echo" to test this script.
5004007ebaSmrg
5104007ebaSmrgdoit=${DOITPROG-}
5205cf1079Smrgdoit_exec=${doit:-exec}
5304007ebaSmrg
5404007ebaSmrg# Put in absolute file names if you don't have them in your path;
5504007ebaSmrg# or use environment vars.
5604007ebaSmrg
5704007ebaSmrgchgrpprog=${CHGRPPROG-chgrp}
5804007ebaSmrgchmodprog=${CHMODPROG-chmod}
5904007ebaSmrgchownprog=${CHOWNPROG-chown}
6004007ebaSmrgcmpprog=${CMPPROG-cmp}
6104007ebaSmrgcpprog=${CPPROG-cp}
6204007ebaSmrgmkdirprog=${MKDIRPROG-mkdir}
6304007ebaSmrgmvprog=${MVPROG-mv}
6404007ebaSmrgrmprog=${RMPROG-rm}
6504007ebaSmrgstripprog=${STRIPPROG-strip}
6604007ebaSmrg
6704007ebaSmrgposix_mkdir=
6804007ebaSmrg
6904007ebaSmrg# Desired mode of installed file.
7004007ebaSmrgmode=0755
7104007ebaSmrg
7279d5fcd7Smrg# Create dirs (including intermediate dirs) using mode 755.
7379d5fcd7Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
7479d5fcd7Smrgmkdir_umask=22
7579d5fcd7Smrg
7679d5fcd7Smrgbackupsuffix=
7704007ebaSmrgchgrpcmd=
7804007ebaSmrgchmodcmd=$chmodprog
7904007ebaSmrgchowncmd=
8004007ebaSmrgmvcmd=$mvprog
8104007ebaSmrgrmcmd="$rmprog -f"
8204007ebaSmrgstripcmd=
8304007ebaSmrg
8404007ebaSmrgsrc=
8504007ebaSmrgdst=
8604007ebaSmrgdir_arg=
8704007ebaSmrgdst_arg=
8804007ebaSmrg
8904007ebaSmrgcopy_on_change=false
9005cf1079Smrgis_target_a_directory=possibly
9104007ebaSmrg
9204007ebaSmrgusage="\
9304007ebaSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
9404007ebaSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9504007ebaSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9604007ebaSmrg   or: $0 [OPTION]... -d DIRECTORIES...
9704007ebaSmrg
9804007ebaSmrgIn the 1st form, copy SRCFILE to DSTFILE.
9904007ebaSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
10004007ebaSmrgIn the 4th, create DIRECTORIES.
10104007ebaSmrg
10204007ebaSmrgOptions:
10304007ebaSmrg     --help     display this help and exit.
10404007ebaSmrg     --version  display version info and exit.
10504007ebaSmrg
10604007ebaSmrg  -c            (ignored)
10779d5fcd7Smrg  -C            install only if different (preserve data modification time)
10804007ebaSmrg  -d            create directories instead of installing files.
10904007ebaSmrg  -g GROUP      $chgrpprog installed files to GROUP.
11004007ebaSmrg  -m MODE       $chmodprog installed files to MODE.
11104007ebaSmrg  -o USER       $chownprog installed files to USER.
11279d5fcd7Smrg  -p            pass -p to $cpprog.
11304007ebaSmrg  -s            $stripprog installed files.
11479d5fcd7Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
11504007ebaSmrg  -t DIRECTORY  install into DIRECTORY.
11604007ebaSmrg  -T            report an error if DSTFILE is a directory.
11704007ebaSmrg
11804007ebaSmrgEnvironment variables override the default commands:
11904007ebaSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
12004007ebaSmrg  RMPROG STRIPPROG
12179d5fcd7Smrg
12279d5fcd7SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
12379d5fcd7Smrgit's up to you to specify -f if you want it.
12479d5fcd7Smrg
12579d5fcd7SmrgIf -S is not specified, no backups are attempted.
12679d5fcd7Smrg
12779d5fcd7SmrgEmail bug reports to bug-automake@gnu.org.
12879d5fcd7SmrgAutomake home page: https://www.gnu.org/software/automake/
12904007ebaSmrg"
13004007ebaSmrg
13104007ebaSmrgwhile test $# -ne 0; do
13204007ebaSmrg  case $1 in
13304007ebaSmrg    -c) ;;
13404007ebaSmrg
13504007ebaSmrg    -C) copy_on_change=true;;
13604007ebaSmrg
13704007ebaSmrg    -d) dir_arg=true;;
13804007ebaSmrg
13904007ebaSmrg    -g) chgrpcmd="$chgrpprog $2"
14005cf1079Smrg        shift;;
14104007ebaSmrg
14204007ebaSmrg    --help) echo "$usage"; exit $?;;
14304007ebaSmrg
14404007ebaSmrg    -m) mode=$2
14505cf1079Smrg        case $mode in
14605cf1079Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
14705cf1079Smrg            echo "$0: invalid mode: $mode" >&2
14805cf1079Smrg            exit 1;;
14905cf1079Smrg        esac
15005cf1079Smrg        shift;;
15104007ebaSmrg
15204007ebaSmrg    -o) chowncmd="$chownprog $2"
15305cf1079Smrg        shift;;
15404007ebaSmrg
15579d5fcd7Smrg    -p) cpprog="$cpprog -p";;
15679d5fcd7Smrg
15704007ebaSmrg    -s) stripcmd=$stripprog;;
15804007ebaSmrg
15979d5fcd7Smrg    -S) backupsuffix="$2"
16079d5fcd7Smrg        shift;;
16179d5fcd7Smrg
16205cf1079Smrg    -t)
16305cf1079Smrg        is_target_a_directory=always
16405cf1079Smrg        dst_arg=$2
16505cf1079Smrg        # Protect names problematic for 'test' and other utilities.
16605cf1079Smrg        case $dst_arg in
16705cf1079Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
16805cf1079Smrg        esac
16905cf1079Smrg        shift;;
17004007ebaSmrg
17105cf1079Smrg    -T) is_target_a_directory=never;;
17204007ebaSmrg
17304007ebaSmrg    --version) echo "$0 $scriptversion"; exit $?;;
17404007ebaSmrg
17505cf1079Smrg    --) shift
17605cf1079Smrg        break;;
17704007ebaSmrg
17805cf1079Smrg    -*) echo "$0: invalid option: $1" >&2
17905cf1079Smrg        exit 1;;
18004007ebaSmrg
18104007ebaSmrg    *)  break;;
18204007ebaSmrg  esac
18304007ebaSmrg  shift
18404007ebaSmrgdone
18504007ebaSmrg
18605cf1079Smrg# We allow the use of options -d and -T together, by making -d
18705cf1079Smrg# take the precedence; this is for compatibility with GNU install.
18805cf1079Smrg
18905cf1079Smrgif test -n "$dir_arg"; then
19005cf1079Smrg  if test -n "$dst_arg"; then
19105cf1079Smrg    echo "$0: target directory not allowed when installing a directory." >&2
19205cf1079Smrg    exit 1
19305cf1079Smrg  fi
19405cf1079Smrgfi
19505cf1079Smrg
19604007ebaSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
19704007ebaSmrg  # When -d is used, all remaining arguments are directories to create.
19804007ebaSmrg  # When -t is used, the destination is already specified.
19904007ebaSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
20004007ebaSmrg  for arg
20104007ebaSmrg  do
20204007ebaSmrg    if test -n "$dst_arg"; then
20304007ebaSmrg      # $@ is not empty: it contains at least $arg.
20404007ebaSmrg      set fnord "$@" "$dst_arg"
20504007ebaSmrg      shift # fnord
20604007ebaSmrg    fi
20704007ebaSmrg    shift # arg
20804007ebaSmrg    dst_arg=$arg
20904007ebaSmrg    # Protect names problematic for 'test' and other utilities.
21004007ebaSmrg    case $dst_arg in
21104007ebaSmrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
21204007ebaSmrg    esac
21304007ebaSmrg  done
21404007ebaSmrgfi
21504007ebaSmrg
21604007ebaSmrgif test $# -eq 0; then
21704007ebaSmrg  if test -z "$dir_arg"; then
21804007ebaSmrg    echo "$0: no input file specified." >&2
21904007ebaSmrg    exit 1
22004007ebaSmrg  fi
22104007ebaSmrg  # It's OK to call 'install-sh -d' without argument.
22204007ebaSmrg  # This can happen when creating conditional directories.
22304007ebaSmrg  exit 0
22404007ebaSmrgfi
22504007ebaSmrg
22605cf1079Smrgif test -z "$dir_arg"; then
22705cf1079Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
22805cf1079Smrg    if test ! -d "$dst_arg"; then
22905cf1079Smrg      echo "$0: $dst_arg: Is not a directory." >&2
23005cf1079Smrg      exit 1
23105cf1079Smrg    fi
23205cf1079Smrg  fi
23305cf1079Smrgfi
23405cf1079Smrg
23504007ebaSmrgif test -z "$dir_arg"; then
23604007ebaSmrg  do_exit='(exit $ret); exit $ret'
23704007ebaSmrg  trap "ret=129; $do_exit" 1
23804007ebaSmrg  trap "ret=130; $do_exit" 2
23904007ebaSmrg  trap "ret=141; $do_exit" 13
24004007ebaSmrg  trap "ret=143; $do_exit" 15
24104007ebaSmrg
24204007ebaSmrg  # Set umask so as not to create temps with too-generous modes.
24304007ebaSmrg  # However, 'strip' requires both read and write access to temps.
24404007ebaSmrg  case $mode in
24504007ebaSmrg    # Optimize common cases.
24604007ebaSmrg    *644) cp_umask=133;;
24704007ebaSmrg    *755) cp_umask=22;;
24804007ebaSmrg
24904007ebaSmrg    *[0-7])
25004007ebaSmrg      if test -z "$stripcmd"; then
25105cf1079Smrg        u_plus_rw=
25204007ebaSmrg      else
25305cf1079Smrg        u_plus_rw='% 200'
25404007ebaSmrg      fi
25504007ebaSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
25604007ebaSmrg    *)
25704007ebaSmrg      if test -z "$stripcmd"; then
25805cf1079Smrg        u_plus_rw=
25904007ebaSmrg      else
26005cf1079Smrg        u_plus_rw=,u+rw
26104007ebaSmrg      fi
26204007ebaSmrg      cp_umask=$mode$u_plus_rw;;
26304007ebaSmrg  esac
26404007ebaSmrgfi
26504007ebaSmrg
26604007ebaSmrgfor src
26704007ebaSmrgdo
26804007ebaSmrg  # Protect names problematic for 'test' and other utilities.
26904007ebaSmrg  case $src in
27004007ebaSmrg    -* | [=\(\)!]) src=./$src;;
27104007ebaSmrg  esac
27204007ebaSmrg
27304007ebaSmrg  if test -n "$dir_arg"; then
27404007ebaSmrg    dst=$src
27504007ebaSmrg    dstdir=$dst
27604007ebaSmrg    test -d "$dstdir"
27704007ebaSmrg    dstdir_status=$?
27879d5fcd7Smrg    # Don't chown directories that already exist.
27979d5fcd7Smrg    if test $dstdir_status = 0; then
28079d5fcd7Smrg      chowncmd=""
28179d5fcd7Smrg    fi
28204007ebaSmrg  else
28304007ebaSmrg
28404007ebaSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
28504007ebaSmrg    # might cause directories to be created, which would be especially bad
28604007ebaSmrg    # if $src (and thus $dsttmp) contains '*'.
28704007ebaSmrg    if test ! -f "$src" && test ! -d "$src"; then
28804007ebaSmrg      echo "$0: $src does not exist." >&2
28904007ebaSmrg      exit 1
29004007ebaSmrg    fi
29104007ebaSmrg
29204007ebaSmrg    if test -z "$dst_arg"; then
29304007ebaSmrg      echo "$0: no destination specified." >&2
29404007ebaSmrg      exit 1
29504007ebaSmrg    fi
29604007ebaSmrg    dst=$dst_arg
29704007ebaSmrg
29805cf1079Smrg    # If destination is a directory, append the input filename.
29904007ebaSmrg    if test -d "$dst"; then
30005cf1079Smrg      if test "$is_target_a_directory" = never; then
30105cf1079Smrg        echo "$0: $dst_arg: Is a directory" >&2
30205cf1079Smrg        exit 1
30304007ebaSmrg      fi
30404007ebaSmrg      dstdir=$dst
30505cf1079Smrg      dstbase=`basename "$src"`
30605cf1079Smrg      case $dst in
30705cf1079Smrg	*/) dst=$dst$dstbase;;
30805cf1079Smrg	*)  dst=$dst/$dstbase;;
30905cf1079Smrg      esac
31004007ebaSmrg      dstdir_status=0
31104007ebaSmrg    else
31205cf1079Smrg      dstdir=`dirname "$dst"`
31304007ebaSmrg      test -d "$dstdir"
31404007ebaSmrg      dstdir_status=$?
31504007ebaSmrg    fi
31604007ebaSmrg  fi
31704007ebaSmrg
31805cf1079Smrg  case $dstdir in
31905cf1079Smrg    */) dstdirslash=$dstdir;;
32005cf1079Smrg    *)  dstdirslash=$dstdir/;;
32105cf1079Smrg  esac
32205cf1079Smrg
32304007ebaSmrg  obsolete_mkdir_used=false
32404007ebaSmrg
32504007ebaSmrg  if test $dstdir_status != 0; then
32604007ebaSmrg    case $posix_mkdir in
32704007ebaSmrg      '')
32805cf1079Smrg        # With -d, create the new directory with the user-specified mode.
32905cf1079Smrg        # Otherwise, rely on $mkdir_umask.
33005cf1079Smrg        if test -n "$dir_arg"; then
33105cf1079Smrg          mkdir_mode=-m$mode
33205cf1079Smrg        else
33305cf1079Smrg          mkdir_mode=
33405cf1079Smrg        fi
33505cf1079Smrg
33605cf1079Smrg        posix_mkdir=false
33779d5fcd7Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
33879d5fcd7Smrg	# here however when possible just to lower collision chance.
33979d5fcd7Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34079d5fcd7Smrg
34179d5fcd7Smrg	trap '
34279d5fcd7Smrg	  ret=$?
34379d5fcd7Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
34479d5fcd7Smrg	  exit $ret
34579d5fcd7Smrg	' 0
34679d5fcd7Smrg
34779d5fcd7Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
34879d5fcd7Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
34979d5fcd7Smrg	# directory is successfully created first before we actually test
35079d5fcd7Smrg	# 'mkdir -p'.
35179d5fcd7Smrg	if (umask $mkdir_umask &&
35279d5fcd7Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
35379d5fcd7Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
35479d5fcd7Smrg	then
35579d5fcd7Smrg	  if test -z "$dir_arg" || {
35679d5fcd7Smrg	       # Check for POSIX incompatibilities with -m.
35779d5fcd7Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35879d5fcd7Smrg	       # other-writable bit of parent directory when it shouldn't.
35979d5fcd7Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
36079d5fcd7Smrg	       test_tmpdir="$tmpdir/a"
36179d5fcd7Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
36279d5fcd7Smrg	       case $ls_ld_tmpdir in
36379d5fcd7Smrg		 d????-?r-*) different_mode=700;;
36479d5fcd7Smrg		 d????-?--*) different_mode=755;;
36579d5fcd7Smrg		 *) false;;
36679d5fcd7Smrg	       esac &&
36779d5fcd7Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
36879d5fcd7Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
36979d5fcd7Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
37079d5fcd7Smrg	       }
37179d5fcd7Smrg	     }
37279d5fcd7Smrg	  then posix_mkdir=:
37379d5fcd7Smrg	  fi
37479d5fcd7Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
37579d5fcd7Smrg	else
37679d5fcd7Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
37779d5fcd7Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
37879d5fcd7Smrg	fi
37979d5fcd7Smrg	trap '' 0;;
38004007ebaSmrg    esac
38104007ebaSmrg
38204007ebaSmrg    if
38304007ebaSmrg      $posix_mkdir && (
38405cf1079Smrg        umask $mkdir_umask &&
38505cf1079Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
38604007ebaSmrg      )
38704007ebaSmrg    then :
38804007ebaSmrg    else
38904007ebaSmrg
39079d5fcd7Smrg      # mkdir does not conform to POSIX,
39104007ebaSmrg      # or it failed possibly due to a race condition.  Create the
39204007ebaSmrg      # directory the slow way, step by step, checking for races as we go.
39304007ebaSmrg
39404007ebaSmrg      case $dstdir in
39505cf1079Smrg        /*) prefix='/';;
39605cf1079Smrg        [-=\(\)!]*) prefix='./';;
39705cf1079Smrg        *)  prefix='';;
39804007ebaSmrg      esac
39904007ebaSmrg
40004007ebaSmrg      oIFS=$IFS
40104007ebaSmrg      IFS=/
40205cf1079Smrg      set -f
40304007ebaSmrg      set fnord $dstdir
40404007ebaSmrg      shift
40505cf1079Smrg      set +f
40604007ebaSmrg      IFS=$oIFS
40704007ebaSmrg
40804007ebaSmrg      prefixes=
40904007ebaSmrg
41004007ebaSmrg      for d
41104007ebaSmrg      do
41205cf1079Smrg        test X"$d" = X && continue
41305cf1079Smrg
41405cf1079Smrg        prefix=$prefix$d
41505cf1079Smrg        if test -d "$prefix"; then
41605cf1079Smrg          prefixes=
41705cf1079Smrg        else
41805cf1079Smrg          if $posix_mkdir; then
41979d5fcd7Smrg            (umask $mkdir_umask &&
42005cf1079Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
42105cf1079Smrg            # Don't fail if two instances are running concurrently.
42205cf1079Smrg            test -d "$prefix" || exit 1
42305cf1079Smrg          else
42405cf1079Smrg            case $prefix in
42505cf1079Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42605cf1079Smrg              *) qprefix=$prefix;;
42705cf1079Smrg            esac
42805cf1079Smrg            prefixes="$prefixes '$qprefix'"
42905cf1079Smrg          fi
43005cf1079Smrg        fi
43105cf1079Smrg        prefix=$prefix/
43204007ebaSmrg      done
43304007ebaSmrg
43404007ebaSmrg      if test -n "$prefixes"; then
43505cf1079Smrg        # Don't fail if two instances are running concurrently.
43605cf1079Smrg        (umask $mkdir_umask &&
43705cf1079Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
43805cf1079Smrg          test -d "$dstdir" || exit 1
43905cf1079Smrg        obsolete_mkdir_used=true
44004007ebaSmrg      fi
44104007ebaSmrg    fi
44204007ebaSmrg  fi
44304007ebaSmrg
44404007ebaSmrg  if test -n "$dir_arg"; then
44504007ebaSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
44604007ebaSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
44704007ebaSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
44804007ebaSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44904007ebaSmrg  else
45004007ebaSmrg
45104007ebaSmrg    # Make a couple of temp file names in the proper directory.
45205cf1079Smrg    dsttmp=${dstdirslash}_inst.$$_
45305cf1079Smrg    rmtmp=${dstdirslash}_rm.$$_
45404007ebaSmrg
45504007ebaSmrg    # Trap to clean up those temp files at exit.
45604007ebaSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45704007ebaSmrg
45804007ebaSmrg    # Copy the file name to the temp name.
45979d5fcd7Smrg    (umask $cp_umask &&
46079d5fcd7Smrg     { test -z "$stripcmd" || {
46179d5fcd7Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
46279d5fcd7Smrg	 # which would cause strip to fail.
46379d5fcd7Smrg	 if test -z "$doit"; then
46479d5fcd7Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
46579d5fcd7Smrg	 else
46679d5fcd7Smrg	   $doit touch "$dsttmp"
46779d5fcd7Smrg	 fi
46879d5fcd7Smrg       }
46979d5fcd7Smrg     } &&
47079d5fcd7Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
47104007ebaSmrg
47204007ebaSmrg    # and set any options; do chmod last to preserve setuid bits.
47304007ebaSmrg    #
47404007ebaSmrg    # If any of these fail, we abort the whole thing.  If we want to
47504007ebaSmrg    # ignore errors from any of these, just make sure not to ignore
47604007ebaSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
47704007ebaSmrg    #
47804007ebaSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
47904007ebaSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
48004007ebaSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
48104007ebaSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
48204007ebaSmrg
48304007ebaSmrg    # If -C, don't bother to copy if it wouldn't change the file.
48404007ebaSmrg    if $copy_on_change &&
48505cf1079Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
48605cf1079Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
48705cf1079Smrg       set -f &&
48804007ebaSmrg       set X $old && old=:$2:$4:$5:$6 &&
48904007ebaSmrg       set X $new && new=:$2:$4:$5:$6 &&
49005cf1079Smrg       set +f &&
49104007ebaSmrg       test "$old" = "$new" &&
49204007ebaSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
49304007ebaSmrg    then
49404007ebaSmrg      rm -f "$dsttmp"
49504007ebaSmrg    else
49679d5fcd7Smrg      # If $backupsuffix is set, and the file being installed
49779d5fcd7Smrg      # already exists, attempt a backup.  Don't worry if it fails,
49879d5fcd7Smrg      # e.g., if mv doesn't support -f.
49979d5fcd7Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
50079d5fcd7Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
50179d5fcd7Smrg      fi
50279d5fcd7Smrg
50304007ebaSmrg      # Rename the file to the real destination.
50404007ebaSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
50504007ebaSmrg
50604007ebaSmrg      # The rename failed, perhaps because mv can't rename something else
50704007ebaSmrg      # to itself, or perhaps because mv is so ancient that it does not
50804007ebaSmrg      # support -f.
50904007ebaSmrg      {
51005cf1079Smrg        # Now remove or move aside any old file at destination location.
51105cf1079Smrg        # We try this two ways since rm can't unlink itself on some
51205cf1079Smrg        # systems and the destination file might be busy for other
51305cf1079Smrg        # reasons.  In this case, the final cleanup might fail but the new
51405cf1079Smrg        # file should still install successfully.
51505cf1079Smrg        {
51605cf1079Smrg          test ! -f "$dst" ||
51779d5fcd7Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
51805cf1079Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
51979d5fcd7Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
52005cf1079Smrg          } ||
52105cf1079Smrg          { echo "$0: cannot unlink or rename $dst" >&2
52205cf1079Smrg            (exit 1); exit 1
52305cf1079Smrg          }
52405cf1079Smrg        } &&
52505cf1079Smrg
52605cf1079Smrg        # Now rename the file to the real destination.
52705cf1079Smrg        $doit $mvcmd "$dsttmp" "$dst"
52804007ebaSmrg      }
52904007ebaSmrg    fi || exit 1
53004007ebaSmrg
53104007ebaSmrg    trap '' 0
53204007ebaSmrg  fi
53304007ebaSmrgdone
53404007ebaSmrg
53504007ebaSmrg# Local variables:
53605cf1079Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
53704007ebaSmrg# time-stamp-start: "scriptversion="
53804007ebaSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
53905cf1079Smrg# time-stamp-time-zone: "UTC0"
54004007ebaSmrg# time-stamp-end: "; # UTC"
54104007ebaSmrg# End:
542