install-sh revision 3d13e800
192bb16f8Smrg#!/bin/sh
292bb16f8Smrg# install - install a program, script, or datafile
392bb16f8Smrg
43d13e800Smrgscriptversion=2020-11-14.01; # UTC
592bb16f8Smrg
692bb16f8Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
792bb16f8Smrg# later released in X11R6 (xc/config/util/install.sh) with the
892bb16f8Smrg# following copyright and license.
992bb16f8Smrg#
1092bb16f8Smrg# Copyright (C) 1994 X Consortium
1192bb16f8Smrg#
1292bb16f8Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1392bb16f8Smrg# of this software and associated documentation files (the "Software"), to
1492bb16f8Smrg# deal in the Software without restriction, including without limitation the
1592bb16f8Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1692bb16f8Smrg# sell copies of the Software, and to permit persons to whom the Software is
1792bb16f8Smrg# furnished to do so, subject to the following conditions:
1892bb16f8Smrg#
1992bb16f8Smrg# The above copyright notice and this permission notice shall be included in
2092bb16f8Smrg# all copies or substantial portions of the Software.
2192bb16f8Smrg#
2292bb16f8Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2392bb16f8Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2492bb16f8Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2592bb16f8Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2692bb16f8Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2792bb16f8Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2892bb16f8Smrg#
2992bb16f8Smrg# Except as contained in this notice, the name of the X Consortium shall not
3092bb16f8Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3192bb16f8Smrg# ings in this Software without prior written authorization from the X Consor-
3292bb16f8Smrg# tium.
3392bb16f8Smrg#
3492bb16f8Smrg#
3592bb16f8Smrg# FSF changes to this file are in the public domain.
3692bb16f8Smrg#
3792bb16f8Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3801395c31Smrg# 'make' implicit rules from creating a file called install from it
3992bb16f8Smrg# when there is no Makefile.
4092bb16f8Smrg#
4192bb16f8Smrg# This script is compatible with the BSD install script, but was written
428255a313Smrg# from scratch.
438255a313Smrg
4401395c31Smrgtab='	'
458255a313Smrgnl='
468255a313Smrg'
4701395c31SmrgIFS=" $tab$nl"
4892bb16f8Smrg
4901395c31Smrg# Set DOITPROG to "echo" to test this script.
5092bb16f8Smrg
518255a313Smrgdoit=${DOITPROG-}
5201395c31Smrgdoit_exec=${doit:-exec}
5392bb16f8Smrg
548255a313Smrg# Put in absolute file names if you don't have them in your path;
558255a313Smrg# or use environment vars.
568255a313Smrg
578255a313Smrgchgrpprog=${CHGRPPROG-chgrp}
588255a313Smrgchmodprog=${CHMODPROG-chmod}
598255a313Smrgchownprog=${CHOWNPROG-chown}
608255a313Smrgcmpprog=${CMPPROG-cmp}
618255a313Smrgcpprog=${CPPROG-cp}
628255a313Smrgmkdirprog=${MKDIRPROG-mkdir}
638255a313Smrgmvprog=${MVPROG-mv}
648255a313Smrgrmprog=${RMPROG-rm}
658255a313Smrgstripprog=${STRIPPROG-strip}
668255a313Smrg
678255a313Smrgposix_mkdir=
688255a313Smrg
698255a313Smrg# Desired mode of installed file.
708255a313Smrgmode=0755
7192bb16f8Smrg
723d13e800Smrg# Create dirs (including intermediate dirs) using mode 755.
733d13e800Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
743d13e800Smrgmkdir_umask=22
753d13e800Smrg
763d13e800Smrgbackupsuffix=
7792bb16f8Smrgchgrpcmd=
788255a313Smrgchmodcmd=$chmodprog
798255a313Smrgchowncmd=
808255a313Smrgmvcmd=$mvprog
8192bb16f8Smrgrmcmd="$rmprog -f"
828255a313Smrgstripcmd=
838255a313Smrg
8492bb16f8Smrgsrc=
8592bb16f8Smrgdst=
8692bb16f8Smrgdir_arg=
878255a313Smrgdst_arg=
888255a313Smrg
898255a313Smrgcopy_on_change=false
9001395c31Smrgis_target_a_directory=possibly
9192bb16f8Smrg
928255a313Smrgusage="\
938255a313SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
9492bb16f8Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9592bb16f8Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9692bb16f8Smrg   or: $0 [OPTION]... -d DIRECTORIES...
9792bb16f8Smrg
9892bb16f8SmrgIn the 1st form, copy SRCFILE to DSTFILE.
9992bb16f8SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
10092bb16f8SmrgIn the 4th, create DIRECTORIES.
10192bb16f8Smrg
10292bb16f8SmrgOptions:
1038255a313Smrg     --help     display this help and exit.
1048255a313Smrg     --version  display version info and exit.
1058255a313Smrg
1068255a313Smrg  -c            (ignored)
1073d13e800Smrg  -C            install only if different (preserve data modification time)
1088255a313Smrg  -d            create directories instead of installing files.
1098255a313Smrg  -g GROUP      $chgrpprog installed files to GROUP.
1108255a313Smrg  -m MODE       $chmodprog installed files to MODE.
1118255a313Smrg  -o USER       $chownprog installed files to USER.
1123d13e800Smrg  -p            pass -p to $cpprog.
1138255a313Smrg  -s            $stripprog installed files.
1143d13e800Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
1158255a313Smrg  -t DIRECTORY  install into DIRECTORY.
1168255a313Smrg  -T            report an error if DSTFILE is a directory.
11792bb16f8Smrg
11892bb16f8SmrgEnvironment variables override the default commands:
1198255a313Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1208255a313Smrg  RMPROG STRIPPROG
1213d13e800Smrg
1223d13e800SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
1233d13e800Smrgit's up to you to specify -f if you want it.
1243d13e800Smrg
1253d13e800SmrgIf -S is not specified, no backups are attempted.
1263d13e800Smrg
1273d13e800SmrgEmail bug reports to bug-automake@gnu.org.
1283d13e800SmrgAutomake home page: https://www.gnu.org/software/automake/
12992bb16f8Smrg"
13092bb16f8Smrg
1318255a313Smrgwhile test $# -ne 0; do
13292bb16f8Smrg  case $1 in
1338255a313Smrg    -c) ;;
1348255a313Smrg
1358255a313Smrg    -C) copy_on_change=true;;
13692bb16f8Smrg
1378255a313Smrg    -d) dir_arg=true;;
13892bb16f8Smrg
13992bb16f8Smrg    -g) chgrpcmd="$chgrpprog $2"
14001395c31Smrg        shift;;
14192bb16f8Smrg
14292bb16f8Smrg    --help) echo "$usage"; exit $?;;
14392bb16f8Smrg
1448255a313Smrg    -m) mode=$2
14501395c31Smrg        case $mode in
14601395c31Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
14701395c31Smrg            echo "$0: invalid mode: $mode" >&2
14801395c31Smrg            exit 1;;
14901395c31Smrg        esac
15001395c31Smrg        shift;;
15192bb16f8Smrg
15292bb16f8Smrg    -o) chowncmd="$chownprog $2"
15301395c31Smrg        shift;;
15492bb16f8Smrg
1553d13e800Smrg    -p) cpprog="$cpprog -p";;
1563d13e800Smrg
1578255a313Smrg    -s) stripcmd=$stripprog;;
15892bb16f8Smrg
1593d13e800Smrg    -S) backupsuffix="$2"
1603d13e800Smrg        shift;;
1613d13e800Smrg
16201395c31Smrg    -t)
16301395c31Smrg        is_target_a_directory=always
16401395c31Smrg        dst_arg=$2
16501395c31Smrg        # Protect names problematic for 'test' and other utilities.
16601395c31Smrg        case $dst_arg in
16701395c31Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
16801395c31Smrg        esac
16901395c31Smrg        shift;;
17092bb16f8Smrg
17101395c31Smrg    -T) is_target_a_directory=never;;
17292bb16f8Smrg
17392bb16f8Smrg    --version) echo "$0 $scriptversion"; exit $?;;
17492bb16f8Smrg
17501395c31Smrg    --) shift
17601395c31Smrg        break;;
1778255a313Smrg
17801395c31Smrg    -*) echo "$0: invalid option: $1" >&2
17901395c31Smrg        exit 1;;
1808255a313Smrg
1818255a313Smrg    *)  break;;
18292bb16f8Smrg  esac
1838255a313Smrg  shift
18492bb16f8Smrgdone
18592bb16f8Smrg
18601395c31Smrg# We allow the use of options -d and -T together, by making -d
18701395c31Smrg# take the precedence; this is for compatibility with GNU install.
18801395c31Smrg
18901395c31Smrgif test -n "$dir_arg"; then
19001395c31Smrg  if test -n "$dst_arg"; then
19101395c31Smrg    echo "$0: target directory not allowed when installing a directory." >&2
19201395c31Smrg    exit 1
19301395c31Smrg  fi
19401395c31Smrgfi
19501395c31Smrg
1968255a313Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1978255a313Smrg  # When -d is used, all remaining arguments are directories to create.
1988255a313Smrg  # When -t is used, the destination is already specified.
1998255a313Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
2008255a313Smrg  for arg
2018255a313Smrg  do
2028255a313Smrg    if test -n "$dst_arg"; then
2038255a313Smrg      # $@ is not empty: it contains at least $arg.
2048255a313Smrg      set fnord "$@" "$dst_arg"
2058255a313Smrg      shift # fnord
2068255a313Smrg    fi
2078255a313Smrg    shift # arg
2088255a313Smrg    dst_arg=$arg
20901395c31Smrg    # Protect names problematic for 'test' and other utilities.
21001395c31Smrg    case $dst_arg in
21101395c31Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
21201395c31Smrg    esac
2138255a313Smrg  done
2148255a313Smrgfi
2158255a313Smrg
2168255a313Smrgif test $# -eq 0; then
21792bb16f8Smrg  if test -z "$dir_arg"; then
21892bb16f8Smrg    echo "$0: no input file specified." >&2
21992bb16f8Smrg    exit 1
22092bb16f8Smrg  fi
22101395c31Smrg  # It's OK to call 'install-sh -d' without argument.
22292bb16f8Smrg  # This can happen when creating conditional directories.
22392bb16f8Smrg  exit 0
22492bb16f8Smrgfi
22592bb16f8Smrg
2268255a313Smrgif test -z "$dir_arg"; then
22701395c31Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
22801395c31Smrg    if test ! -d "$dst_arg"; then
22901395c31Smrg      echo "$0: $dst_arg: Is not a directory." >&2
23001395c31Smrg      exit 1
23101395c31Smrg    fi
23201395c31Smrg  fi
23301395c31Smrgfi
23401395c31Smrg
23501395c31Smrgif test -z "$dir_arg"; then
23601395c31Smrg  do_exit='(exit $ret); exit $ret'
23701395c31Smrg  trap "ret=129; $do_exit" 1
23801395c31Smrg  trap "ret=130; $do_exit" 2
23901395c31Smrg  trap "ret=141; $do_exit" 13
24001395c31Smrg  trap "ret=143; $do_exit" 15
2418255a313Smrg
2428255a313Smrg  # Set umask so as not to create temps with too-generous modes.
2438255a313Smrg  # However, 'strip' requires both read and write access to temps.
2448255a313Smrg  case $mode in
2458255a313Smrg    # Optimize common cases.
2468255a313Smrg    *644) cp_umask=133;;
2478255a313Smrg    *755) cp_umask=22;;
2488255a313Smrg
2498255a313Smrg    *[0-7])
2508255a313Smrg      if test -z "$stripcmd"; then
25101395c31Smrg        u_plus_rw=
2528255a313Smrg      else
25301395c31Smrg        u_plus_rw='% 200'
2548255a313Smrg      fi
2558255a313Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2568255a313Smrg    *)
2578255a313Smrg      if test -z "$stripcmd"; then
25801395c31Smrg        u_plus_rw=
2598255a313Smrg      else
26001395c31Smrg        u_plus_rw=,u+rw
2618255a313Smrg      fi
2628255a313Smrg      cp_umask=$mode$u_plus_rw;;
2638255a313Smrg  esac
2648255a313Smrgfi
2658255a313Smrg
26692bb16f8Smrgfor src
26792bb16f8Smrgdo
26801395c31Smrg  # Protect names problematic for 'test' and other utilities.
26992bb16f8Smrg  case $src in
27001395c31Smrg    -* | [=\(\)!]) src=./$src;;
27192bb16f8Smrg  esac
27292bb16f8Smrg
27392bb16f8Smrg  if test -n "$dir_arg"; then
27492bb16f8Smrg    dst=$src
2758255a313Smrg    dstdir=$dst
2768255a313Smrg    test -d "$dstdir"
2778255a313Smrg    dstdir_status=$?
2783d13e800Smrg    # Don't chown directories that already exist.
2793d13e800Smrg    if test $dstdir_status = 0; then
2803d13e800Smrg      chowncmd=""
2813d13e800Smrg    fi
28292bb16f8Smrg  else
2838255a313Smrg
28492bb16f8Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
28592bb16f8Smrg    # might cause directories to be created, which would be especially bad
28692bb16f8Smrg    # if $src (and thus $dsttmp) contains '*'.
28792bb16f8Smrg    if test ! -f "$src" && test ! -d "$src"; then
28892bb16f8Smrg      echo "$0: $src does not exist." >&2
28992bb16f8Smrg      exit 1
29092bb16f8Smrg    fi
29192bb16f8Smrg
2928255a313Smrg    if test -z "$dst_arg"; then
29392bb16f8Smrg      echo "$0: no destination specified." >&2
29492bb16f8Smrg      exit 1
29592bb16f8Smrg    fi
2968255a313Smrg    dst=$dst_arg
29792bb16f8Smrg
29801395c31Smrg    # If destination is a directory, append the input filename.
29992bb16f8Smrg    if test -d "$dst"; then
30001395c31Smrg      if test "$is_target_a_directory" = never; then
30101395c31Smrg        echo "$0: $dst_arg: Is a directory" >&2
30201395c31Smrg        exit 1
30392bb16f8Smrg      fi
3048255a313Smrg      dstdir=$dst
30501395c31Smrg      dstbase=`basename "$src"`
30601395c31Smrg      case $dst in
30701395c31Smrg	*/) dst=$dst$dstbase;;
30801395c31Smrg	*)  dst=$dst/$dstbase;;
30901395c31Smrg      esac
3108255a313Smrg      dstdir_status=0
3118255a313Smrg    else
31201395c31Smrg      dstdir=`dirname "$dst"`
3138255a313Smrg      test -d "$dstdir"
3148255a313Smrg      dstdir_status=$?
31592bb16f8Smrg    fi
31692bb16f8Smrg  fi
31792bb16f8Smrg
31801395c31Smrg  case $dstdir in
31901395c31Smrg    */) dstdirslash=$dstdir;;
32001395c31Smrg    *)  dstdirslash=$dstdir/;;
32101395c31Smrg  esac
32201395c31Smrg
3238255a313Smrg  obsolete_mkdir_used=false
3248255a313Smrg
3258255a313Smrg  if test $dstdir_status != 0; then
3268255a313Smrg    case $posix_mkdir in
3278255a313Smrg      '')
32801395c31Smrg        # With -d, create the new directory with the user-specified mode.
32901395c31Smrg        # Otherwise, rely on $mkdir_umask.
33001395c31Smrg        if test -n "$dir_arg"; then
33101395c31Smrg          mkdir_mode=-m$mode
33201395c31Smrg        else
33301395c31Smrg          mkdir_mode=
33401395c31Smrg        fi
33501395c31Smrg
33601395c31Smrg        posix_mkdir=false
3373d13e800Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
3383d13e800Smrg	# here however when possible just to lower collision chance.
3393d13e800Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3403d13e800Smrg
3413d13e800Smrg	trap '
3423d13e800Smrg	  ret=$?
3433d13e800Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
3443d13e800Smrg	  exit $ret
3453d13e800Smrg	' 0
3463d13e800Smrg
3473d13e800Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
3483d13e800Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
3493d13e800Smrg	# directory is successfully created first before we actually test
3503d13e800Smrg	# 'mkdir -p'.
3513d13e800Smrg	if (umask $mkdir_umask &&
3523d13e800Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
3533d13e800Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
3543d13e800Smrg	then
3553d13e800Smrg	  if test -z "$dir_arg" || {
3563d13e800Smrg	       # Check for POSIX incompatibilities with -m.
3573d13e800Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3583d13e800Smrg	       # other-writable bit of parent directory when it shouldn't.
3593d13e800Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3603d13e800Smrg	       test_tmpdir="$tmpdir/a"
3613d13e800Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
3623d13e800Smrg	       case $ls_ld_tmpdir in
3633d13e800Smrg		 d????-?r-*) different_mode=700;;
3643d13e800Smrg		 d????-?--*) different_mode=755;;
3653d13e800Smrg		 *) false;;
3663d13e800Smrg	       esac &&
3673d13e800Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
3683d13e800Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
3693d13e800Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3703d13e800Smrg	       }
3713d13e800Smrg	     }
3723d13e800Smrg	  then posix_mkdir=:
3733d13e800Smrg	  fi
3743d13e800Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
3753d13e800Smrg	else
3763d13e800Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
3773d13e800Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
3783d13e800Smrg	fi
3793d13e800Smrg	trap '' 0;;
3808255a313Smrg    esac
38192bb16f8Smrg
3828255a313Smrg    if
3838255a313Smrg      $posix_mkdir && (
38401395c31Smrg        umask $mkdir_umask &&
38501395c31Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3868255a313Smrg      )
3878255a313Smrg    then :
3888255a313Smrg    else
38992bb16f8Smrg
3903d13e800Smrg      # mkdir does not conform to POSIX,
3918255a313Smrg      # or it failed possibly due to a race condition.  Create the
3928255a313Smrg      # directory the slow way, step by step, checking for races as we go.
39392bb16f8Smrg
3948255a313Smrg      case $dstdir in
39501395c31Smrg        /*) prefix='/';;
39601395c31Smrg        [-=\(\)!]*) prefix='./';;
39701395c31Smrg        *)  prefix='';;
3988255a313Smrg      esac
39992bb16f8Smrg
4008255a313Smrg      oIFS=$IFS
4018255a313Smrg      IFS=/
40201395c31Smrg      set -f
4038255a313Smrg      set fnord $dstdir
40492bb16f8Smrg      shift
40501395c31Smrg      set +f
4068255a313Smrg      IFS=$oIFS
4078255a313Smrg
4088255a313Smrg      prefixes=
4098255a313Smrg
4108255a313Smrg      for d
4118255a313Smrg      do
41201395c31Smrg        test X"$d" = X && continue
41301395c31Smrg
41401395c31Smrg        prefix=$prefix$d
41501395c31Smrg        if test -d "$prefix"; then
41601395c31Smrg          prefixes=
41701395c31Smrg        else
41801395c31Smrg          if $posix_mkdir; then
4193d13e800Smrg            (umask $mkdir_umask &&
42001395c31Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
42101395c31Smrg            # Don't fail if two instances are running concurrently.
42201395c31Smrg            test -d "$prefix" || exit 1
42301395c31Smrg          else
42401395c31Smrg            case $prefix in
42501395c31Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42601395c31Smrg              *) qprefix=$prefix;;
42701395c31Smrg            esac
42801395c31Smrg            prefixes="$prefixes '$qprefix'"
42901395c31Smrg          fi
43001395c31Smrg        fi
43101395c31Smrg        prefix=$prefix/
4328255a313Smrg      done
4338255a313Smrg
4348255a313Smrg      if test -n "$prefixes"; then
43501395c31Smrg        # Don't fail if two instances are running concurrently.
43601395c31Smrg        (umask $mkdir_umask &&
43701395c31Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
43801395c31Smrg          test -d "$dstdir" || exit 1
43901395c31Smrg        obsolete_mkdir_used=true
44092bb16f8Smrg      fi
4418255a313Smrg    fi
44292bb16f8Smrg  fi
44392bb16f8Smrg
44492bb16f8Smrg  if test -n "$dir_arg"; then
4458255a313Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4468255a313Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4478255a313Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4488255a313Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44992bb16f8Smrg  else
45092bb16f8Smrg
45192bb16f8Smrg    # Make a couple of temp file names in the proper directory.
45201395c31Smrg    dsttmp=${dstdirslash}_inst.$$_
45301395c31Smrg    rmtmp=${dstdirslash}_rm.$$_
45492bb16f8Smrg
45592bb16f8Smrg    # Trap to clean up those temp files at exit.
45692bb16f8Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45792bb16f8Smrg
45892bb16f8Smrg    # Copy the file name to the temp name.
4593d13e800Smrg    (umask $cp_umask &&
4603d13e800Smrg     { test -z "$stripcmd" || {
4613d13e800Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
4623d13e800Smrg	 # which would cause strip to fail.
4633d13e800Smrg	 if test -z "$doit"; then
4643d13e800Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
4653d13e800Smrg	 else
4663d13e800Smrg	   $doit touch "$dsttmp"
4673d13e800Smrg	 fi
4683d13e800Smrg       }
4693d13e800Smrg     } &&
4703d13e800Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
47192bb16f8Smrg
47292bb16f8Smrg    # and set any options; do chmod last to preserve setuid bits.
47392bb16f8Smrg    #
47492bb16f8Smrg    # If any of these fail, we abort the whole thing.  If we want to
47592bb16f8Smrg    # ignore errors from any of these, just make sure not to ignore
47692bb16f8Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
47792bb16f8Smrg    #
4788255a313Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4798255a313Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4808255a313Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4818255a313Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4828255a313Smrg
4838255a313Smrg    # If -C, don't bother to copy if it wouldn't change the file.
4848255a313Smrg    if $copy_on_change &&
48501395c31Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
48601395c31Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
48701395c31Smrg       set -f &&
4888255a313Smrg       set X $old && old=:$2:$4:$5:$6 &&
4898255a313Smrg       set X $new && new=:$2:$4:$5:$6 &&
49001395c31Smrg       set +f &&
4918255a313Smrg       test "$old" = "$new" &&
4928255a313Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4938255a313Smrg    then
4948255a313Smrg      rm -f "$dsttmp"
4958255a313Smrg    else
4963d13e800Smrg      # If $backupsuffix is set, and the file being installed
4973d13e800Smrg      # already exists, attempt a backup.  Don't worry if it fails,
4983d13e800Smrg      # e.g., if mv doesn't support -f.
4993d13e800Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
5003d13e800Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
5013d13e800Smrg      fi
5023d13e800Smrg
5038255a313Smrg      # Rename the file to the real destination.
5048255a313Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
5058255a313Smrg
5068255a313Smrg      # The rename failed, perhaps because mv can't rename something else
5078255a313Smrg      # to itself, or perhaps because mv is so ancient that it does not
5088255a313Smrg      # support -f.
5098255a313Smrg      {
51001395c31Smrg        # Now remove or move aside any old file at destination location.
51101395c31Smrg        # We try this two ways since rm can't unlink itself on some
51201395c31Smrg        # systems and the destination file might be busy for other
51301395c31Smrg        # reasons.  In this case, the final cleanup might fail but the new
51401395c31Smrg        # file should still install successfully.
51501395c31Smrg        {
51601395c31Smrg          test ! -f "$dst" ||
5173d13e800Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
51801395c31Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
5193d13e800Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
52001395c31Smrg          } ||
52101395c31Smrg          { echo "$0: cannot unlink or rename $dst" >&2
52201395c31Smrg            (exit 1); exit 1
52301395c31Smrg          }
52401395c31Smrg        } &&
52501395c31Smrg
52601395c31Smrg        # Now rename the file to the real destination.
52701395c31Smrg        $doit $mvcmd "$dsttmp" "$dst"
5288255a313Smrg      }
5298255a313Smrg    fi || exit 1
5308255a313Smrg
5318255a313Smrg    trap '' 0
5328255a313Smrg  fi
53392bb16f8Smrgdone
53492bb16f8Smrg
53592bb16f8Smrg# Local variables:
53601395c31Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
53792bb16f8Smrg# time-stamp-start: "scriptversion="
53892bb16f8Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
53901395c31Smrg# time-stamp-time-zone: "UTC0"
5408255a313Smrg# time-stamp-end: "; # UTC"
54192bb16f8Smrg# End:
542