install-sh revision 22663e35
11d54945dSmrg#!/bin/sh
21d54945dSmrg# install - install a program, script, or datafile
31d54945dSmrg
422663e35Smrgscriptversion=2020-11-14.01; # UTC
51d54945dSmrg
61d54945dSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
71d54945dSmrg# later released in X11R6 (xc/config/util/install.sh) with the
81d54945dSmrg# following copyright and license.
91d54945dSmrg#
101d54945dSmrg# Copyright (C) 1994 X Consortium
111d54945dSmrg#
121d54945dSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
131d54945dSmrg# of this software and associated documentation files (the "Software"), to
141d54945dSmrg# deal in the Software without restriction, including without limitation the
151d54945dSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
161d54945dSmrg# sell copies of the Software, and to permit persons to whom the Software is
171d54945dSmrg# furnished to do so, subject to the following conditions:
181d54945dSmrg#
191d54945dSmrg# The above copyright notice and this permission notice shall be included in
201d54945dSmrg# all copies or substantial portions of the Software.
211d54945dSmrg#
221d54945dSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
231d54945dSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
241d54945dSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
251d54945dSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
261d54945dSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
271d54945dSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
281d54945dSmrg#
291d54945dSmrg# Except as contained in this notice, the name of the X Consortium shall not
301d54945dSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
311d54945dSmrg# ings in this Software without prior written authorization from the X Consor-
321d54945dSmrg# tium.
331d54945dSmrg#
341d54945dSmrg#
351d54945dSmrg# FSF changes to this file are in the public domain.
361d54945dSmrg#
371d54945dSmrg# Calling this script install-sh is preferred over install.sh, to prevent
387322289dSmrg# 'make' implicit rules from creating a file called install from it
391d54945dSmrg# when there is no Makefile.
401d54945dSmrg#
411d54945dSmrg# This script is compatible with the BSD install script, but was written
42ba85709eSmrg# from scratch.
43ba85709eSmrg
447322289dSmrgtab='	'
45ba85709eSmrgnl='
46ba85709eSmrg'
477322289dSmrgIFS=" $tab$nl"
481d54945dSmrg
497322289dSmrg# Set DOITPROG to "echo" to test this script.
501d54945dSmrg
51786a6f21Smrgdoit=${DOITPROG-}
527322289dSmrgdoit_exec=${doit:-exec}
531d54945dSmrg
54ba85709eSmrg# Put in absolute file names if you don't have them in your path;
55ba85709eSmrg# or use environment vars.
561d54945dSmrg
57786a6f21Smrgchgrpprog=${CHGRPPROG-chgrp}
58786a6f21Smrgchmodprog=${CHMODPROG-chmod}
59786a6f21Smrgchownprog=${CHOWNPROG-chown}
60786a6f21Smrgcmpprog=${CMPPROG-cmp}
61786a6f21Smrgcpprog=${CPPROG-cp}
62786a6f21Smrgmkdirprog=${MKDIRPROG-mkdir}
63786a6f21Smrgmvprog=${MVPROG-mv}
64786a6f21Smrgrmprog=${RMPROG-rm}
65786a6f21Smrgstripprog=${STRIPPROG-strip}
66786a6f21Smrg
67ba85709eSmrgposix_mkdir=
68ba85709eSmrg
69ba85709eSmrg# Desired mode of installed file.
70ba85709eSmrgmode=0755
71ba85709eSmrg
7222663e35Smrg# Create dirs (including intermediate dirs) using mode 755.
7322663e35Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
7422663e35Smrgmkdir_umask=22
7522663e35Smrg
7622663e35Smrgbackupsuffix=
77786a6f21Smrgchgrpcmd=
78ba85709eSmrgchmodcmd=$chmodprog
791d54945dSmrgchowncmd=
80786a6f21Smrgmvcmd=$mvprog
811d54945dSmrgrmcmd="$rmprog -f"
82786a6f21Smrgstripcmd=
83786a6f21Smrg
841d54945dSmrgsrc=
851d54945dSmrgdst=
861d54945dSmrgdir_arg=
87786a6f21Smrgdst_arg=
88786a6f21Smrg
89786a6f21Smrgcopy_on_change=false
907322289dSmrgis_target_a_directory=possibly
911d54945dSmrg
92786a6f21Smrgusage="\
93786a6f21SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
941d54945dSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
951d54945dSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
961d54945dSmrg   or: $0 [OPTION]... -d DIRECTORIES...
971d54945dSmrg
981d54945dSmrgIn the 1st form, copy SRCFILE to DSTFILE.
991d54945dSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1001d54945dSmrgIn the 4th, create DIRECTORIES.
1011d54945dSmrg
1021d54945dSmrgOptions:
103786a6f21Smrg     --help     display this help and exit.
104786a6f21Smrg     --version  display version info and exit.
105786a6f21Smrg
106786a6f21Smrg  -c            (ignored)
10722663e35Smrg  -C            install only if different (preserve data modification time)
108786a6f21Smrg  -d            create directories instead of installing files.
109786a6f21Smrg  -g GROUP      $chgrpprog installed files to GROUP.
110786a6f21Smrg  -m MODE       $chmodprog installed files to MODE.
111786a6f21Smrg  -o USER       $chownprog installed files to USER.
11222663e35Smrg  -p            pass -p to $cpprog.
113786a6f21Smrg  -s            $stripprog installed files.
11422663e35Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
115786a6f21Smrg  -t DIRECTORY  install into DIRECTORY.
116786a6f21Smrg  -T            report an error if DSTFILE is a directory.
1171d54945dSmrg
1181d54945dSmrgEnvironment variables override the default commands:
119786a6f21Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
120786a6f21Smrg  RMPROG STRIPPROG
12122663e35Smrg
12222663e35SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
12322663e35Smrgit's up to you to specify -f if you want it.
12422663e35Smrg
12522663e35SmrgIf -S is not specified, no backups are attempted.
12622663e35Smrg
12722663e35SmrgEmail bug reports to bug-automake@gnu.org.
12822663e35SmrgAutomake home page: https://www.gnu.org/software/automake/
1291d54945dSmrg"
1301d54945dSmrg
131ba85709eSmrgwhile test $# -ne 0; do
1321d54945dSmrg  case $1 in
133786a6f21Smrg    -c) ;;
134786a6f21Smrg
135786a6f21Smrg    -C) copy_on_change=true;;
1361d54945dSmrg
137786a6f21Smrg    -d) dir_arg=true;;
1381d54945dSmrg
1391d54945dSmrg    -g) chgrpcmd="$chgrpprog $2"
1407322289dSmrg        shift;;
1411d54945dSmrg
1421d54945dSmrg    --help) echo "$usage"; exit $?;;
1431d54945dSmrg
144ba85709eSmrg    -m) mode=$2
1457322289dSmrg        case $mode in
1467322289dSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1477322289dSmrg            echo "$0: invalid mode: $mode" >&2
1487322289dSmrg            exit 1;;
1497322289dSmrg        esac
1507322289dSmrg        shift;;
1511d54945dSmrg
1521d54945dSmrg    -o) chowncmd="$chownprog $2"
1537322289dSmrg        shift;;
1541d54945dSmrg
15522663e35Smrg    -p) cpprog="$cpprog -p";;
15622663e35Smrg
157786a6f21Smrg    -s) stripcmd=$stripprog;;
1581d54945dSmrg
15922663e35Smrg    -S) backupsuffix="$2"
16022663e35Smrg        shift;;
16122663e35Smrg
1627322289dSmrg    -t)
1637322289dSmrg        is_target_a_directory=always
1647322289dSmrg        dst_arg=$2
1657322289dSmrg        # Protect names problematic for 'test' and other utilities.
1667322289dSmrg        case $dst_arg in
1677322289dSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1687322289dSmrg        esac
1697322289dSmrg        shift;;
1701d54945dSmrg
1717322289dSmrg    -T) is_target_a_directory=never;;
1721d54945dSmrg
1731d54945dSmrg    --version) echo "$0 $scriptversion"; exit $?;;
1741d54945dSmrg
1757322289dSmrg    --) shift
1767322289dSmrg        break;;
177ba85709eSmrg
1787322289dSmrg    -*) echo "$0: invalid option: $1" >&2
1797322289dSmrg        exit 1;;
180ba85709eSmrg
181ba85709eSmrg    *)  break;;
1821d54945dSmrg  esac
183786a6f21Smrg  shift
1841d54945dSmrgdone
1851d54945dSmrg
1867322289dSmrg# We allow the use of options -d and -T together, by making -d
1877322289dSmrg# take the precedence; this is for compatibility with GNU install.
1887322289dSmrg
1897322289dSmrgif test -n "$dir_arg"; then
1907322289dSmrg  if test -n "$dst_arg"; then
1917322289dSmrg    echo "$0: target directory not allowed when installing a directory." >&2
1927322289dSmrg    exit 1
1937322289dSmrg  fi
1947322289dSmrgfi
1957322289dSmrg
196786a6f21Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
197ba85709eSmrg  # When -d is used, all remaining arguments are directories to create.
198ba85709eSmrg  # When -t is used, the destination is already specified.
199ba85709eSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
200ba85709eSmrg  for arg
201ba85709eSmrg  do
202786a6f21Smrg    if test -n "$dst_arg"; then
203ba85709eSmrg      # $@ is not empty: it contains at least $arg.
204786a6f21Smrg      set fnord "$@" "$dst_arg"
205ba85709eSmrg      shift # fnord
206ba85709eSmrg    fi
207ba85709eSmrg    shift # arg
208786a6f21Smrg    dst_arg=$arg
2097322289dSmrg    # Protect names problematic for 'test' and other utilities.
210d769e936Smrg    case $dst_arg in
211d769e936Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
212d769e936Smrg    esac
213ba85709eSmrg  done
214ba85709eSmrgfi
215ba85709eSmrg
216ba85709eSmrgif test $# -eq 0; then
2171d54945dSmrg  if test -z "$dir_arg"; then
2181d54945dSmrg    echo "$0: no input file specified." >&2
2191d54945dSmrg    exit 1
2201d54945dSmrg  fi
2217322289dSmrg  # It's OK to call 'install-sh -d' without argument.
2221d54945dSmrg  # This can happen when creating conditional directories.
2231d54945dSmrg  exit 0
2241d54945dSmrgfi
2251d54945dSmrg
2267322289dSmrgif test -z "$dir_arg"; then
2277322289dSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
2287322289dSmrg    if test ! -d "$dst_arg"; then
2297322289dSmrg      echo "$0: $dst_arg: Is not a directory." >&2
2307322289dSmrg      exit 1
2317322289dSmrg    fi
2327322289dSmrg  fi
2337322289dSmrgfi
2347322289dSmrg
235ba85709eSmrgif test -z "$dir_arg"; then
236d769e936Smrg  do_exit='(exit $ret); exit $ret'
237d769e936Smrg  trap "ret=129; $do_exit" 1
238d769e936Smrg  trap "ret=130; $do_exit" 2
239d769e936Smrg  trap "ret=141; $do_exit" 13
240d769e936Smrg  trap "ret=143; $do_exit" 15
241ba85709eSmrg
242ba85709eSmrg  # Set umask so as not to create temps with too-generous modes.
243ba85709eSmrg  # However, 'strip' requires both read and write access to temps.
244ba85709eSmrg  case $mode in
245ba85709eSmrg    # Optimize common cases.
246ba85709eSmrg    *644) cp_umask=133;;
247ba85709eSmrg    *755) cp_umask=22;;
248ba85709eSmrg
249ba85709eSmrg    *[0-7])
250ba85709eSmrg      if test -z "$stripcmd"; then
2517322289dSmrg        u_plus_rw=
252ba85709eSmrg      else
2537322289dSmrg        u_plus_rw='% 200'
254ba85709eSmrg      fi
255ba85709eSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
256ba85709eSmrg    *)
257ba85709eSmrg      if test -z "$stripcmd"; then
2587322289dSmrg        u_plus_rw=
259ba85709eSmrg      else
2607322289dSmrg        u_plus_rw=,u+rw
261ba85709eSmrg      fi
262ba85709eSmrg      cp_umask=$mode$u_plus_rw;;
263ba85709eSmrg  esac
264ba85709eSmrgfi
265ba85709eSmrg
2661d54945dSmrgfor src
2671d54945dSmrgdo
2687322289dSmrg  # Protect names problematic for 'test' and other utilities.
2691d54945dSmrg  case $src in
270d769e936Smrg    -* | [=\(\)!]) src=./$src;;
2711d54945dSmrg  esac
2721d54945dSmrg
2731d54945dSmrg  if test -n "$dir_arg"; then
2741d54945dSmrg    dst=$src
275ba85709eSmrg    dstdir=$dst
276ba85709eSmrg    test -d "$dstdir"
277ba85709eSmrg    dstdir_status=$?
27822663e35Smrg    # Don't chown directories that already exist.
27922663e35Smrg    if test $dstdir_status = 0; then
28022663e35Smrg      chowncmd=""
28122663e35Smrg    fi
2821d54945dSmrg  else
283ba85709eSmrg
2841d54945dSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2851d54945dSmrg    # might cause directories to be created, which would be especially bad
2861d54945dSmrg    # if $src (and thus $dsttmp) contains '*'.
2871d54945dSmrg    if test ! -f "$src" && test ! -d "$src"; then
2881d54945dSmrg      echo "$0: $src does not exist." >&2
2891d54945dSmrg      exit 1
2901d54945dSmrg    fi
2911d54945dSmrg
292786a6f21Smrg    if test -z "$dst_arg"; then
2931d54945dSmrg      echo "$0: no destination specified." >&2
2941d54945dSmrg      exit 1
2951d54945dSmrg    fi
296786a6f21Smrg    dst=$dst_arg
2971d54945dSmrg
29822663e35Smrg    # If destination is a directory, append the input filename.
2991d54945dSmrg    if test -d "$dst"; then
3007322289dSmrg      if test "$is_target_a_directory" = never; then
3017322289dSmrg        echo "$0: $dst_arg: Is a directory" >&2
3027322289dSmrg        exit 1
3031d54945dSmrg      fi
304ba85709eSmrg      dstdir=$dst
30522663e35Smrg      dstbase=`basename "$src"`
30622663e35Smrg      case $dst in
30722663e35Smrg	*/) dst=$dst$dstbase;;
30822663e35Smrg	*)  dst=$dst/$dstbase;;
30922663e35Smrg      esac
310ba85709eSmrg      dstdir_status=0
311ba85709eSmrg    else
3127322289dSmrg      dstdir=`dirname "$dst"`
313ba85709eSmrg      test -d "$dstdir"
314ba85709eSmrg      dstdir_status=$?
3151d54945dSmrg    fi
3161d54945dSmrg  fi
3171d54945dSmrg
31822663e35Smrg  case $dstdir in
31922663e35Smrg    */) dstdirslash=$dstdir;;
32022663e35Smrg    *)  dstdirslash=$dstdir/;;
32122663e35Smrg  esac
32222663e35Smrg
323ba85709eSmrg  obsolete_mkdir_used=false
324ba85709eSmrg
325ba85709eSmrg  if test $dstdir_status != 0; then
326ba85709eSmrg    case $posix_mkdir in
327ba85709eSmrg      '')
3287322289dSmrg        # With -d, create the new directory with the user-specified mode.
3297322289dSmrg        # Otherwise, rely on $mkdir_umask.
3307322289dSmrg        if test -n "$dir_arg"; then
3317322289dSmrg          mkdir_mode=-m$mode
3327322289dSmrg        else
3337322289dSmrg          mkdir_mode=
3347322289dSmrg        fi
3357322289dSmrg
3367322289dSmrg        posix_mkdir=false
33722663e35Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
33822663e35Smrg	# here however when possible just to lower collision chance.
33922663e35Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34022663e35Smrg
34122663e35Smrg	trap '
34222663e35Smrg	  ret=$?
34322663e35Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
34422663e35Smrg	  exit $ret
34522663e35Smrg	' 0
34622663e35Smrg
34722663e35Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
34822663e35Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
34922663e35Smrg	# directory is successfully created first before we actually test
35022663e35Smrg	# 'mkdir -p'.
35122663e35Smrg	if (umask $mkdir_umask &&
35222663e35Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
35322663e35Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
35422663e35Smrg	then
35522663e35Smrg	  if test -z "$dir_arg" || {
35622663e35Smrg	       # Check for POSIX incompatibilities with -m.
35722663e35Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35822663e35Smrg	       # other-writable bit of parent directory when it shouldn't.
35922663e35Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
36022663e35Smrg	       test_tmpdir="$tmpdir/a"
36122663e35Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
36222663e35Smrg	       case $ls_ld_tmpdir in
36322663e35Smrg		 d????-?r-*) different_mode=700;;
36422663e35Smrg		 d????-?--*) different_mode=755;;
36522663e35Smrg		 *) false;;
36622663e35Smrg	       esac &&
36722663e35Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
36822663e35Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
36922663e35Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
37022663e35Smrg	       }
37122663e35Smrg	     }
37222663e35Smrg	  then posix_mkdir=:
37322663e35Smrg	  fi
37422663e35Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
37522663e35Smrg	else
37622663e35Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
37722663e35Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
37822663e35Smrg	fi
37922663e35Smrg	trap '' 0;;
380ba85709eSmrg    esac
3811d54945dSmrg
382ba85709eSmrg    if
383ba85709eSmrg      $posix_mkdir && (
3847322289dSmrg        umask $mkdir_umask &&
3857322289dSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
386ba85709eSmrg      )
387ba85709eSmrg    then :
388ba85709eSmrg    else
3891d54945dSmrg
39022663e35Smrg      # mkdir does not conform to POSIX,
391ba85709eSmrg      # or it failed possibly due to a race condition.  Create the
392ba85709eSmrg      # directory the slow way, step by step, checking for races as we go.
393ba85709eSmrg
394ba85709eSmrg      case $dstdir in
3957322289dSmrg        /*) prefix='/';;
3967322289dSmrg        [-=\(\)!]*) prefix='./';;
3977322289dSmrg        *)  prefix='';;
398ba85709eSmrg      esac
399ba85709eSmrg
400ba85709eSmrg      oIFS=$IFS
401ba85709eSmrg      IFS=/
4027322289dSmrg      set -f
403ba85709eSmrg      set fnord $dstdir
4041d54945dSmrg      shift
4057322289dSmrg      set +f
406ba85709eSmrg      IFS=$oIFS
407ba85709eSmrg
408ba85709eSmrg      prefixes=
409ba85709eSmrg
410ba85709eSmrg      for d
411ba85709eSmrg      do
4127322289dSmrg        test X"$d" = X && continue
4137322289dSmrg
4147322289dSmrg        prefix=$prefix$d
4157322289dSmrg        if test -d "$prefix"; then
4167322289dSmrg          prefixes=
4177322289dSmrg        else
4187322289dSmrg          if $posix_mkdir; then
41922663e35Smrg            (umask $mkdir_umask &&
4207322289dSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4217322289dSmrg            # Don't fail if two instances are running concurrently.
4227322289dSmrg            test -d "$prefix" || exit 1
4237322289dSmrg          else
4247322289dSmrg            case $prefix in
4257322289dSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4267322289dSmrg              *) qprefix=$prefix;;
4277322289dSmrg            esac
4287322289dSmrg            prefixes="$prefixes '$qprefix'"
4297322289dSmrg          fi
4307322289dSmrg        fi
4317322289dSmrg        prefix=$prefix/
432ba85709eSmrg      done
433ba85709eSmrg
434ba85709eSmrg      if test -n "$prefixes"; then
4357322289dSmrg        # Don't fail if two instances are running concurrently.
4367322289dSmrg        (umask $mkdir_umask &&
4377322289dSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
4387322289dSmrg          test -d "$dstdir" || exit 1
4397322289dSmrg        obsolete_mkdir_used=true
4401d54945dSmrg      fi
441ba85709eSmrg    fi
4421d54945dSmrg  fi
4431d54945dSmrg
4441d54945dSmrg  if test -n "$dir_arg"; then
445ba85709eSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
446ba85709eSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
447ba85709eSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
448ba85709eSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4491d54945dSmrg  else
4501d54945dSmrg
4511d54945dSmrg    # Make a couple of temp file names in the proper directory.
45222663e35Smrg    dsttmp=${dstdirslash}_inst.$$_
45322663e35Smrg    rmtmp=${dstdirslash}_rm.$$_
4541d54945dSmrg
4551d54945dSmrg    # Trap to clean up those temp files at exit.
4561d54945dSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4571d54945dSmrg
4581d54945dSmrg    # Copy the file name to the temp name.
45922663e35Smrg    (umask $cp_umask &&
46022663e35Smrg     { test -z "$stripcmd" || {
46122663e35Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
46222663e35Smrg	 # which would cause strip to fail.
46322663e35Smrg	 if test -z "$doit"; then
46422663e35Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
46522663e35Smrg	 else
46622663e35Smrg	   $doit touch "$dsttmp"
46722663e35Smrg	 fi
46822663e35Smrg       }
46922663e35Smrg     } &&
47022663e35Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
4711d54945dSmrg
4721d54945dSmrg    # and set any options; do chmod last to preserve setuid bits.
4731d54945dSmrg    #
4741d54945dSmrg    # If any of these fail, we abort the whole thing.  If we want to
4751d54945dSmrg    # ignore errors from any of these, just make sure not to ignore
4761d54945dSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4771d54945dSmrg    #
478786a6f21Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
479786a6f21Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
480786a6f21Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
481786a6f21Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
482786a6f21Smrg
483786a6f21Smrg    # If -C, don't bother to copy if it wouldn't change the file.
484786a6f21Smrg    if $copy_on_change &&
4857322289dSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4867322289dSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
4877322289dSmrg       set -f &&
488786a6f21Smrg       set X $old && old=:$2:$4:$5:$6 &&
489786a6f21Smrg       set X $new && new=:$2:$4:$5:$6 &&
4907322289dSmrg       set +f &&
491786a6f21Smrg       test "$old" = "$new" &&
492786a6f21Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
493786a6f21Smrg    then
494786a6f21Smrg      rm -f "$dsttmp"
495786a6f21Smrg    else
49622663e35Smrg      # If $backupsuffix is set, and the file being installed
49722663e35Smrg      # already exists, attempt a backup.  Don't worry if it fails,
49822663e35Smrg      # e.g., if mv doesn't support -f.
49922663e35Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
50022663e35Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
50122663e35Smrg      fi
50222663e35Smrg
503786a6f21Smrg      # Rename the file to the real destination.
504786a6f21Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
505786a6f21Smrg
506786a6f21Smrg      # The rename failed, perhaps because mv can't rename something else
507786a6f21Smrg      # to itself, or perhaps because mv is so ancient that it does not
508786a6f21Smrg      # support -f.
509786a6f21Smrg      {
5107322289dSmrg        # Now remove or move aside any old file at destination location.
5117322289dSmrg        # We try this two ways since rm can't unlink itself on some
5127322289dSmrg        # systems and the destination file might be busy for other
5137322289dSmrg        # reasons.  In this case, the final cleanup might fail but the new
5147322289dSmrg        # file should still install successfully.
5157322289dSmrg        {
5167322289dSmrg          test ! -f "$dst" ||
51722663e35Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
5187322289dSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
51922663e35Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
5207322289dSmrg          } ||
5217322289dSmrg          { echo "$0: cannot unlink or rename $dst" >&2
5227322289dSmrg            (exit 1); exit 1
5237322289dSmrg          }
5247322289dSmrg        } &&
5257322289dSmrg
5267322289dSmrg        # Now rename the file to the real destination.
5277322289dSmrg        $doit $mvcmd "$dsttmp" "$dst"
528786a6f21Smrg      }
529786a6f21Smrg    fi || exit 1
5301d54945dSmrg
531ba85709eSmrg    trap '' 0
532ba85709eSmrg  fi
533ba85709eSmrgdone
5341d54945dSmrg
5351d54945dSmrg# Local variables:
53622663e35Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
5371d54945dSmrg# time-stamp-start: "scriptversion="
5381d54945dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
53922663e35Smrg# time-stamp-time-zone: "UTC0"
540ec713c28Smrg# time-stamp-end: "; # UTC"
5411d54945dSmrg# End:
542