120d725fbSmrg#!/bin/sh
220d725fbSmrg# install - install a program, script, or datafile
320d725fbSmrg
4fe605390Smrgscriptversion=2020-11-14.01; # UTC
520d725fbSmrg
620d725fbSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
720d725fbSmrg# later released in X11R6 (xc/config/util/install.sh) with the
820d725fbSmrg# following copyright and license.
920d725fbSmrg#
1020d725fbSmrg# Copyright (C) 1994 X Consortium
1120d725fbSmrg#
1220d725fbSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1320d725fbSmrg# of this software and associated documentation files (the "Software"), to
1420d725fbSmrg# deal in the Software without restriction, including without limitation the
1520d725fbSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1620d725fbSmrg# sell copies of the Software, and to permit persons to whom the Software is
1720d725fbSmrg# furnished to do so, subject to the following conditions:
1820d725fbSmrg#
1920d725fbSmrg# The above copyright notice and this permission notice shall be included in
2020d725fbSmrg# all copies or substantial portions of the Software.
2120d725fbSmrg#
2220d725fbSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2320d725fbSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2420d725fbSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2520d725fbSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2620d725fbSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2720d725fbSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2820d725fbSmrg#
2920d725fbSmrg# Except as contained in this notice, the name of the X Consortium shall not
3020d725fbSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
3120d725fbSmrg# ings in this Software without prior written authorization from the X Consor-
3220d725fbSmrg# tium.
3320d725fbSmrg#
3420d725fbSmrg#
3520d725fbSmrg# FSF changes to this file are in the public domain.
3620d725fbSmrg#
3720d725fbSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38fe605390Smrg# 'make' implicit rules from creating a file called install from it
3920d725fbSmrg# when there is no Makefile.
4020d725fbSmrg#
4120d725fbSmrg# This script is compatible with the BSD install script, but was written
4263fbae1dSmrg# from scratch.
4363fbae1dSmrg
44fe605390Smrgtab='	'
4563fbae1dSmrgnl='
4663fbae1dSmrg'
47fe605390SmrgIFS=" $tab$nl"
4820d725fbSmrg
49fe605390Smrg# Set DOITPROG to "echo" to test this script.
5020d725fbSmrg
5163fbae1dSmrgdoit=${DOITPROG-}
52fe605390Smrgdoit_exec=${doit:-exec}
5320d725fbSmrg
5463fbae1dSmrg# Put in absolute file names if you don't have them in your path;
5563fbae1dSmrg# or use environment vars.
5663fbae1dSmrg
5763fbae1dSmrgchgrpprog=${CHGRPPROG-chgrp}
5863fbae1dSmrgchmodprog=${CHMODPROG-chmod}
5963fbae1dSmrgchownprog=${CHOWNPROG-chown}
6063fbae1dSmrgcmpprog=${CMPPROG-cmp}
6163fbae1dSmrgcpprog=${CPPROG-cp}
6263fbae1dSmrgmkdirprog=${MKDIRPROG-mkdir}
6363fbae1dSmrgmvprog=${MVPROG-mv}
6463fbae1dSmrgrmprog=${RMPROG-rm}
6563fbae1dSmrgstripprog=${STRIPPROG-strip}
6663fbae1dSmrg
6763fbae1dSmrgposix_mkdir=
6863fbae1dSmrg
6963fbae1dSmrg# Desired mode of installed file.
7063fbae1dSmrgmode=0755
7120d725fbSmrg
72fe605390Smrg# Create dirs (including intermediate dirs) using mode 755.
73fe605390Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
74fe605390Smrgmkdir_umask=22
75fe605390Smrg
76fe605390Smrgbackupsuffix=
7720d725fbSmrgchgrpcmd=
7863fbae1dSmrgchmodcmd=$chmodprog
7963fbae1dSmrgchowncmd=
8063fbae1dSmrgmvcmd=$mvprog
8120d725fbSmrgrmcmd="$rmprog -f"
8263fbae1dSmrgstripcmd=
8363fbae1dSmrg
8420d725fbSmrgsrc=
8520d725fbSmrgdst=
8620d725fbSmrgdir_arg=
8763fbae1dSmrgdst_arg=
8863fbae1dSmrg
8963fbae1dSmrgcopy_on_change=false
90fe605390Smrgis_target_a_directory=possibly
9120d725fbSmrg
9263fbae1dSmrgusage="\
9363fbae1dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
9420d725fbSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9520d725fbSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9620d725fbSmrg   or: $0 [OPTION]... -d DIRECTORIES...
9720d725fbSmrg
9820d725fbSmrgIn the 1st form, copy SRCFILE to DSTFILE.
9920d725fbSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
10020d725fbSmrgIn the 4th, create DIRECTORIES.
10120d725fbSmrg
10220d725fbSmrgOptions:
10363fbae1dSmrg     --help     display this help and exit.
10463fbae1dSmrg     --version  display version info and exit.
10563fbae1dSmrg
10663fbae1dSmrg  -c            (ignored)
107fe605390Smrg  -C            install only if different (preserve data modification time)
10863fbae1dSmrg  -d            create directories instead of installing files.
10963fbae1dSmrg  -g GROUP      $chgrpprog installed files to GROUP.
11063fbae1dSmrg  -m MODE       $chmodprog installed files to MODE.
11163fbae1dSmrg  -o USER       $chownprog installed files to USER.
112fe605390Smrg  -p            pass -p to $cpprog.
11363fbae1dSmrg  -s            $stripprog installed files.
114fe605390Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
11563fbae1dSmrg  -t DIRECTORY  install into DIRECTORY.
11663fbae1dSmrg  -T            report an error if DSTFILE is a directory.
11720d725fbSmrg
11820d725fbSmrgEnvironment variables override the default commands:
11963fbae1dSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
12063fbae1dSmrg  RMPROG STRIPPROG
121fe605390Smrg
122fe605390SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
123fe605390Smrgit's up to you to specify -f if you want it.
124fe605390Smrg
125fe605390SmrgIf -S is not specified, no backups are attempted.
126fe605390Smrg
127fe605390SmrgEmail bug reports to bug-automake@gnu.org.
128fe605390SmrgAutomake home page: https://www.gnu.org/software/automake/
12920d725fbSmrg"
13020d725fbSmrg
13163fbae1dSmrgwhile test $# -ne 0; do
13220d725fbSmrg  case $1 in
13363fbae1dSmrg    -c) ;;
13463fbae1dSmrg
13563fbae1dSmrg    -C) copy_on_change=true;;
13620d725fbSmrg
13763fbae1dSmrg    -d) dir_arg=true;;
13820d725fbSmrg
13920d725fbSmrg    -g) chgrpcmd="$chgrpprog $2"
140fe605390Smrg        shift;;
14120d725fbSmrg
14220d725fbSmrg    --help) echo "$usage"; exit $?;;
14320d725fbSmrg
14463fbae1dSmrg    -m) mode=$2
145fe605390Smrg        case $mode in
146fe605390Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
147fe605390Smrg            echo "$0: invalid mode: $mode" >&2
148fe605390Smrg            exit 1;;
149fe605390Smrg        esac
150fe605390Smrg        shift;;
15120d725fbSmrg
15220d725fbSmrg    -o) chowncmd="$chownprog $2"
153fe605390Smrg        shift;;
154fe605390Smrg
155fe605390Smrg    -p) cpprog="$cpprog -p";;
15620d725fbSmrg
15763fbae1dSmrg    -s) stripcmd=$stripprog;;
15820d725fbSmrg
159fe605390Smrg    -S) backupsuffix="$2"
160fe605390Smrg        shift;;
161fe605390Smrg
162fe605390Smrg    -t)
163fe605390Smrg        is_target_a_directory=always
164fe605390Smrg        dst_arg=$2
165fe605390Smrg        # Protect names problematic for 'test' and other utilities.
166fe605390Smrg        case $dst_arg in
167fe605390Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
168fe605390Smrg        esac
169fe605390Smrg        shift;;
17020d725fbSmrg
171fe605390Smrg    -T) is_target_a_directory=never;;
17220d725fbSmrg
17320d725fbSmrg    --version) echo "$0 $scriptversion"; exit $?;;
17420d725fbSmrg
175fe605390Smrg    --) shift
176fe605390Smrg        break;;
17763fbae1dSmrg
178fe605390Smrg    -*) echo "$0: invalid option: $1" >&2
179fe605390Smrg        exit 1;;
18063fbae1dSmrg
18163fbae1dSmrg    *)  break;;
18220d725fbSmrg  esac
18363fbae1dSmrg  shift
18420d725fbSmrgdone
18520d725fbSmrg
186fe605390Smrg# We allow the use of options -d and -T together, by making -d
187fe605390Smrg# take the precedence; this is for compatibility with GNU install.
188fe605390Smrg
189fe605390Smrgif test -n "$dir_arg"; then
190fe605390Smrg  if test -n "$dst_arg"; then
191fe605390Smrg    echo "$0: target directory not allowed when installing a directory." >&2
192fe605390Smrg    exit 1
193fe605390Smrg  fi
194fe605390Smrgfi
195fe605390Smrg
19663fbae1dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
19763fbae1dSmrg  # When -d is used, all remaining arguments are directories to create.
19863fbae1dSmrg  # When -t is used, the destination is already specified.
19963fbae1dSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
20063fbae1dSmrg  for arg
20163fbae1dSmrg  do
20263fbae1dSmrg    if test -n "$dst_arg"; then
20363fbae1dSmrg      # $@ is not empty: it contains at least $arg.
20463fbae1dSmrg      set fnord "$@" "$dst_arg"
20563fbae1dSmrg      shift # fnord
20663fbae1dSmrg    fi
20763fbae1dSmrg    shift # arg
20863fbae1dSmrg    dst_arg=$arg
209fe605390Smrg    # Protect names problematic for 'test' and other utilities.
210fe605390Smrg    case $dst_arg in
211fe605390Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
212fe605390Smrg    esac
21363fbae1dSmrg  done
21463fbae1dSmrgfi
21563fbae1dSmrg
21663fbae1dSmrgif test $# -eq 0; then
21720d725fbSmrg  if test -z "$dir_arg"; then
21820d725fbSmrg    echo "$0: no input file specified." >&2
21920d725fbSmrg    exit 1
22020d725fbSmrg  fi
221fe605390Smrg  # It's OK to call 'install-sh -d' without argument.
22220d725fbSmrg  # This can happen when creating conditional directories.
22320d725fbSmrg  exit 0
22420d725fbSmrgfi
22520d725fbSmrg
22663fbae1dSmrgif test -z "$dir_arg"; then
227fe605390Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
228fe605390Smrg    if test ! -d "$dst_arg"; then
229fe605390Smrg      echo "$0: $dst_arg: Is not a directory." >&2
230fe605390Smrg      exit 1
231fe605390Smrg    fi
232fe605390Smrg  fi
233fe605390Smrgfi
234fe605390Smrg
235fe605390Smrgif test -z "$dir_arg"; then
236fe605390Smrg  do_exit='(exit $ret); exit $ret'
237fe605390Smrg  trap "ret=129; $do_exit" 1
238fe605390Smrg  trap "ret=130; $do_exit" 2
239fe605390Smrg  trap "ret=141; $do_exit" 13
240fe605390Smrg  trap "ret=143; $do_exit" 15
24163fbae1dSmrg
24263fbae1dSmrg  # Set umask so as not to create temps with too-generous modes.
24363fbae1dSmrg  # However, 'strip' requires both read and write access to temps.
24463fbae1dSmrg  case $mode in
24563fbae1dSmrg    # Optimize common cases.
24663fbae1dSmrg    *644) cp_umask=133;;
24763fbae1dSmrg    *755) cp_umask=22;;
24863fbae1dSmrg
24963fbae1dSmrg    *[0-7])
25063fbae1dSmrg      if test -z "$stripcmd"; then
251fe605390Smrg        u_plus_rw=
25263fbae1dSmrg      else
253fe605390Smrg        u_plus_rw='% 200'
25463fbae1dSmrg      fi
25563fbae1dSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
25663fbae1dSmrg    *)
25763fbae1dSmrg      if test -z "$stripcmd"; then
258fe605390Smrg        u_plus_rw=
25963fbae1dSmrg      else
260fe605390Smrg        u_plus_rw=,u+rw
26163fbae1dSmrg      fi
26263fbae1dSmrg      cp_umask=$mode$u_plus_rw;;
26363fbae1dSmrg  esac
26463fbae1dSmrgfi
26563fbae1dSmrg
26620d725fbSmrgfor src
26720d725fbSmrgdo
268fe605390Smrg  # Protect names problematic for 'test' and other utilities.
26920d725fbSmrg  case $src in
270fe605390Smrg    -* | [=\(\)!]) src=./$src;;
27120d725fbSmrg  esac
27220d725fbSmrg
27320d725fbSmrg  if test -n "$dir_arg"; then
27420d725fbSmrg    dst=$src
27563fbae1dSmrg    dstdir=$dst
27663fbae1dSmrg    test -d "$dstdir"
27763fbae1dSmrg    dstdir_status=$?
278fe605390Smrg    # Don't chown directories that already exist.
279fe605390Smrg    if test $dstdir_status = 0; then
280fe605390Smrg      chowncmd=""
281fe605390Smrg    fi
28220d725fbSmrg  else
28363fbae1dSmrg
28420d725fbSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
28520d725fbSmrg    # might cause directories to be created, which would be especially bad
28620d725fbSmrg    # if $src (and thus $dsttmp) contains '*'.
28720d725fbSmrg    if test ! -f "$src" && test ! -d "$src"; then
28820d725fbSmrg      echo "$0: $src does not exist." >&2
28920d725fbSmrg      exit 1
29020d725fbSmrg    fi
29120d725fbSmrg
29263fbae1dSmrg    if test -z "$dst_arg"; then
29320d725fbSmrg      echo "$0: no destination specified." >&2
29420d725fbSmrg      exit 1
29520d725fbSmrg    fi
29663fbae1dSmrg    dst=$dst_arg
29720d725fbSmrg
298fe605390Smrg    # If destination is a directory, append the input filename.
29920d725fbSmrg    if test -d "$dst"; then
300fe605390Smrg      if test "$is_target_a_directory" = never; then
301fe605390Smrg        echo "$0: $dst_arg: Is a directory" >&2
302fe605390Smrg        exit 1
30320d725fbSmrg      fi
30463fbae1dSmrg      dstdir=$dst
305fe605390Smrg      dstbase=`basename "$src"`
306fe605390Smrg      case $dst in
307fe605390Smrg	*/) dst=$dst$dstbase;;
308fe605390Smrg	*)  dst=$dst/$dstbase;;
309fe605390Smrg      esac
31063fbae1dSmrg      dstdir_status=0
31163fbae1dSmrg    else
312fe605390Smrg      dstdir=`dirname "$dst"`
31363fbae1dSmrg      test -d "$dstdir"
31463fbae1dSmrg      dstdir_status=$?
31520d725fbSmrg    fi
31620d725fbSmrg  fi
31720d725fbSmrg
318fe605390Smrg  case $dstdir in
319fe605390Smrg    */) dstdirslash=$dstdir;;
320fe605390Smrg    *)  dstdirslash=$dstdir/;;
321fe605390Smrg  esac
322fe605390Smrg
32363fbae1dSmrg  obsolete_mkdir_used=false
32463fbae1dSmrg
32563fbae1dSmrg  if test $dstdir_status != 0; then
32663fbae1dSmrg    case $posix_mkdir in
32763fbae1dSmrg      '')
328fe605390Smrg        # With -d, create the new directory with the user-specified mode.
329fe605390Smrg        # Otherwise, rely on $mkdir_umask.
330fe605390Smrg        if test -n "$dir_arg"; then
331fe605390Smrg          mkdir_mode=-m$mode
332fe605390Smrg        else
333fe605390Smrg          mkdir_mode=
334fe605390Smrg        fi
335fe605390Smrg
336fe605390Smrg        posix_mkdir=false
337fe605390Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
338fe605390Smrg	# here however when possible just to lower collision chance.
339fe605390Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
340fe605390Smrg
341fe605390Smrg	trap '
342fe605390Smrg	  ret=$?
343fe605390Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
344fe605390Smrg	  exit $ret
345fe605390Smrg	' 0
346fe605390Smrg
347fe605390Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
348fe605390Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
349fe605390Smrg	# directory is successfully created first before we actually test
350fe605390Smrg	# 'mkdir -p'.
351fe605390Smrg	if (umask $mkdir_umask &&
352fe605390Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
353fe605390Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
354fe605390Smrg	then
355fe605390Smrg	  if test -z "$dir_arg" || {
356fe605390Smrg	       # Check for POSIX incompatibilities with -m.
357fe605390Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
358fe605390Smrg	       # other-writable bit of parent directory when it shouldn't.
359fe605390Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
360fe605390Smrg	       test_tmpdir="$tmpdir/a"
361fe605390Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
362fe605390Smrg	       case $ls_ld_tmpdir in
363fe605390Smrg		 d????-?r-*) different_mode=700;;
364fe605390Smrg		 d????-?--*) different_mode=755;;
365fe605390Smrg		 *) false;;
366fe605390Smrg	       esac &&
367fe605390Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
368fe605390Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
369fe605390Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
370fe605390Smrg	       }
371fe605390Smrg	     }
372fe605390Smrg	  then posix_mkdir=:
373fe605390Smrg	  fi
374fe605390Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
37563fbae1dSmrg	else
376fe605390Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
377fe605390Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
37863fbae1dSmrg	fi
379fe605390Smrg	trap '' 0;;
38063fbae1dSmrg    esac
38120d725fbSmrg
38263fbae1dSmrg    if
38363fbae1dSmrg      $posix_mkdir && (
384fe605390Smrg        umask $mkdir_umask &&
385fe605390Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
38663fbae1dSmrg      )
38763fbae1dSmrg    then :
38863fbae1dSmrg    else
38920d725fbSmrg
390fe605390Smrg      # mkdir does not conform to POSIX,
39163fbae1dSmrg      # or it failed possibly due to a race condition.  Create the
39263fbae1dSmrg      # directory the slow way, step by step, checking for races as we go.
39320d725fbSmrg
39463fbae1dSmrg      case $dstdir in
395fe605390Smrg        /*) prefix='/';;
396fe605390Smrg        [-=\(\)!]*) prefix='./';;
397fe605390Smrg        *)  prefix='';;
39863fbae1dSmrg      esac
39920d725fbSmrg
40063fbae1dSmrg      oIFS=$IFS
40163fbae1dSmrg      IFS=/
402fe605390Smrg      set -f
40363fbae1dSmrg      set fnord $dstdir
40420d725fbSmrg      shift
405fe605390Smrg      set +f
40663fbae1dSmrg      IFS=$oIFS
40763fbae1dSmrg
40863fbae1dSmrg      prefixes=
40963fbae1dSmrg
41063fbae1dSmrg      for d
41163fbae1dSmrg      do
412fe605390Smrg        test X"$d" = X && continue
413fe605390Smrg
414fe605390Smrg        prefix=$prefix$d
415fe605390Smrg        if test -d "$prefix"; then
416fe605390Smrg          prefixes=
417fe605390Smrg        else
418fe605390Smrg          if $posix_mkdir; then
419fe605390Smrg            (umask $mkdir_umask &&
420fe605390Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
421fe605390Smrg            # Don't fail if two instances are running concurrently.
422fe605390Smrg            test -d "$prefix" || exit 1
423fe605390Smrg          else
424fe605390Smrg            case $prefix in
425fe605390Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
426fe605390Smrg              *) qprefix=$prefix;;
427fe605390Smrg            esac
428fe605390Smrg            prefixes="$prefixes '$qprefix'"
429fe605390Smrg          fi
430fe605390Smrg        fi
431fe605390Smrg        prefix=$prefix/
43263fbae1dSmrg      done
43363fbae1dSmrg
43463fbae1dSmrg      if test -n "$prefixes"; then
435fe605390Smrg        # Don't fail if two instances are running concurrently.
436fe605390Smrg        (umask $mkdir_umask &&
437fe605390Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
438fe605390Smrg          test -d "$dstdir" || exit 1
439fe605390Smrg        obsolete_mkdir_used=true
44020d725fbSmrg      fi
44163fbae1dSmrg    fi
44220d725fbSmrg  fi
44320d725fbSmrg
44420d725fbSmrg  if test -n "$dir_arg"; then
44563fbae1dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
44663fbae1dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
44763fbae1dSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
44863fbae1dSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
44920d725fbSmrg  else
45020d725fbSmrg
45120d725fbSmrg    # Make a couple of temp file names in the proper directory.
452fe605390Smrg    dsttmp=${dstdirslash}_inst.$$_
453fe605390Smrg    rmtmp=${dstdirslash}_rm.$$_
45420d725fbSmrg
45520d725fbSmrg    # Trap to clean up those temp files at exit.
45620d725fbSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45720d725fbSmrg
45820d725fbSmrg    # Copy the file name to the temp name.
459fe605390Smrg    (umask $cp_umask &&
460fe605390Smrg     { test -z "$stripcmd" || {
461fe605390Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
462fe605390Smrg	 # which would cause strip to fail.
463fe605390Smrg	 if test -z "$doit"; then
464fe605390Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
465fe605390Smrg	 else
466fe605390Smrg	   $doit touch "$dsttmp"
467fe605390Smrg	 fi
468fe605390Smrg       }
469fe605390Smrg     } &&
470fe605390Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
47120d725fbSmrg
47220d725fbSmrg    # and set any options; do chmod last to preserve setuid bits.
47320d725fbSmrg    #
47420d725fbSmrg    # If any of these fail, we abort the whole thing.  If we want to
47520d725fbSmrg    # ignore errors from any of these, just make sure not to ignore
47620d725fbSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
47720d725fbSmrg    #
47863fbae1dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
47963fbae1dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
48063fbae1dSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
48163fbae1dSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
48263fbae1dSmrg
48363fbae1dSmrg    # If -C, don't bother to copy if it wouldn't change the file.
48463fbae1dSmrg    if $copy_on_change &&
485fe605390Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
486fe605390Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
487fe605390Smrg       set -f &&
48863fbae1dSmrg       set X $old && old=:$2:$4:$5:$6 &&
48963fbae1dSmrg       set X $new && new=:$2:$4:$5:$6 &&
490fe605390Smrg       set +f &&
49163fbae1dSmrg       test "$old" = "$new" &&
49263fbae1dSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
49363fbae1dSmrg    then
49463fbae1dSmrg      rm -f "$dsttmp"
49563fbae1dSmrg    else
496fe605390Smrg      # If $backupsuffix is set, and the file being installed
497fe605390Smrg      # already exists, attempt a backup.  Don't worry if it fails,
498fe605390Smrg      # e.g., if mv doesn't support -f.
499fe605390Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
500fe605390Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
501fe605390Smrg      fi
502fe605390Smrg
50363fbae1dSmrg      # Rename the file to the real destination.
50463fbae1dSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
50563fbae1dSmrg
50663fbae1dSmrg      # The rename failed, perhaps because mv can't rename something else
50763fbae1dSmrg      # to itself, or perhaps because mv is so ancient that it does not
50863fbae1dSmrg      # support -f.
50963fbae1dSmrg      {
510fe605390Smrg        # Now remove or move aside any old file at destination location.
511fe605390Smrg        # We try this two ways since rm can't unlink itself on some
512fe605390Smrg        # systems and the destination file might be busy for other
513fe605390Smrg        # reasons.  In this case, the final cleanup might fail but the new
514fe605390Smrg        # file should still install successfully.
515fe605390Smrg        {
516fe605390Smrg          test ! -f "$dst" ||
517fe605390Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
518fe605390Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
519fe605390Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
520fe605390Smrg          } ||
521fe605390Smrg          { echo "$0: cannot unlink or rename $dst" >&2
522fe605390Smrg            (exit 1); exit 1
523fe605390Smrg          }
524fe605390Smrg        } &&
525fe605390Smrg
526fe605390Smrg        # Now rename the file to the real destination.
527fe605390Smrg        $doit $mvcmd "$dsttmp" "$dst"
52863fbae1dSmrg      }
52963fbae1dSmrg    fi || exit 1
53063fbae1dSmrg
53163fbae1dSmrg    trap '' 0
53263fbae1dSmrg  fi
53320d725fbSmrgdone
53420d725fbSmrg
53520d725fbSmrg# Local variables:
536fe605390Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
53720d725fbSmrg# time-stamp-start: "scriptversion="
53820d725fbSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
539fe605390Smrg# time-stamp-time-zone: "UTC0"
54063fbae1dSmrg# time-stamp-end: "; # UTC"
54120d725fbSmrg# End:
542