install-sh revision 6d8e82c3
13e747e6dSmrg#!/bin/sh
23e747e6dSmrg# install - install a program, script, or datafile
33e747e6dSmrg
46d8e82c3Smrgscriptversion=2020-11-14.01; # UTC
53e747e6dSmrg
63e747e6dSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
73e747e6dSmrg# later released in X11R6 (xc/config/util/install.sh) with the
83e747e6dSmrg# following copyright and license.
93e747e6dSmrg#
103e747e6dSmrg# Copyright (C) 1994 X Consortium
113e747e6dSmrg#
123e747e6dSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
133e747e6dSmrg# of this software and associated documentation files (the "Software"), to
143e747e6dSmrg# deal in the Software without restriction, including without limitation the
153e747e6dSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
163e747e6dSmrg# sell copies of the Software, and to permit persons to whom the Software is
173e747e6dSmrg# furnished to do so, subject to the following conditions:
183e747e6dSmrg#
193e747e6dSmrg# The above copyright notice and this permission notice shall be included in
203e747e6dSmrg# all copies or substantial portions of the Software.
213e747e6dSmrg#
223e747e6dSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233e747e6dSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
243e747e6dSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
253e747e6dSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
263e747e6dSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
273e747e6dSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
283e747e6dSmrg#
293e747e6dSmrg# Except as contained in this notice, the name of the X Consortium shall not
303e747e6dSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
313e747e6dSmrg# ings in this Software without prior written authorization from the X Consor-
323e747e6dSmrg# tium.
333e747e6dSmrg#
343e747e6dSmrg#
353e747e6dSmrg# FSF changes to this file are in the public domain.
363e747e6dSmrg#
373e747e6dSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38c2535118Smrg# 'make' implicit rules from creating a file called install from it
393e747e6dSmrg# when there is no Makefile.
403e747e6dSmrg#
413e747e6dSmrg# This script is compatible with the BSD install script, but was written
423e747e6dSmrg# from scratch.
433e747e6dSmrg
449cd34f4bSmrgtab='	'
453e747e6dSmrgnl='
463e747e6dSmrg'
479cd34f4bSmrgIFS=" $tab$nl"
483e747e6dSmrg
499cd34f4bSmrg# Set DOITPROG to "echo" to test this script.
503e747e6dSmrg
513e747e6dSmrgdoit=${DOITPROG-}
529cd34f4bSmrgdoit_exec=${doit:-exec}
533e747e6dSmrg
543e747e6dSmrg# Put in absolute file names if you don't have them in your path;
553e747e6dSmrg# or use environment vars.
563e747e6dSmrg
573e747e6dSmrgchgrpprog=${CHGRPPROG-chgrp}
583e747e6dSmrgchmodprog=${CHMODPROG-chmod}
593e747e6dSmrgchownprog=${CHOWNPROG-chown}
603e747e6dSmrgcmpprog=${CMPPROG-cmp}
613e747e6dSmrgcpprog=${CPPROG-cp}
623e747e6dSmrgmkdirprog=${MKDIRPROG-mkdir}
633e747e6dSmrgmvprog=${MVPROG-mv}
643e747e6dSmrgrmprog=${RMPROG-rm}
653e747e6dSmrgstripprog=${STRIPPROG-strip}
663e747e6dSmrg
673e747e6dSmrgposix_mkdir=
683e747e6dSmrg
693e747e6dSmrg# Desired mode of installed file.
703e747e6dSmrgmode=0755
713e747e6dSmrg
726d8e82c3Smrg# Create dirs (including intermediate dirs) using mode 755.
736d8e82c3Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
746d8e82c3Smrgmkdir_umask=22
756d8e82c3Smrg
766d8e82c3Smrgbackupsuffix=
773e747e6dSmrgchgrpcmd=
783e747e6dSmrgchmodcmd=$chmodprog
793e747e6dSmrgchowncmd=
803e747e6dSmrgmvcmd=$mvprog
813e747e6dSmrgrmcmd="$rmprog -f"
823e747e6dSmrgstripcmd=
833e747e6dSmrg
843e747e6dSmrgsrc=
853e747e6dSmrgdst=
863e747e6dSmrgdir_arg=
873e747e6dSmrgdst_arg=
883e747e6dSmrg
893e747e6dSmrgcopy_on_change=false
909cd34f4bSmrgis_target_a_directory=possibly
913e747e6dSmrg
923e747e6dSmrgusage="\
933e747e6dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
943e747e6dSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
953e747e6dSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
963e747e6dSmrg   or: $0 [OPTION]... -d DIRECTORIES...
973e747e6dSmrg
983e747e6dSmrgIn the 1st form, copy SRCFILE to DSTFILE.
993e747e6dSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1003e747e6dSmrgIn the 4th, create DIRECTORIES.
1013e747e6dSmrg
1023e747e6dSmrgOptions:
1033e747e6dSmrg     --help     display this help and exit.
1043e747e6dSmrg     --version  display version info and exit.
1053e747e6dSmrg
1063e747e6dSmrg  -c            (ignored)
1076d8e82c3Smrg  -C            install only if different (preserve data modification time)
1083e747e6dSmrg  -d            create directories instead of installing files.
1093e747e6dSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1103e747e6dSmrg  -m MODE       $chmodprog installed files to MODE.
1113e747e6dSmrg  -o USER       $chownprog installed files to USER.
1126d8e82c3Smrg  -p            pass -p to $cpprog.
1133e747e6dSmrg  -s            $stripprog installed files.
1146d8e82c3Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
1153e747e6dSmrg  -t DIRECTORY  install into DIRECTORY.
1163e747e6dSmrg  -T            report an error if DSTFILE is a directory.
1173e747e6dSmrg
1183e747e6dSmrgEnvironment variables override the default commands:
1193e747e6dSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1203e747e6dSmrg  RMPROG STRIPPROG
1216d8e82c3Smrg
1226d8e82c3SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
1236d8e82c3Smrgit's up to you to specify -f if you want it.
1246d8e82c3Smrg
1256d8e82c3SmrgIf -S is not specified, no backups are attempted.
1266d8e82c3Smrg
1276d8e82c3SmrgEmail bug reports to bug-automake@gnu.org.
1286d8e82c3SmrgAutomake home page: https://www.gnu.org/software/automake/
1293e747e6dSmrg"
1303e747e6dSmrg
1313e747e6dSmrgwhile test $# -ne 0; do
1323e747e6dSmrg  case $1 in
1333e747e6dSmrg    -c) ;;
1343e747e6dSmrg
1353e747e6dSmrg    -C) copy_on_change=true;;
1363e747e6dSmrg
1373e747e6dSmrg    -d) dir_arg=true;;
1383e747e6dSmrg
1393e747e6dSmrg    -g) chgrpcmd="$chgrpprog $2"
1409cd34f4bSmrg        shift;;
1413e747e6dSmrg
1423e747e6dSmrg    --help) echo "$usage"; exit $?;;
1433e747e6dSmrg
1443e747e6dSmrg    -m) mode=$2
1459cd34f4bSmrg        case $mode in
1469cd34f4bSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1479cd34f4bSmrg            echo "$0: invalid mode: $mode" >&2
1489cd34f4bSmrg            exit 1;;
1499cd34f4bSmrg        esac
1509cd34f4bSmrg        shift;;
1513e747e6dSmrg
1523e747e6dSmrg    -o) chowncmd="$chownprog $2"
1539cd34f4bSmrg        shift;;
1543e747e6dSmrg
1556d8e82c3Smrg    -p) cpprog="$cpprog -p";;
1566d8e82c3Smrg
1573e747e6dSmrg    -s) stripcmd=$stripprog;;
1583e747e6dSmrg
1596d8e82c3Smrg    -S) backupsuffix="$2"
1606d8e82c3Smrg        shift;;
1616d8e82c3Smrg
1629cd34f4bSmrg    -t)
1639cd34f4bSmrg        is_target_a_directory=always
1649cd34f4bSmrg        dst_arg=$2
1659cd34f4bSmrg        # Protect names problematic for 'test' and other utilities.
1669cd34f4bSmrg        case $dst_arg in
1679cd34f4bSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1689cd34f4bSmrg        esac
1699cd34f4bSmrg        shift;;
1703e747e6dSmrg
1719cd34f4bSmrg    -T) is_target_a_directory=never;;
1723e747e6dSmrg
1733e747e6dSmrg    --version) echo "$0 $scriptversion"; exit $?;;
1743e747e6dSmrg
1759cd34f4bSmrg    --) shift
1769cd34f4bSmrg        break;;
1773e747e6dSmrg
1789cd34f4bSmrg    -*) echo "$0: invalid option: $1" >&2
1799cd34f4bSmrg        exit 1;;
1803e747e6dSmrg
1813e747e6dSmrg    *)  break;;
1823e747e6dSmrg  esac
1833e747e6dSmrg  shift
1843e747e6dSmrgdone
1853e747e6dSmrg
1869cd34f4bSmrg# We allow the use of options -d and -T together, by making -d
1879cd34f4bSmrg# take the precedence; this is for compatibility with GNU install.
1889cd34f4bSmrg
1899cd34f4bSmrgif test -n "$dir_arg"; then
1909cd34f4bSmrg  if test -n "$dst_arg"; then
1919cd34f4bSmrg    echo "$0: target directory not allowed when installing a directory." >&2
1929cd34f4bSmrg    exit 1
1939cd34f4bSmrg  fi
1949cd34f4bSmrgfi
1959cd34f4bSmrg
1963e747e6dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1973e747e6dSmrg  # When -d is used, all remaining arguments are directories to create.
1983e747e6dSmrg  # When -t is used, the destination is already specified.
1993e747e6dSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
2003e747e6dSmrg  for arg
2013e747e6dSmrg  do
2023e747e6dSmrg    if test -n "$dst_arg"; then
2033e747e6dSmrg      # $@ is not empty: it contains at least $arg.
2043e747e6dSmrg      set fnord "$@" "$dst_arg"
2053e747e6dSmrg      shift # fnord
2063e747e6dSmrg    fi
2073e747e6dSmrg    shift # arg
2083e747e6dSmrg    dst_arg=$arg
209c2535118Smrg    # Protect names problematic for 'test' and other utilities.
210c2535118Smrg    case $dst_arg in
211c2535118Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
212c2535118Smrg    esac
2133e747e6dSmrg  done
2143e747e6dSmrgfi
2153e747e6dSmrg
2163e747e6dSmrgif test $# -eq 0; then
2173e747e6dSmrg  if test -z "$dir_arg"; then
2183e747e6dSmrg    echo "$0: no input file specified." >&2
2193e747e6dSmrg    exit 1
2203e747e6dSmrg  fi
221c2535118Smrg  # It's OK to call 'install-sh -d' without argument.
2223e747e6dSmrg  # This can happen when creating conditional directories.
2233e747e6dSmrg  exit 0
2243e747e6dSmrgfi
2253e747e6dSmrg
2269cd34f4bSmrgif test -z "$dir_arg"; then
2279cd34f4bSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
2289cd34f4bSmrg    if test ! -d "$dst_arg"; then
2299cd34f4bSmrg      echo "$0: $dst_arg: Is not a directory." >&2
2309cd34f4bSmrg      exit 1
2319cd34f4bSmrg    fi
2329cd34f4bSmrg  fi
2339cd34f4bSmrgfi
2349cd34f4bSmrg
2353e747e6dSmrgif test -z "$dir_arg"; then
236c2535118Smrg  do_exit='(exit $ret); exit $ret'
237c2535118Smrg  trap "ret=129; $do_exit" 1
238c2535118Smrg  trap "ret=130; $do_exit" 2
239c2535118Smrg  trap "ret=141; $do_exit" 13
240c2535118Smrg  trap "ret=143; $do_exit" 15
2413e747e6dSmrg
2423e747e6dSmrg  # Set umask so as not to create temps with too-generous modes.
2433e747e6dSmrg  # However, 'strip' requires both read and write access to temps.
2443e747e6dSmrg  case $mode in
2453e747e6dSmrg    # Optimize common cases.
2463e747e6dSmrg    *644) cp_umask=133;;
2473e747e6dSmrg    *755) cp_umask=22;;
2483e747e6dSmrg
2493e747e6dSmrg    *[0-7])
2503e747e6dSmrg      if test -z "$stripcmd"; then
2519cd34f4bSmrg        u_plus_rw=
2523e747e6dSmrg      else
2539cd34f4bSmrg        u_plus_rw='% 200'
2543e747e6dSmrg      fi
2553e747e6dSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2563e747e6dSmrg    *)
2573e747e6dSmrg      if test -z "$stripcmd"; then
2589cd34f4bSmrg        u_plus_rw=
2593e747e6dSmrg      else
2609cd34f4bSmrg        u_plus_rw=,u+rw
2613e747e6dSmrg      fi
2623e747e6dSmrg      cp_umask=$mode$u_plus_rw;;
2633e747e6dSmrg  esac
2643e747e6dSmrgfi
2653e747e6dSmrg
2663e747e6dSmrgfor src
2673e747e6dSmrgdo
268c2535118Smrg  # Protect names problematic for 'test' and other utilities.
2693e747e6dSmrg  case $src in
270c2535118Smrg    -* | [=\(\)!]) src=./$src;;
2713e747e6dSmrg  esac
2723e747e6dSmrg
2733e747e6dSmrg  if test -n "$dir_arg"; then
2743e747e6dSmrg    dst=$src
2753e747e6dSmrg    dstdir=$dst
2763e747e6dSmrg    test -d "$dstdir"
2773e747e6dSmrg    dstdir_status=$?
2786d8e82c3Smrg    # Don't chown directories that already exist.
2796d8e82c3Smrg    if test $dstdir_status = 0; then
2806d8e82c3Smrg      chowncmd=""
2816d8e82c3Smrg    fi
2823e747e6dSmrg  else
2833e747e6dSmrg
2843e747e6dSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2853e747e6dSmrg    # might cause directories to be created, which would be especially bad
2863e747e6dSmrg    # if $src (and thus $dsttmp) contains '*'.
2873e747e6dSmrg    if test ! -f "$src" && test ! -d "$src"; then
2883e747e6dSmrg      echo "$0: $src does not exist." >&2
2893e747e6dSmrg      exit 1
2903e747e6dSmrg    fi
2913e747e6dSmrg
2923e747e6dSmrg    if test -z "$dst_arg"; then
2933e747e6dSmrg      echo "$0: no destination specified." >&2
2943e747e6dSmrg      exit 1
2953e747e6dSmrg    fi
2963e747e6dSmrg    dst=$dst_arg
2973e747e6dSmrg
2986d8e82c3Smrg    # If destination is a directory, append the input filename.
2993e747e6dSmrg    if test -d "$dst"; then
3009cd34f4bSmrg      if test "$is_target_a_directory" = never; then
3019cd34f4bSmrg        echo "$0: $dst_arg: Is a directory" >&2
3029cd34f4bSmrg        exit 1
3033e747e6dSmrg      fi
3043e747e6dSmrg      dstdir=$dst
3056d8e82c3Smrg      dstbase=`basename "$src"`
3066d8e82c3Smrg      case $dst in
3076d8e82c3Smrg	*/) dst=$dst$dstbase;;
3086d8e82c3Smrg	*)  dst=$dst/$dstbase;;
3096d8e82c3Smrg      esac
3103e747e6dSmrg      dstdir_status=0
3113e747e6dSmrg    else
3129cd34f4bSmrg      dstdir=`dirname "$dst"`
3133e747e6dSmrg      test -d "$dstdir"
3143e747e6dSmrg      dstdir_status=$?
3153e747e6dSmrg    fi
3163e747e6dSmrg  fi
3173e747e6dSmrg
3186d8e82c3Smrg  case $dstdir in
3196d8e82c3Smrg    */) dstdirslash=$dstdir;;
3206d8e82c3Smrg    *)  dstdirslash=$dstdir/;;
3216d8e82c3Smrg  esac
3226d8e82c3Smrg
3233e747e6dSmrg  obsolete_mkdir_used=false
3243e747e6dSmrg
3253e747e6dSmrg  if test $dstdir_status != 0; then
3263e747e6dSmrg    case $posix_mkdir in
3273e747e6dSmrg      '')
3289cd34f4bSmrg        # With -d, create the new directory with the user-specified mode.
3299cd34f4bSmrg        # Otherwise, rely on $mkdir_umask.
3309cd34f4bSmrg        if test -n "$dir_arg"; then
3319cd34f4bSmrg          mkdir_mode=-m$mode
3329cd34f4bSmrg        else
3339cd34f4bSmrg          mkdir_mode=
3349cd34f4bSmrg        fi
3359cd34f4bSmrg
3369cd34f4bSmrg        posix_mkdir=false
3376d8e82c3Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
3386d8e82c3Smrg	# here however when possible just to lower collision chance.
3396d8e82c3Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3406d8e82c3Smrg
3416d8e82c3Smrg	trap '
3426d8e82c3Smrg	  ret=$?
3436d8e82c3Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
3446d8e82c3Smrg	  exit $ret
3456d8e82c3Smrg	' 0
3466d8e82c3Smrg
3476d8e82c3Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
3486d8e82c3Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
3496d8e82c3Smrg	# directory is successfully created first before we actually test
3506d8e82c3Smrg	# 'mkdir -p'.
3516d8e82c3Smrg	if (umask $mkdir_umask &&
3526d8e82c3Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
3536d8e82c3Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
3546d8e82c3Smrg	then
3556d8e82c3Smrg	  if test -z "$dir_arg" || {
3566d8e82c3Smrg	       # Check for POSIX incompatibilities with -m.
3576d8e82c3Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3586d8e82c3Smrg	       # other-writable bit of parent directory when it shouldn't.
3596d8e82c3Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3606d8e82c3Smrg	       test_tmpdir="$tmpdir/a"
3616d8e82c3Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
3626d8e82c3Smrg	       case $ls_ld_tmpdir in
3636d8e82c3Smrg		 d????-?r-*) different_mode=700;;
3646d8e82c3Smrg		 d????-?--*) different_mode=755;;
3656d8e82c3Smrg		 *) false;;
3666d8e82c3Smrg	       esac &&
3676d8e82c3Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
3686d8e82c3Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
3696d8e82c3Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3706d8e82c3Smrg	       }
3716d8e82c3Smrg	     }
3726d8e82c3Smrg	  then posix_mkdir=:
3736d8e82c3Smrg	  fi
3746d8e82c3Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
3756d8e82c3Smrg	else
3766d8e82c3Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
3776d8e82c3Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
3786d8e82c3Smrg	fi
3796d8e82c3Smrg	trap '' 0;;
3803e747e6dSmrg    esac
3813e747e6dSmrg
3823e747e6dSmrg    if
3833e747e6dSmrg      $posix_mkdir && (
3849cd34f4bSmrg        umask $mkdir_umask &&
3859cd34f4bSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3863e747e6dSmrg      )
3873e747e6dSmrg    then :
3883e747e6dSmrg    else
3893e747e6dSmrg
3906d8e82c3Smrg      # mkdir does not conform to POSIX,
3913e747e6dSmrg      # or it failed possibly due to a race condition.  Create the
3923e747e6dSmrg      # directory the slow way, step by step, checking for races as we go.
3933e747e6dSmrg
3943e747e6dSmrg      case $dstdir in
3959cd34f4bSmrg        /*) prefix='/';;
3969cd34f4bSmrg        [-=\(\)!]*) prefix='./';;
3979cd34f4bSmrg        *)  prefix='';;
3983e747e6dSmrg      esac
3993e747e6dSmrg
4003e747e6dSmrg      oIFS=$IFS
4013e747e6dSmrg      IFS=/
4029cd34f4bSmrg      set -f
4033e747e6dSmrg      set fnord $dstdir
4043e747e6dSmrg      shift
4059cd34f4bSmrg      set +f
4063e747e6dSmrg      IFS=$oIFS
4073e747e6dSmrg
4083e747e6dSmrg      prefixes=
4093e747e6dSmrg
4103e747e6dSmrg      for d
4113e747e6dSmrg      do
4129cd34f4bSmrg        test X"$d" = X && continue
4139cd34f4bSmrg
4149cd34f4bSmrg        prefix=$prefix$d
4159cd34f4bSmrg        if test -d "$prefix"; then
4169cd34f4bSmrg          prefixes=
4179cd34f4bSmrg        else
4189cd34f4bSmrg          if $posix_mkdir; then
4196d8e82c3Smrg            (umask $mkdir_umask &&
4209cd34f4bSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4219cd34f4bSmrg            # Don't fail if two instances are running concurrently.
4229cd34f4bSmrg            test -d "$prefix" || exit 1
4239cd34f4bSmrg          else
4249cd34f4bSmrg            case $prefix in
4259cd34f4bSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4269cd34f4bSmrg              *) qprefix=$prefix;;
4279cd34f4bSmrg            esac
4289cd34f4bSmrg            prefixes="$prefixes '$qprefix'"
4299cd34f4bSmrg          fi
4309cd34f4bSmrg        fi
4319cd34f4bSmrg        prefix=$prefix/
4323e747e6dSmrg      done
4333e747e6dSmrg
4343e747e6dSmrg      if test -n "$prefixes"; then
4359cd34f4bSmrg        # Don't fail if two instances are running concurrently.
4369cd34f4bSmrg        (umask $mkdir_umask &&
4379cd34f4bSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
4389cd34f4bSmrg          test -d "$dstdir" || exit 1
4399cd34f4bSmrg        obsolete_mkdir_used=true
4403e747e6dSmrg      fi
4413e747e6dSmrg    fi
4423e747e6dSmrg  fi
4433e747e6dSmrg
4443e747e6dSmrg  if test -n "$dir_arg"; then
4453e747e6dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4463e747e6dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4473e747e6dSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4483e747e6dSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4493e747e6dSmrg  else
4503e747e6dSmrg
4513e747e6dSmrg    # Make a couple of temp file names in the proper directory.
4526d8e82c3Smrg    dsttmp=${dstdirslash}_inst.$$_
4536d8e82c3Smrg    rmtmp=${dstdirslash}_rm.$$_
4543e747e6dSmrg
4553e747e6dSmrg    # Trap to clean up those temp files at exit.
4563e747e6dSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4573e747e6dSmrg
4583e747e6dSmrg    # Copy the file name to the temp name.
4596d8e82c3Smrg    (umask $cp_umask &&
4606d8e82c3Smrg     { test -z "$stripcmd" || {
4616d8e82c3Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
4626d8e82c3Smrg	 # which would cause strip to fail.
4636d8e82c3Smrg	 if test -z "$doit"; then
4646d8e82c3Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
4656d8e82c3Smrg	 else
4666d8e82c3Smrg	   $doit touch "$dsttmp"
4676d8e82c3Smrg	 fi
4686d8e82c3Smrg       }
4696d8e82c3Smrg     } &&
4706d8e82c3Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
4713e747e6dSmrg
4723e747e6dSmrg    # and set any options; do chmod last to preserve setuid bits.
4733e747e6dSmrg    #
4743e747e6dSmrg    # If any of these fail, we abort the whole thing.  If we want to
4753e747e6dSmrg    # ignore errors from any of these, just make sure not to ignore
4763e747e6dSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4773e747e6dSmrg    #
4783e747e6dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4793e747e6dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4803e747e6dSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4813e747e6dSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4823e747e6dSmrg
4833e747e6dSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4843e747e6dSmrg    if $copy_on_change &&
4859cd34f4bSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4869cd34f4bSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
4879cd34f4bSmrg       set -f &&
4883e747e6dSmrg       set X $old && old=:$2:$4:$5:$6 &&
4893e747e6dSmrg       set X $new && new=:$2:$4:$5:$6 &&
4909cd34f4bSmrg       set +f &&
4913e747e6dSmrg       test "$old" = "$new" &&
4923e747e6dSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4933e747e6dSmrg    then
4943e747e6dSmrg      rm -f "$dsttmp"
4953e747e6dSmrg    else
4966d8e82c3Smrg      # If $backupsuffix is set, and the file being installed
4976d8e82c3Smrg      # already exists, attempt a backup.  Don't worry if it fails,
4986d8e82c3Smrg      # e.g., if mv doesn't support -f.
4996d8e82c3Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
5006d8e82c3Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
5016d8e82c3Smrg      fi
5026d8e82c3Smrg
5033e747e6dSmrg      # Rename the file to the real destination.
5043e747e6dSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
5053e747e6dSmrg
5063e747e6dSmrg      # The rename failed, perhaps because mv can't rename something else
5073e747e6dSmrg      # to itself, or perhaps because mv is so ancient that it does not
5083e747e6dSmrg      # support -f.
5093e747e6dSmrg      {
5109cd34f4bSmrg        # Now remove or move aside any old file at destination location.
5119cd34f4bSmrg        # We try this two ways since rm can't unlink itself on some
5129cd34f4bSmrg        # systems and the destination file might be busy for other
5139cd34f4bSmrg        # reasons.  In this case, the final cleanup might fail but the new
5149cd34f4bSmrg        # file should still install successfully.
5159cd34f4bSmrg        {
5169cd34f4bSmrg          test ! -f "$dst" ||
5176d8e82c3Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
5189cd34f4bSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
5196d8e82c3Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
5209cd34f4bSmrg          } ||
5219cd34f4bSmrg          { echo "$0: cannot unlink or rename $dst" >&2
5229cd34f4bSmrg            (exit 1); exit 1
5239cd34f4bSmrg          }
5249cd34f4bSmrg        } &&
5259cd34f4bSmrg
5269cd34f4bSmrg        # Now rename the file to the real destination.
5279cd34f4bSmrg        $doit $mvcmd "$dsttmp" "$dst"
5283e747e6dSmrg      }
5293e747e6dSmrg    fi || exit 1
5303e747e6dSmrg
5313e747e6dSmrg    trap '' 0
5323e747e6dSmrg  fi
5333e747e6dSmrgdone
5343e747e6dSmrg
5353e747e6dSmrg# Local variables:
5366d8e82c3Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
5373e747e6dSmrg# time-stamp-start: "scriptversion="
5383e747e6dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5396d8e82c3Smrg# time-stamp-time-zone: "UTC0"
5407a2631fcSmrg# time-stamp-end: "; # UTC"
5413e747e6dSmrg# End:
542