19027f4a0Smrg#!/bin/sh
29027f4a0Smrg# install - install a program, script, or datafile
39027f4a0Smrg
40d6f290aSmrgscriptversion=2020-11-14.01; # UTC
59027f4a0Smrg
69027f4a0Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
79027f4a0Smrg# later released in X11R6 (xc/config/util/install.sh) with the
89027f4a0Smrg# following copyright and license.
99027f4a0Smrg#
109027f4a0Smrg# Copyright (C) 1994 X Consortium
119027f4a0Smrg#
129027f4a0Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
139027f4a0Smrg# of this software and associated documentation files (the "Software"), to
149027f4a0Smrg# deal in the Software without restriction, including without limitation the
159027f4a0Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
169027f4a0Smrg# sell copies of the Software, and to permit persons to whom the Software is
179027f4a0Smrg# furnished to do so, subject to the following conditions:
189027f4a0Smrg#
199027f4a0Smrg# The above copyright notice and this permission notice shall be included in
209027f4a0Smrg# all copies or substantial portions of the Software.
219027f4a0Smrg#
229027f4a0Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
239027f4a0Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
249027f4a0Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
259027f4a0Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
269027f4a0Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
279027f4a0Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
289027f4a0Smrg#
299027f4a0Smrg# Except as contained in this notice, the name of the X Consortium shall not
309027f4a0Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
319027f4a0Smrg# ings in this Software without prior written authorization from the X Consor-
329027f4a0Smrg# tium.
339027f4a0Smrg#
349027f4a0Smrg#
359027f4a0Smrg# FSF changes to this file are in the public domain.
369027f4a0Smrg#
379027f4a0Smrg# Calling this script install-sh is preferred over install.sh, to prevent
38fe2ac8d7Smrg# 'make' implicit rules from creating a file called install from it
399027f4a0Smrg# when there is no Makefile.
409027f4a0Smrg#
419027f4a0Smrg# This script is compatible with the BSD install script, but was written
423a72f200Smrg# from scratch.
433a72f200Smrg
44376c9fa8Smrgtab='	'
453a72f200Smrgnl='
463a72f200Smrg'
47376c9fa8SmrgIFS=" $tab$nl"
489027f4a0Smrg
49376c9fa8Smrg# Set DOITPROG to "echo" to test this script.
509027f4a0Smrg
513a72f200Smrgdoit=${DOITPROG-}
52376c9fa8Smrgdoit_exec=${doit:-exec}
539027f4a0Smrg
543a72f200Smrg# Put in absolute file names if you don't have them in your path;
553a72f200Smrg# or use environment vars.
563a72f200Smrg
573a72f200Smrgchgrpprog=${CHGRPPROG-chgrp}
583a72f200Smrgchmodprog=${CHMODPROG-chmod}
593a72f200Smrgchownprog=${CHOWNPROG-chown}
603a72f200Smrgcmpprog=${CMPPROG-cmp}
613a72f200Smrgcpprog=${CPPROG-cp}
623a72f200Smrgmkdirprog=${MKDIRPROG-mkdir}
633a72f200Smrgmvprog=${MVPROG-mv}
643a72f200Smrgrmprog=${RMPROG-rm}
653a72f200Smrgstripprog=${STRIPPROG-strip}
663a72f200Smrg
673a72f200Smrgposix_mkdir=
683a72f200Smrg
693a72f200Smrg# Desired mode of installed file.
703a72f200Smrgmode=0755
719027f4a0Smrg
720d6f290aSmrg# Create dirs (including intermediate dirs) using mode 755.
730d6f290aSmrg# This is like GNU 'install' as of coreutils 8.32 (2020).
740d6f290aSmrgmkdir_umask=22
750d6f290aSmrg
760d6f290aSmrgbackupsuffix=
779027f4a0Smrgchgrpcmd=
783a72f200Smrgchmodcmd=$chmodprog
793a72f200Smrgchowncmd=
803a72f200Smrgmvcmd=$mvprog
819027f4a0Smrgrmcmd="$rmprog -f"
823a72f200Smrgstripcmd=
833a72f200Smrg
849027f4a0Smrgsrc=
859027f4a0Smrgdst=
869027f4a0Smrgdir_arg=
873a72f200Smrgdst_arg=
883a72f200Smrg
893a72f200Smrgcopy_on_change=false
90376c9fa8Smrgis_target_a_directory=possibly
919027f4a0Smrg
923a72f200Smrgusage="\
933a72f200SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
949027f4a0Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
959027f4a0Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
969027f4a0Smrg   or: $0 [OPTION]... -d DIRECTORIES...
979027f4a0Smrg
989027f4a0SmrgIn the 1st form, copy SRCFILE to DSTFILE.
999027f4a0SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1009027f4a0SmrgIn the 4th, create DIRECTORIES.
1019027f4a0Smrg
1029027f4a0SmrgOptions:
1033a72f200Smrg     --help     display this help and exit.
1043a72f200Smrg     --version  display version info and exit.
1053a72f200Smrg
1063a72f200Smrg  -c            (ignored)
1070d6f290aSmrg  -C            install only if different (preserve data modification time)
1083a72f200Smrg  -d            create directories instead of installing files.
1093a72f200Smrg  -g GROUP      $chgrpprog installed files to GROUP.
1103a72f200Smrg  -m MODE       $chmodprog installed files to MODE.
1113a72f200Smrg  -o USER       $chownprog installed files to USER.
1120d6f290aSmrg  -p            pass -p to $cpprog.
1133a72f200Smrg  -s            $stripprog installed files.
1140d6f290aSmrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
1153a72f200Smrg  -t DIRECTORY  install into DIRECTORY.
1163a72f200Smrg  -T            report an error if DSTFILE is a directory.
1179027f4a0Smrg
1189027f4a0SmrgEnvironment variables override the default commands:
1193a72f200Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1203a72f200Smrg  RMPROG STRIPPROG
1210d6f290aSmrg
1220d6f290aSmrgBy default, rm is invoked with -f; when overridden with RMPROG,
1230d6f290aSmrgit's up to you to specify -f if you want it.
1240d6f290aSmrg
1250d6f290aSmrgIf -S is not specified, no backups are attempted.
1260d6f290aSmrg
1270d6f290aSmrgEmail bug reports to bug-automake@gnu.org.
1280d6f290aSmrgAutomake home page: https://www.gnu.org/software/automake/
1299027f4a0Smrg"
1309027f4a0Smrg
1313a72f200Smrgwhile test $# -ne 0; do
1329027f4a0Smrg  case $1 in
1333a72f200Smrg    -c) ;;
1343a72f200Smrg
1353a72f200Smrg    -C) copy_on_change=true;;
1369027f4a0Smrg
1373a72f200Smrg    -d) dir_arg=true;;
1389027f4a0Smrg
1399027f4a0Smrg    -g) chgrpcmd="$chgrpprog $2"
140376c9fa8Smrg        shift;;
1419027f4a0Smrg
1429027f4a0Smrg    --help) echo "$usage"; exit $?;;
1439027f4a0Smrg
1443a72f200Smrg    -m) mode=$2
145376c9fa8Smrg        case $mode in
146376c9fa8Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
147376c9fa8Smrg            echo "$0: invalid mode: $mode" >&2
148376c9fa8Smrg            exit 1;;
149376c9fa8Smrg        esac
150376c9fa8Smrg        shift;;
1519027f4a0Smrg
1529027f4a0Smrg    -o) chowncmd="$chownprog $2"
153376c9fa8Smrg        shift;;
1549027f4a0Smrg
1550d6f290aSmrg    -p) cpprog="$cpprog -p";;
1560d6f290aSmrg
1573a72f200Smrg    -s) stripcmd=$stripprog;;
1589027f4a0Smrg
1590d6f290aSmrg    -S) backupsuffix="$2"
1600d6f290aSmrg        shift;;
1610d6f290aSmrg
162376c9fa8Smrg    -t)
163376c9fa8Smrg        is_target_a_directory=always
164376c9fa8Smrg        dst_arg=$2
165376c9fa8Smrg        # Protect names problematic for 'test' and other utilities.
166376c9fa8Smrg        case $dst_arg in
167376c9fa8Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
168376c9fa8Smrg        esac
169376c9fa8Smrg        shift;;
1709027f4a0Smrg
171376c9fa8Smrg    -T) is_target_a_directory=never;;
1729027f4a0Smrg
1739027f4a0Smrg    --version) echo "$0 $scriptversion"; exit $?;;
1749027f4a0Smrg
175376c9fa8Smrg    --) shift
176376c9fa8Smrg        break;;
1773a72f200Smrg
178376c9fa8Smrg    -*) echo "$0: invalid option: $1" >&2
179376c9fa8Smrg        exit 1;;
1803a72f200Smrg
1813a72f200Smrg    *)  break;;
1829027f4a0Smrg  esac
1833a72f200Smrg  shift
1849027f4a0Smrgdone
1859027f4a0Smrg
186376c9fa8Smrg# We allow the use of options -d and -T together, by making -d
187376c9fa8Smrg# take the precedence; this is for compatibility with GNU install.
188376c9fa8Smrg
189376c9fa8Smrgif test -n "$dir_arg"; then
190376c9fa8Smrg  if test -n "$dst_arg"; then
191376c9fa8Smrg    echo "$0: target directory not allowed when installing a directory." >&2
192376c9fa8Smrg    exit 1
193376c9fa8Smrg  fi
194376c9fa8Smrgfi
195376c9fa8Smrg
1963a72f200Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1973a72f200Smrg  # When -d is used, all remaining arguments are directories to create.
1983a72f200Smrg  # When -t is used, the destination is already specified.
1993a72f200Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
2003a72f200Smrg  for arg
2013a72f200Smrg  do
2023a72f200Smrg    if test -n "$dst_arg"; then
2033a72f200Smrg      # $@ is not empty: it contains at least $arg.
2043a72f200Smrg      set fnord "$@" "$dst_arg"
2053a72f200Smrg      shift # fnord
2063a72f200Smrg    fi
2073a72f200Smrg    shift # arg
2083a72f200Smrg    dst_arg=$arg
209fe2ac8d7Smrg    # Protect names problematic for 'test' and other utilities.
210fe2ac8d7Smrg    case $dst_arg in
211fe2ac8d7Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
212fe2ac8d7Smrg    esac
2133a72f200Smrg  done
2143a72f200Smrgfi
2153a72f200Smrg
2163a72f200Smrgif test $# -eq 0; then
2179027f4a0Smrg  if test -z "$dir_arg"; then
2189027f4a0Smrg    echo "$0: no input file specified." >&2
2199027f4a0Smrg    exit 1
2209027f4a0Smrg  fi
221fe2ac8d7Smrg  # It's OK to call 'install-sh -d' without argument.
2229027f4a0Smrg  # This can happen when creating conditional directories.
2239027f4a0Smrg  exit 0
2249027f4a0Smrgfi
2259027f4a0Smrg
226376c9fa8Smrgif test -z "$dir_arg"; then
227376c9fa8Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
228376c9fa8Smrg    if test ! -d "$dst_arg"; then
229376c9fa8Smrg      echo "$0: $dst_arg: Is not a directory." >&2
230376c9fa8Smrg      exit 1
231376c9fa8Smrg    fi
232376c9fa8Smrg  fi
233376c9fa8Smrgfi
234376c9fa8Smrg
2353a72f200Smrgif test -z "$dir_arg"; then
236fe2ac8d7Smrg  do_exit='(exit $ret); exit $ret'
237fe2ac8d7Smrg  trap "ret=129; $do_exit" 1
238fe2ac8d7Smrg  trap "ret=130; $do_exit" 2
239fe2ac8d7Smrg  trap "ret=141; $do_exit" 13
240fe2ac8d7Smrg  trap "ret=143; $do_exit" 15
2413a72f200Smrg
2423a72f200Smrg  # Set umask so as not to create temps with too-generous modes.
2433a72f200Smrg  # However, 'strip' requires both read and write access to temps.
2443a72f200Smrg  case $mode in
2453a72f200Smrg    # Optimize common cases.
2463a72f200Smrg    *644) cp_umask=133;;
2473a72f200Smrg    *755) cp_umask=22;;
2483a72f200Smrg
2493a72f200Smrg    *[0-7])
2503a72f200Smrg      if test -z "$stripcmd"; then
251376c9fa8Smrg        u_plus_rw=
2523a72f200Smrg      else
253376c9fa8Smrg        u_plus_rw='% 200'
2543a72f200Smrg      fi
2553a72f200Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2563a72f200Smrg    *)
2573a72f200Smrg      if test -z "$stripcmd"; then
258376c9fa8Smrg        u_plus_rw=
2593a72f200Smrg      else
260376c9fa8Smrg        u_plus_rw=,u+rw
2613a72f200Smrg      fi
2623a72f200Smrg      cp_umask=$mode$u_plus_rw;;
2633a72f200Smrg  esac
2643a72f200Smrgfi
2653a72f200Smrg
2669027f4a0Smrgfor src
2679027f4a0Smrgdo
268fe2ac8d7Smrg  # Protect names problematic for 'test' and other utilities.
2699027f4a0Smrg  case $src in
270fe2ac8d7Smrg    -* | [=\(\)!]) src=./$src;;
2719027f4a0Smrg  esac
2729027f4a0Smrg
2739027f4a0Smrg  if test -n "$dir_arg"; then
2749027f4a0Smrg    dst=$src
2753a72f200Smrg    dstdir=$dst
2763a72f200Smrg    test -d "$dstdir"
2773a72f200Smrg    dstdir_status=$?
2780d6f290aSmrg    # Don't chown directories that already exist.
2790d6f290aSmrg    if test $dstdir_status = 0; then
2800d6f290aSmrg      chowncmd=""
2810d6f290aSmrg    fi
2829027f4a0Smrg  else
2833a72f200Smrg
2849027f4a0Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2859027f4a0Smrg    # might cause directories to be created, which would be especially bad
2869027f4a0Smrg    # if $src (and thus $dsttmp) contains '*'.
2879027f4a0Smrg    if test ! -f "$src" && test ! -d "$src"; then
2889027f4a0Smrg      echo "$0: $src does not exist." >&2
2899027f4a0Smrg      exit 1
2909027f4a0Smrg    fi
2919027f4a0Smrg
2923a72f200Smrg    if test -z "$dst_arg"; then
2939027f4a0Smrg      echo "$0: no destination specified." >&2
2949027f4a0Smrg      exit 1
2959027f4a0Smrg    fi
2963a72f200Smrg    dst=$dst_arg
2979027f4a0Smrg
2980d6f290aSmrg    # If destination is a directory, append the input filename.
2999027f4a0Smrg    if test -d "$dst"; then
300376c9fa8Smrg      if test "$is_target_a_directory" = never; then
301376c9fa8Smrg        echo "$0: $dst_arg: Is a directory" >&2
302376c9fa8Smrg        exit 1
3039027f4a0Smrg      fi
3043a72f200Smrg      dstdir=$dst
3050d6f290aSmrg      dstbase=`basename "$src"`
3060d6f290aSmrg      case $dst in
3070d6f290aSmrg	*/) dst=$dst$dstbase;;
3080d6f290aSmrg	*)  dst=$dst/$dstbase;;
3090d6f290aSmrg      esac
3103a72f200Smrg      dstdir_status=0
3113a72f200Smrg    else
312376c9fa8Smrg      dstdir=`dirname "$dst"`
3133a72f200Smrg      test -d "$dstdir"
3143a72f200Smrg      dstdir_status=$?
3159027f4a0Smrg    fi
3169027f4a0Smrg  fi
3179027f4a0Smrg
3180d6f290aSmrg  case $dstdir in
3190d6f290aSmrg    */) dstdirslash=$dstdir;;
3200d6f290aSmrg    *)  dstdirslash=$dstdir/;;
3210d6f290aSmrg  esac
3220d6f290aSmrg
3233a72f200Smrg  obsolete_mkdir_used=false
3243a72f200Smrg
3253a72f200Smrg  if test $dstdir_status != 0; then
3263a72f200Smrg    case $posix_mkdir in
3273a72f200Smrg      '')
328376c9fa8Smrg        # With -d, create the new directory with the user-specified mode.
329376c9fa8Smrg        # Otherwise, rely on $mkdir_umask.
330376c9fa8Smrg        if test -n "$dir_arg"; then
331376c9fa8Smrg          mkdir_mode=-m$mode
332376c9fa8Smrg        else
333376c9fa8Smrg          mkdir_mode=
334376c9fa8Smrg        fi
335376c9fa8Smrg
336376c9fa8Smrg        posix_mkdir=false
3370d6f290aSmrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
3380d6f290aSmrg	# here however when possible just to lower collision chance.
3390d6f290aSmrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3400d6f290aSmrg
3410d6f290aSmrg	trap '
3420d6f290aSmrg	  ret=$?
3430d6f290aSmrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
3440d6f290aSmrg	  exit $ret
3450d6f290aSmrg	' 0
3460d6f290aSmrg
3470d6f290aSmrg	# Because "mkdir -p" follows existing symlinks and we likely work
3480d6f290aSmrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
3490d6f290aSmrg	# directory is successfully created first before we actually test
3500d6f290aSmrg	# 'mkdir -p'.
3510d6f290aSmrg	if (umask $mkdir_umask &&
3520d6f290aSmrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
3530d6f290aSmrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
3540d6f290aSmrg	then
3550d6f290aSmrg	  if test -z "$dir_arg" || {
3560d6f290aSmrg	       # Check for POSIX incompatibilities with -m.
3570d6f290aSmrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3580d6f290aSmrg	       # other-writable bit of parent directory when it shouldn't.
3590d6f290aSmrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3600d6f290aSmrg	       test_tmpdir="$tmpdir/a"
3610d6f290aSmrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
3620d6f290aSmrg	       case $ls_ld_tmpdir in
3630d6f290aSmrg		 d????-?r-*) different_mode=700;;
3640d6f290aSmrg		 d????-?--*) different_mode=755;;
3650d6f290aSmrg		 *) false;;
3660d6f290aSmrg	       esac &&
3670d6f290aSmrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
3680d6f290aSmrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
3690d6f290aSmrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3700d6f290aSmrg	       }
3710d6f290aSmrg	     }
3720d6f290aSmrg	  then posix_mkdir=:
3730d6f290aSmrg	  fi
3740d6f290aSmrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
3750d6f290aSmrg	else
3760d6f290aSmrg	  # Remove any dirs left behind by ancient mkdir implementations.
3770d6f290aSmrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
3780d6f290aSmrg	fi
3790d6f290aSmrg	trap '' 0;;
3803a72f200Smrg    esac
3819027f4a0Smrg
3823a72f200Smrg    if
3833a72f200Smrg      $posix_mkdir && (
384376c9fa8Smrg        umask $mkdir_umask &&
385376c9fa8Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3863a72f200Smrg      )
3873a72f200Smrg    then :
3883a72f200Smrg    else
3899027f4a0Smrg
3900d6f290aSmrg      # mkdir does not conform to POSIX,
3913a72f200Smrg      # or it failed possibly due to a race condition.  Create the
3923a72f200Smrg      # directory the slow way, step by step, checking for races as we go.
3939027f4a0Smrg
3943a72f200Smrg      case $dstdir in
395376c9fa8Smrg        /*) prefix='/';;
396376c9fa8Smrg        [-=\(\)!]*) prefix='./';;
397376c9fa8Smrg        *)  prefix='';;
3983a72f200Smrg      esac
3999027f4a0Smrg
4003a72f200Smrg      oIFS=$IFS
4013a72f200Smrg      IFS=/
402376c9fa8Smrg      set -f
4033a72f200Smrg      set fnord $dstdir
4049027f4a0Smrg      shift
405376c9fa8Smrg      set +f
4063a72f200Smrg      IFS=$oIFS
4073a72f200Smrg
4083a72f200Smrg      prefixes=
4093a72f200Smrg
4103a72f200Smrg      for d
4113a72f200Smrg      do
412376c9fa8Smrg        test X"$d" = X && continue
413376c9fa8Smrg
414376c9fa8Smrg        prefix=$prefix$d
415376c9fa8Smrg        if test -d "$prefix"; then
416376c9fa8Smrg          prefixes=
417376c9fa8Smrg        else
418376c9fa8Smrg          if $posix_mkdir; then
4190d6f290aSmrg            (umask $mkdir_umask &&
420376c9fa8Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
421376c9fa8Smrg            # Don't fail if two instances are running concurrently.
422376c9fa8Smrg            test -d "$prefix" || exit 1
423376c9fa8Smrg          else
424376c9fa8Smrg            case $prefix in
425376c9fa8Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
426376c9fa8Smrg              *) qprefix=$prefix;;
427376c9fa8Smrg            esac
428376c9fa8Smrg            prefixes="$prefixes '$qprefix'"
429376c9fa8Smrg          fi
430376c9fa8Smrg        fi
431376c9fa8Smrg        prefix=$prefix/
4323a72f200Smrg      done
4333a72f200Smrg
4343a72f200Smrg      if test -n "$prefixes"; then
435376c9fa8Smrg        # Don't fail if two instances are running concurrently.
436376c9fa8Smrg        (umask $mkdir_umask &&
437376c9fa8Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
438376c9fa8Smrg          test -d "$dstdir" || exit 1
439376c9fa8Smrg        obsolete_mkdir_used=true
4409027f4a0Smrg      fi
4413a72f200Smrg    fi
4429027f4a0Smrg  fi
4439027f4a0Smrg
4449027f4a0Smrg  if test -n "$dir_arg"; then
4453a72f200Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4463a72f200Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4473a72f200Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4483a72f200Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4499027f4a0Smrg  else
4509027f4a0Smrg
4519027f4a0Smrg    # Make a couple of temp file names in the proper directory.
4520d6f290aSmrg    dsttmp=${dstdirslash}_inst.$$_
4530d6f290aSmrg    rmtmp=${dstdirslash}_rm.$$_
4549027f4a0Smrg
4559027f4a0Smrg    # Trap to clean up those temp files at exit.
4569027f4a0Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4579027f4a0Smrg
4589027f4a0Smrg    # Copy the file name to the temp name.
4590d6f290aSmrg    (umask $cp_umask &&
4600d6f290aSmrg     { test -z "$stripcmd" || {
4610d6f290aSmrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
4620d6f290aSmrg	 # which would cause strip to fail.
4630d6f290aSmrg	 if test -z "$doit"; then
4640d6f290aSmrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
4650d6f290aSmrg	 else
4660d6f290aSmrg	   $doit touch "$dsttmp"
4670d6f290aSmrg	 fi
4680d6f290aSmrg       }
4690d6f290aSmrg     } &&
4700d6f290aSmrg     $doit_exec $cpprog "$src" "$dsttmp") &&
4719027f4a0Smrg
4729027f4a0Smrg    # and set any options; do chmod last to preserve setuid bits.
4739027f4a0Smrg    #
4749027f4a0Smrg    # If any of these fail, we abort the whole thing.  If we want to
4759027f4a0Smrg    # ignore errors from any of these, just make sure not to ignore
4769027f4a0Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4779027f4a0Smrg    #
4783a72f200Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4793a72f200Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4803a72f200Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4813a72f200Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4823a72f200Smrg
4833a72f200Smrg    # If -C, don't bother to copy if it wouldn't change the file.
4843a72f200Smrg    if $copy_on_change &&
485376c9fa8Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
486376c9fa8Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
487376c9fa8Smrg       set -f &&
4883a72f200Smrg       set X $old && old=:$2:$4:$5:$6 &&
4893a72f200Smrg       set X $new && new=:$2:$4:$5:$6 &&
490376c9fa8Smrg       set +f &&
4913a72f200Smrg       test "$old" = "$new" &&
4923a72f200Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4933a72f200Smrg    then
4943a72f200Smrg      rm -f "$dsttmp"
4953a72f200Smrg    else
4960d6f290aSmrg      # If $backupsuffix is set, and the file being installed
4970d6f290aSmrg      # already exists, attempt a backup.  Don't worry if it fails,
4980d6f290aSmrg      # e.g., if mv doesn't support -f.
4990d6f290aSmrg      if test -n "$backupsuffix" && test -f "$dst"; then
5000d6f290aSmrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
5010d6f290aSmrg      fi
5020d6f290aSmrg
5033a72f200Smrg      # Rename the file to the real destination.
5043a72f200Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
5053a72f200Smrg
5063a72f200Smrg      # The rename failed, perhaps because mv can't rename something else
5073a72f200Smrg      # to itself, or perhaps because mv is so ancient that it does not
5083a72f200Smrg      # support -f.
5093a72f200Smrg      {
510376c9fa8Smrg        # Now remove or move aside any old file at destination location.
511376c9fa8Smrg        # We try this two ways since rm can't unlink itself on some
512376c9fa8Smrg        # systems and the destination file might be busy for other
513376c9fa8Smrg        # reasons.  In this case, the final cleanup might fail but the new
514376c9fa8Smrg        # file should still install successfully.
515376c9fa8Smrg        {
516376c9fa8Smrg          test ! -f "$dst" ||
5170d6f290aSmrg          $doit $rmcmd "$dst" 2>/dev/null ||
518376c9fa8Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
5190d6f290aSmrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
520376c9fa8Smrg          } ||
521376c9fa8Smrg          { echo "$0: cannot unlink or rename $dst" >&2
522376c9fa8Smrg            (exit 1); exit 1
523376c9fa8Smrg          }
524376c9fa8Smrg        } &&
525376c9fa8Smrg
526376c9fa8Smrg        # Now rename the file to the real destination.
527376c9fa8Smrg        $doit $mvcmd "$dsttmp" "$dst"
5283a72f200Smrg      }
5293a72f200Smrg    fi || exit 1
5303a72f200Smrg
5313a72f200Smrg    trap '' 0
5323a72f200Smrg  fi
5339027f4a0Smrgdone
5349027f4a0Smrg
5359027f4a0Smrg# Local variables:
5360d6f290aSmrg# eval: (add-hook 'before-save-hook 'time-stamp)
5379027f4a0Smrg# time-stamp-start: "scriptversion="
5389027f4a0Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5390d6f290aSmrg# time-stamp-time-zone: "UTC0"
5403a72f200Smrg# time-stamp-end: "; # UTC"
5419027f4a0Smrg# End:
542