10cc6efb6Smrg#!/bin/sh
20cc6efb6Smrg# install - install a program, script, or datafile
36cf5427aSmrg
448e37bc2Smrgscriptversion=2020-11-14.01; # UTC
56cf5427aSmrg
60cc6efb6Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
70cc6efb6Smrg# later released in X11R6 (xc/config/util/install.sh) with the
80cc6efb6Smrg# following copyright and license.
90cc6efb6Smrg#
100cc6efb6Smrg# Copyright (C) 1994 X Consortium
110cc6efb6Smrg#
120cc6efb6Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
130cc6efb6Smrg# of this software and associated documentation files (the "Software"), to
140cc6efb6Smrg# deal in the Software without restriction, including without limitation the
150cc6efb6Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
160cc6efb6Smrg# sell copies of the Software, and to permit persons to whom the Software is
170cc6efb6Smrg# furnished to do so, subject to the following conditions:
180cc6efb6Smrg#
190cc6efb6Smrg# The above copyright notice and this permission notice shall be included in
200cc6efb6Smrg# all copies or substantial portions of the Software.
210cc6efb6Smrg#
220cc6efb6Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
230cc6efb6Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
240cc6efb6Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
250cc6efb6Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
260cc6efb6Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
270cc6efb6Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
280cc6efb6Smrg#
290cc6efb6Smrg# Except as contained in this notice, the name of the X Consortium shall not
300cc6efb6Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
310cc6efb6Smrg# ings in this Software without prior written authorization from the X Consor-
320cc6efb6Smrg# tium.
330cc6efb6Smrg#
340cc6efb6Smrg#
350cc6efb6Smrg# FSF changes to this file are in the public domain.
360cc6efb6Smrg#
370cc6efb6Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3848e37bc2Smrg# 'make' implicit rules from creating a file called install from it
390cc6efb6Smrg# when there is no Makefile.
400cc6efb6Smrg#
410cc6efb6Smrg# This script is compatible with the BSD install script, but was written
426cf5427aSmrg# from scratch.
430cc6efb6Smrg
4448e37bc2Smrgtab='	'
456cf5427aSmrgnl='
466cf5427aSmrg'
4748e37bc2SmrgIFS=" $tab$nl"
480cc6efb6Smrg
4948e37bc2Smrg# Set DOITPROG to "echo" to test this script.
500cc6efb6Smrg
516cf5427aSmrgdoit=${DOITPROG-}
5248e37bc2Smrgdoit_exec=${doit:-exec}
530cc6efb6Smrg
546cf5427aSmrg# Put in absolute file names if you don't have them in your path;
556cf5427aSmrg# or use environment vars.
566cf5427aSmrg
576cf5427aSmrgchgrpprog=${CHGRPPROG-chgrp}
586cf5427aSmrgchmodprog=${CHMODPROG-chmod}
596cf5427aSmrgchownprog=${CHOWNPROG-chown}
606cf5427aSmrgcmpprog=${CMPPROG-cmp}
616cf5427aSmrgcpprog=${CPPROG-cp}
626cf5427aSmrgmkdirprog=${MKDIRPROG-mkdir}
636cf5427aSmrgmvprog=${MVPROG-mv}
646cf5427aSmrgrmprog=${RMPROG-rm}
656cf5427aSmrgstripprog=${STRIPPROG-strip}
666cf5427aSmrg
676cf5427aSmrgposix_mkdir=
686cf5427aSmrg
696cf5427aSmrg# Desired mode of installed file.
706cf5427aSmrgmode=0755
716cf5427aSmrg
7248e37bc2Smrg# Create dirs (including intermediate dirs) using mode 755.
7348e37bc2Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
7448e37bc2Smrgmkdir_umask=22
7548e37bc2Smrg
7648e37bc2Smrgbackupsuffix=
776cf5427aSmrgchgrpcmd=
786cf5427aSmrgchmodcmd=$chmodprog
796cf5427aSmrgchowncmd=
806cf5427aSmrgmvcmd=$mvprog
816cf5427aSmrgrmcmd="$rmprog -f"
826cf5427aSmrgstripcmd=
830cc6efb6Smrg
846cf5427aSmrgsrc=
856cf5427aSmrgdst=
866cf5427aSmrgdir_arg=
876cf5427aSmrgdst_arg=
880cc6efb6Smrg
896cf5427aSmrgcopy_on_change=false
9048e37bc2Smrgis_target_a_directory=possibly
910cc6efb6Smrg
926cf5427aSmrgusage="\
936cf5427aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
946cf5427aSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
956cf5427aSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
966cf5427aSmrg   or: $0 [OPTION]... -d DIRECTORIES...
970cc6efb6Smrg
986cf5427aSmrgIn the 1st form, copy SRCFILE to DSTFILE.
996cf5427aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1006cf5427aSmrgIn the 4th, create DIRECTORIES.
1010cc6efb6Smrg
1026cf5427aSmrgOptions:
1036cf5427aSmrg     --help     display this help and exit.
1046cf5427aSmrg     --version  display version info and exit.
1050cc6efb6Smrg
1066cf5427aSmrg  -c            (ignored)
10748e37bc2Smrg  -C            install only if different (preserve data modification time)
1086cf5427aSmrg  -d            create directories instead of installing files.
1096cf5427aSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1106cf5427aSmrg  -m MODE       $chmodprog installed files to MODE.
1116cf5427aSmrg  -o USER       $chownprog installed files to USER.
11248e37bc2Smrg  -p            pass -p to $cpprog.
1136cf5427aSmrg  -s            $stripprog installed files.
11448e37bc2Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
1156cf5427aSmrg  -t DIRECTORY  install into DIRECTORY.
1166cf5427aSmrg  -T            report an error if DSTFILE is a directory.
1170cc6efb6Smrg
1186cf5427aSmrgEnvironment variables override the default commands:
1196cf5427aSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1206cf5427aSmrg  RMPROG STRIPPROG
12148e37bc2Smrg
12248e37bc2SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
12348e37bc2Smrgit's up to you to specify -f if you want it.
12448e37bc2Smrg
12548e37bc2SmrgIf -S is not specified, no backups are attempted.
12648e37bc2Smrg
12748e37bc2SmrgEmail bug reports to bug-automake@gnu.org.
12848e37bc2SmrgAutomake home page: https://www.gnu.org/software/automake/
1296cf5427aSmrg"
1300cc6efb6Smrg
1316cf5427aSmrgwhile test $# -ne 0; do
1326cf5427aSmrg  case $1 in
1336cf5427aSmrg    -c) ;;
1340cc6efb6Smrg
1356cf5427aSmrg    -C) copy_on_change=true;;
1360cc6efb6Smrg
1376cf5427aSmrg    -d) dir_arg=true;;
1380cc6efb6Smrg
1396cf5427aSmrg    -g) chgrpcmd="$chgrpprog $2"
14048e37bc2Smrg        shift;;
1410cc6efb6Smrg
1426cf5427aSmrg    --help) echo "$usage"; exit $?;;
1430cc6efb6Smrg
1446cf5427aSmrg    -m) mode=$2
14548e37bc2Smrg        case $mode in
14648e37bc2Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
14748e37bc2Smrg            echo "$0: invalid mode: $mode" >&2
14848e37bc2Smrg            exit 1;;
14948e37bc2Smrg        esac
15048e37bc2Smrg        shift;;
1510cc6efb6Smrg
1526cf5427aSmrg    -o) chowncmd="$chownprog $2"
15348e37bc2Smrg        shift;;
15448e37bc2Smrg
15548e37bc2Smrg    -p) cpprog="$cpprog -p";;
1560cc6efb6Smrg
1576cf5427aSmrg    -s) stripcmd=$stripprog;;
1580cc6efb6Smrg
15948e37bc2Smrg    -S) backupsuffix="$2"
16048e37bc2Smrg        shift;;
16148e37bc2Smrg
16248e37bc2Smrg    -t)
16348e37bc2Smrg        is_target_a_directory=always
16448e37bc2Smrg        dst_arg=$2
16548e37bc2Smrg        # Protect names problematic for 'test' and other utilities.
16648e37bc2Smrg        case $dst_arg in
16748e37bc2Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
16848e37bc2Smrg        esac
16948e37bc2Smrg        shift;;
1700cc6efb6Smrg
17148e37bc2Smrg    -T) is_target_a_directory=never;;
1720cc6efb6Smrg
1736cf5427aSmrg    --version) echo "$0 $scriptversion"; exit $?;;
1740cc6efb6Smrg
17548e37bc2Smrg    --) shift
17648e37bc2Smrg        break;;
1770cc6efb6Smrg
17848e37bc2Smrg    -*) echo "$0: invalid option: $1" >&2
17948e37bc2Smrg        exit 1;;
1800cc6efb6Smrg
1816cf5427aSmrg    *)  break;;
1826cf5427aSmrg  esac
1836cf5427aSmrg  shift
1846cf5427aSmrgdone
1850cc6efb6Smrg
18648e37bc2Smrg# We allow the use of options -d and -T together, by making -d
18748e37bc2Smrg# take the precedence; this is for compatibility with GNU install.
18848e37bc2Smrg
18948e37bc2Smrgif test -n "$dir_arg"; then
19048e37bc2Smrg  if test -n "$dst_arg"; then
19148e37bc2Smrg    echo "$0: target directory not allowed when installing a directory." >&2
19248e37bc2Smrg    exit 1
19348e37bc2Smrg  fi
19448e37bc2Smrgfi
19548e37bc2Smrg
1966cf5427aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1976cf5427aSmrg  # When -d is used, all remaining arguments are directories to create.
1986cf5427aSmrg  # When -t is used, the destination is already specified.
1996cf5427aSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
2006cf5427aSmrg  for arg
2016cf5427aSmrg  do
2026cf5427aSmrg    if test -n "$dst_arg"; then
2036cf5427aSmrg      # $@ is not empty: it contains at least $arg.
2046cf5427aSmrg      set fnord "$@" "$dst_arg"
2056cf5427aSmrg      shift # fnord
2066cf5427aSmrg    fi
2076cf5427aSmrg    shift # arg
2086cf5427aSmrg    dst_arg=$arg
20948e37bc2Smrg    # Protect names problematic for 'test' and other utilities.
21048e37bc2Smrg    case $dst_arg in
21148e37bc2Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
21248e37bc2Smrg    esac
2136cf5427aSmrg  done
2146cf5427aSmrgfi
2150cc6efb6Smrg
2166cf5427aSmrgif test $# -eq 0; then
2176cf5427aSmrg  if test -z "$dir_arg"; then
2186cf5427aSmrg    echo "$0: no input file specified." >&2
2196cf5427aSmrg    exit 1
2206cf5427aSmrg  fi
22148e37bc2Smrg  # It's OK to call 'install-sh -d' without argument.
2226cf5427aSmrg  # This can happen when creating conditional directories.
2236cf5427aSmrg  exit 0
2246cf5427aSmrgfi
2250cc6efb6Smrg
2266cf5427aSmrgif test -z "$dir_arg"; then
22748e37bc2Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
22848e37bc2Smrg    if test ! -d "$dst_arg"; then
22948e37bc2Smrg      echo "$0: $dst_arg: Is not a directory." >&2
23048e37bc2Smrg      exit 1
23148e37bc2Smrg    fi
23248e37bc2Smrg  fi
23348e37bc2Smrgfi
23448e37bc2Smrg
23548e37bc2Smrgif test -z "$dir_arg"; then
23648e37bc2Smrg  do_exit='(exit $ret); exit $ret'
23748e37bc2Smrg  trap "ret=129; $do_exit" 1
23848e37bc2Smrg  trap "ret=130; $do_exit" 2
23948e37bc2Smrg  trap "ret=141; $do_exit" 13
24048e37bc2Smrg  trap "ret=143; $do_exit" 15
2416cf5427aSmrg
2426cf5427aSmrg  # Set umask so as not to create temps with too-generous modes.
2436cf5427aSmrg  # However, 'strip' requires both read and write access to temps.
2446cf5427aSmrg  case $mode in
2456cf5427aSmrg    # Optimize common cases.
2466cf5427aSmrg    *644) cp_umask=133;;
2476cf5427aSmrg    *755) cp_umask=22;;
2486cf5427aSmrg
2496cf5427aSmrg    *[0-7])
2506cf5427aSmrg      if test -z "$stripcmd"; then
25148e37bc2Smrg        u_plus_rw=
2526cf5427aSmrg      else
25348e37bc2Smrg        u_plus_rw='% 200'
2546cf5427aSmrg      fi
2556cf5427aSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2566cf5427aSmrg    *)
2576cf5427aSmrg      if test -z "$stripcmd"; then
25848e37bc2Smrg        u_plus_rw=
2596cf5427aSmrg      else
26048e37bc2Smrg        u_plus_rw=,u+rw
2616cf5427aSmrg      fi
2626cf5427aSmrg      cp_umask=$mode$u_plus_rw;;
2636cf5427aSmrg  esac
2646cf5427aSmrgfi
2650cc6efb6Smrg
2666cf5427aSmrgfor src
2676cf5427aSmrgdo
26848e37bc2Smrg  # Protect names problematic for 'test' and other utilities.
2696cf5427aSmrg  case $src in
27048e37bc2Smrg    -* | [=\(\)!]) src=./$src;;
2716cf5427aSmrg  esac
2726cf5427aSmrg
2736cf5427aSmrg  if test -n "$dir_arg"; then
2746cf5427aSmrg    dst=$src
2756cf5427aSmrg    dstdir=$dst
2766cf5427aSmrg    test -d "$dstdir"
2776cf5427aSmrg    dstdir_status=$?
27848e37bc2Smrg    # Don't chown directories that already exist.
27948e37bc2Smrg    if test $dstdir_status = 0; then
28048e37bc2Smrg      chowncmd=""
28148e37bc2Smrg    fi
2826cf5427aSmrg  else
2836cf5427aSmrg
2846cf5427aSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2856cf5427aSmrg    # might cause directories to be created, which would be especially bad
2866cf5427aSmrg    # if $src (and thus $dsttmp) contains '*'.
2876cf5427aSmrg    if test ! -f "$src" && test ! -d "$src"; then
2886cf5427aSmrg      echo "$0: $src does not exist." >&2
2896cf5427aSmrg      exit 1
2906cf5427aSmrg    fi
2916cf5427aSmrg
2926cf5427aSmrg    if test -z "$dst_arg"; then
2936cf5427aSmrg      echo "$0: no destination specified." >&2
2946cf5427aSmrg      exit 1
2956cf5427aSmrg    fi
2966cf5427aSmrg    dst=$dst_arg
2970cc6efb6Smrg
29848e37bc2Smrg    # If destination is a directory, append the input filename.
2996cf5427aSmrg    if test -d "$dst"; then
30048e37bc2Smrg      if test "$is_target_a_directory" = never; then
30148e37bc2Smrg        echo "$0: $dst_arg: Is a directory" >&2
30248e37bc2Smrg        exit 1
3036cf5427aSmrg      fi
3046cf5427aSmrg      dstdir=$dst
30548e37bc2Smrg      dstbase=`basename "$src"`
30648e37bc2Smrg      case $dst in
30748e37bc2Smrg	*/) dst=$dst$dstbase;;
30848e37bc2Smrg	*)  dst=$dst/$dstbase;;
30948e37bc2Smrg      esac
3106cf5427aSmrg      dstdir_status=0
3116cf5427aSmrg    else
31248e37bc2Smrg      dstdir=`dirname "$dst"`
3136cf5427aSmrg      test -d "$dstdir"
3146cf5427aSmrg      dstdir_status=$?
3156cf5427aSmrg    fi
3166cf5427aSmrg  fi
3176cf5427aSmrg
31848e37bc2Smrg  case $dstdir in
31948e37bc2Smrg    */) dstdirslash=$dstdir;;
32048e37bc2Smrg    *)  dstdirslash=$dstdir/;;
32148e37bc2Smrg  esac
32248e37bc2Smrg
3236cf5427aSmrg  obsolete_mkdir_used=false
3246cf5427aSmrg
3256cf5427aSmrg  if test $dstdir_status != 0; then
3266cf5427aSmrg    case $posix_mkdir in
3276cf5427aSmrg      '')
32848e37bc2Smrg        # With -d, create the new directory with the user-specified mode.
32948e37bc2Smrg        # Otherwise, rely on $mkdir_umask.
33048e37bc2Smrg        if test -n "$dir_arg"; then
33148e37bc2Smrg          mkdir_mode=-m$mode
33248e37bc2Smrg        else
33348e37bc2Smrg          mkdir_mode=
33448e37bc2Smrg        fi
33548e37bc2Smrg
33648e37bc2Smrg        posix_mkdir=false
33748e37bc2Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
33848e37bc2Smrg	# here however when possible just to lower collision chance.
33948e37bc2Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34048e37bc2Smrg
34148e37bc2Smrg	trap '
34248e37bc2Smrg	  ret=$?
34348e37bc2Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
34448e37bc2Smrg	  exit $ret
34548e37bc2Smrg	' 0
34648e37bc2Smrg
34748e37bc2Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
34848e37bc2Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
34948e37bc2Smrg	# directory is successfully created first before we actually test
35048e37bc2Smrg	# 'mkdir -p'.
35148e37bc2Smrg	if (umask $mkdir_umask &&
35248e37bc2Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
35348e37bc2Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
35448e37bc2Smrg	then
35548e37bc2Smrg	  if test -z "$dir_arg" || {
35648e37bc2Smrg	       # Check for POSIX incompatibilities with -m.
35748e37bc2Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35848e37bc2Smrg	       # other-writable bit of parent directory when it shouldn't.
35948e37bc2Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
36048e37bc2Smrg	       test_tmpdir="$tmpdir/a"
36148e37bc2Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
36248e37bc2Smrg	       case $ls_ld_tmpdir in
36348e37bc2Smrg		 d????-?r-*) different_mode=700;;
36448e37bc2Smrg		 d????-?--*) different_mode=755;;
36548e37bc2Smrg		 *) false;;
36648e37bc2Smrg	       esac &&
36748e37bc2Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
36848e37bc2Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
36948e37bc2Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
37048e37bc2Smrg	       }
37148e37bc2Smrg	     }
37248e37bc2Smrg	  then posix_mkdir=:
37348e37bc2Smrg	  fi
37448e37bc2Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
3750cc6efb6Smrg	else
37648e37bc2Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
37748e37bc2Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
3780cc6efb6Smrg	fi
37948e37bc2Smrg	trap '' 0;;
3806cf5427aSmrg    esac
3810cc6efb6Smrg
3826cf5427aSmrg    if
3836cf5427aSmrg      $posix_mkdir && (
38448e37bc2Smrg        umask $mkdir_umask &&
38548e37bc2Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3866cf5427aSmrg      )
3876cf5427aSmrg    then :
3886cf5427aSmrg    else
3896cf5427aSmrg
39048e37bc2Smrg      # mkdir does not conform to POSIX,
3916cf5427aSmrg      # or it failed possibly due to a race condition.  Create the
3926cf5427aSmrg      # directory the slow way, step by step, checking for races as we go.
3936cf5427aSmrg
3946cf5427aSmrg      case $dstdir in
39548e37bc2Smrg        /*) prefix='/';;
39648e37bc2Smrg        [-=\(\)!]*) prefix='./';;
39748e37bc2Smrg        *)  prefix='';;
3986cf5427aSmrg      esac
3996cf5427aSmrg
4006cf5427aSmrg      oIFS=$IFS
4016cf5427aSmrg      IFS=/
40248e37bc2Smrg      set -f
4036cf5427aSmrg      set fnord $dstdir
4046cf5427aSmrg      shift
40548e37bc2Smrg      set +f
4066cf5427aSmrg      IFS=$oIFS
4076cf5427aSmrg
4086cf5427aSmrg      prefixes=
4096cf5427aSmrg
4106cf5427aSmrg      for d
4116cf5427aSmrg      do
41248e37bc2Smrg        test X"$d" = X && continue
41348e37bc2Smrg
41448e37bc2Smrg        prefix=$prefix$d
41548e37bc2Smrg        if test -d "$prefix"; then
41648e37bc2Smrg          prefixes=
41748e37bc2Smrg        else
41848e37bc2Smrg          if $posix_mkdir; then
41948e37bc2Smrg            (umask $mkdir_umask &&
42048e37bc2Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
42148e37bc2Smrg            # Don't fail if two instances are running concurrently.
42248e37bc2Smrg            test -d "$prefix" || exit 1
42348e37bc2Smrg          else
42448e37bc2Smrg            case $prefix in
42548e37bc2Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42648e37bc2Smrg              *) qprefix=$prefix;;
42748e37bc2Smrg            esac
42848e37bc2Smrg            prefixes="$prefixes '$qprefix'"
42948e37bc2Smrg          fi
43048e37bc2Smrg        fi
43148e37bc2Smrg        prefix=$prefix/
4326cf5427aSmrg      done
4336cf5427aSmrg
4346cf5427aSmrg      if test -n "$prefixes"; then
43548e37bc2Smrg        # Don't fail if two instances are running concurrently.
43648e37bc2Smrg        (umask $mkdir_umask &&
43748e37bc2Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
43848e37bc2Smrg          test -d "$dstdir" || exit 1
43948e37bc2Smrg        obsolete_mkdir_used=true
4406cf5427aSmrg      fi
4416cf5427aSmrg    fi
4426cf5427aSmrg  fi
4436cf5427aSmrg
4446cf5427aSmrg  if test -n "$dir_arg"; then
4456cf5427aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4466cf5427aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4476cf5427aSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4486cf5427aSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4496cf5427aSmrg  else
4506cf5427aSmrg
4516cf5427aSmrg    # Make a couple of temp file names in the proper directory.
45248e37bc2Smrg    dsttmp=${dstdirslash}_inst.$$_
45348e37bc2Smrg    rmtmp=${dstdirslash}_rm.$$_
4546cf5427aSmrg
4556cf5427aSmrg    # Trap to clean up those temp files at exit.
4566cf5427aSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4576cf5427aSmrg
4586cf5427aSmrg    # Copy the file name to the temp name.
45948e37bc2Smrg    (umask $cp_umask &&
46048e37bc2Smrg     { test -z "$stripcmd" || {
46148e37bc2Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
46248e37bc2Smrg	 # which would cause strip to fail.
46348e37bc2Smrg	 if test -z "$doit"; then
46448e37bc2Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
46548e37bc2Smrg	 else
46648e37bc2Smrg	   $doit touch "$dsttmp"
46748e37bc2Smrg	 fi
46848e37bc2Smrg       }
46948e37bc2Smrg     } &&
47048e37bc2Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
4716cf5427aSmrg
4726cf5427aSmrg    # and set any options; do chmod last to preserve setuid bits.
4736cf5427aSmrg    #
4746cf5427aSmrg    # If any of these fail, we abort the whole thing.  If we want to
4756cf5427aSmrg    # ignore errors from any of these, just make sure not to ignore
4766cf5427aSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4776cf5427aSmrg    #
4786cf5427aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4796cf5427aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4806cf5427aSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4816cf5427aSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4826cf5427aSmrg
4836cf5427aSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4846cf5427aSmrg    if $copy_on_change &&
48548e37bc2Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
48648e37bc2Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
48748e37bc2Smrg       set -f &&
4886cf5427aSmrg       set X $old && old=:$2:$4:$5:$6 &&
4896cf5427aSmrg       set X $new && new=:$2:$4:$5:$6 &&
49048e37bc2Smrg       set +f &&
4916cf5427aSmrg       test "$old" = "$new" &&
4926cf5427aSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4936cf5427aSmrg    then
4946cf5427aSmrg      rm -f "$dsttmp"
4956cf5427aSmrg    else
49648e37bc2Smrg      # If $backupsuffix is set, and the file being installed
49748e37bc2Smrg      # already exists, attempt a backup.  Don't worry if it fails,
49848e37bc2Smrg      # e.g., if mv doesn't support -f.
49948e37bc2Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
50048e37bc2Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
50148e37bc2Smrg      fi
50248e37bc2Smrg
5036cf5427aSmrg      # Rename the file to the real destination.
5046cf5427aSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
5056cf5427aSmrg
5066cf5427aSmrg      # The rename failed, perhaps because mv can't rename something else
5076cf5427aSmrg      # to itself, or perhaps because mv is so ancient that it does not
5086cf5427aSmrg      # support -f.
5096cf5427aSmrg      {
51048e37bc2Smrg        # Now remove or move aside any old file at destination location.
51148e37bc2Smrg        # We try this two ways since rm can't unlink itself on some
51248e37bc2Smrg        # systems and the destination file might be busy for other
51348e37bc2Smrg        # reasons.  In this case, the final cleanup might fail but the new
51448e37bc2Smrg        # file should still install successfully.
51548e37bc2Smrg        {
51648e37bc2Smrg          test ! -f "$dst" ||
51748e37bc2Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
51848e37bc2Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
51948e37bc2Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
52048e37bc2Smrg          } ||
52148e37bc2Smrg          { echo "$0: cannot unlink or rename $dst" >&2
52248e37bc2Smrg            (exit 1); exit 1
52348e37bc2Smrg          }
52448e37bc2Smrg        } &&
52548e37bc2Smrg
52648e37bc2Smrg        # Now rename the file to the real destination.
52748e37bc2Smrg        $doit $mvcmd "$dsttmp" "$dst"
5286cf5427aSmrg      }
5296cf5427aSmrg    fi || exit 1
5306cf5427aSmrg
5316cf5427aSmrg    trap '' 0
5326cf5427aSmrg  fi
5336cf5427aSmrgdone
5340cc6efb6Smrg
5356cf5427aSmrg# Local variables:
53648e37bc2Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
5376cf5427aSmrg# time-stamp-start: "scriptversion="
5386cf5427aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
53948e37bc2Smrg# time-stamp-time-zone: "UTC0"
5406cf5427aSmrg# time-stamp-end: "; # UTC"
5416cf5427aSmrg# End:
542