1335e815aSmrg#!/bin/sh
2335e815aSmrg# install - install a program, script, or datafile
3f4959950Smrg
40cfee914Smrgscriptversion=2020-11-14.01; # UTC
5f4959950Smrg
6335e815aSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7335e815aSmrg# later released in X11R6 (xc/config/util/install.sh) with the
8335e815aSmrg# following copyright and license.
9335e815aSmrg#
10335e815aSmrg# Copyright (C) 1994 X Consortium
11335e815aSmrg#
12335e815aSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13335e815aSmrg# of this software and associated documentation files (the "Software"), to
14335e815aSmrg# deal in the Software without restriction, including without limitation the
15335e815aSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16335e815aSmrg# sell copies of the Software, and to permit persons to whom the Software is
17335e815aSmrg# furnished to do so, subject to the following conditions:
18335e815aSmrg#
19335e815aSmrg# The above copyright notice and this permission notice shall be included in
20335e815aSmrg# all copies or substantial portions of the Software.
21335e815aSmrg#
22335e815aSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23335e815aSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24335e815aSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25335e815aSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26335e815aSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27335e815aSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28335e815aSmrg#
29335e815aSmrg# Except as contained in this notice, the name of the X Consortium shall not
30335e815aSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
31335e815aSmrg# ings in this Software without prior written authorization from the X Consor-
32335e815aSmrg# tium.
33335e815aSmrg#
34335e815aSmrg#
35335e815aSmrg# FSF changes to this file are in the public domain.
36335e815aSmrg#
37335e815aSmrg# Calling this script install-sh is preferred over install.sh, to prevent
380cfee914Smrg# 'make' implicit rules from creating a file called install from it
39335e815aSmrg# when there is no Makefile.
40335e815aSmrg#
41335e815aSmrg# This script is compatible with the BSD install script, but was written
42f4959950Smrg# from scratch.
43335e815aSmrg
440cfee914Smrgtab='	'
45f4959950Smrgnl='
46f4959950Smrg'
470cfee914SmrgIFS=" $tab$nl"
48335e815aSmrg
490cfee914Smrg# Set DOITPROG to "echo" to test this script.
50335e815aSmrg
51f4959950Smrgdoit=${DOITPROG-}
520cfee914Smrgdoit_exec=${doit:-exec}
53335e815aSmrg
54f4959950Smrg# Put in absolute file names if you don't have them in your path;
55f4959950Smrg# or use environment vars.
56f4959950Smrg
57f4959950Smrgchgrpprog=${CHGRPPROG-chgrp}
58f4959950Smrgchmodprog=${CHMODPROG-chmod}
59f4959950Smrgchownprog=${CHOWNPROG-chown}
60f4959950Smrgcmpprog=${CMPPROG-cmp}
61f4959950Smrgcpprog=${CPPROG-cp}
62f4959950Smrgmkdirprog=${MKDIRPROG-mkdir}
63f4959950Smrgmvprog=${MVPROG-mv}
64f4959950Smrgrmprog=${RMPROG-rm}
65f4959950Smrgstripprog=${STRIPPROG-strip}
66f4959950Smrg
67f4959950Smrgposix_mkdir=
68f4959950Smrg
69f4959950Smrg# Desired mode of installed file.
70f4959950Smrgmode=0755
71f4959950Smrg
720cfee914Smrg# Create dirs (including intermediate dirs) using mode 755.
730cfee914Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
740cfee914Smrgmkdir_umask=22
750cfee914Smrg
760cfee914Smrgbackupsuffix=
77f4959950Smrgchgrpcmd=
78f4959950Smrgchmodcmd=$chmodprog
79f4959950Smrgchowncmd=
80f4959950Smrgmvcmd=$mvprog
81f4959950Smrgrmcmd="$rmprog -f"
82f4959950Smrgstripcmd=
83335e815aSmrg
84f4959950Smrgsrc=
85f4959950Smrgdst=
86f4959950Smrgdir_arg=
87f4959950Smrgdst_arg=
88335e815aSmrg
89f4959950Smrgcopy_on_change=false
900cfee914Smrgis_target_a_directory=possibly
91335e815aSmrg
92f4959950Smrgusage="\
93f4959950SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
94f4959950Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
95f4959950Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
96f4959950Smrg   or: $0 [OPTION]... -d DIRECTORIES...
97335e815aSmrg
98f4959950SmrgIn the 1st form, copy SRCFILE to DSTFILE.
99f4959950SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
100f4959950SmrgIn the 4th, create DIRECTORIES.
101335e815aSmrg
102f4959950SmrgOptions:
103f4959950Smrg     --help     display this help and exit.
104f4959950Smrg     --version  display version info and exit.
105335e815aSmrg
106f4959950Smrg  -c            (ignored)
1070cfee914Smrg  -C            install only if different (preserve data modification time)
108f4959950Smrg  -d            create directories instead of installing files.
109f4959950Smrg  -g GROUP      $chgrpprog installed files to GROUP.
110f4959950Smrg  -m MODE       $chmodprog installed files to MODE.
111f4959950Smrg  -o USER       $chownprog installed files to USER.
1120cfee914Smrg  -p            pass -p to $cpprog.
113f4959950Smrg  -s            $stripprog installed files.
1140cfee914Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
115f4959950Smrg  -t DIRECTORY  install into DIRECTORY.
116f4959950Smrg  -T            report an error if DSTFILE is a directory.
117335e815aSmrg
118f4959950SmrgEnvironment variables override the default commands:
119f4959950Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
120f4959950Smrg  RMPROG STRIPPROG
1210cfee914Smrg
1220cfee914SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
1230cfee914Smrgit's up to you to specify -f if you want it.
1240cfee914Smrg
1250cfee914SmrgIf -S is not specified, no backups are attempted.
1260cfee914Smrg
1270cfee914SmrgEmail bug reports to bug-automake@gnu.org.
1280cfee914SmrgAutomake home page: https://www.gnu.org/software/automake/
129f4959950Smrg"
130335e815aSmrg
131f4959950Smrgwhile test $# -ne 0; do
132f4959950Smrg  case $1 in
133f4959950Smrg    -c) ;;
134335e815aSmrg
135f4959950Smrg    -C) copy_on_change=true;;
136335e815aSmrg
137f4959950Smrg    -d) dir_arg=true;;
138335e815aSmrg
139f4959950Smrg    -g) chgrpcmd="$chgrpprog $2"
1400cfee914Smrg        shift;;
141335e815aSmrg
142f4959950Smrg    --help) echo "$usage"; exit $?;;
143335e815aSmrg
144f4959950Smrg    -m) mode=$2
1450cfee914Smrg        case $mode in
1460cfee914Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1470cfee914Smrg            echo "$0: invalid mode: $mode" >&2
1480cfee914Smrg            exit 1;;
1490cfee914Smrg        esac
1500cfee914Smrg        shift;;
151335e815aSmrg
152f4959950Smrg    -o) chowncmd="$chownprog $2"
1530cfee914Smrg        shift;;
1540cfee914Smrg
1550cfee914Smrg    -p) cpprog="$cpprog -p";;
156335e815aSmrg
157f4959950Smrg    -s) stripcmd=$stripprog;;
158335e815aSmrg
1590cfee914Smrg    -S) backupsuffix="$2"
1600cfee914Smrg        shift;;
1610cfee914Smrg
1620cfee914Smrg    -t)
1630cfee914Smrg        is_target_a_directory=always
1640cfee914Smrg        dst_arg=$2
1650cfee914Smrg        # Protect names problematic for 'test' and other utilities.
1660cfee914Smrg        case $dst_arg in
1670cfee914Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1680cfee914Smrg        esac
1690cfee914Smrg        shift;;
170335e815aSmrg
1710cfee914Smrg    -T) is_target_a_directory=never;;
172335e815aSmrg
173f4959950Smrg    --version) echo "$0 $scriptversion"; exit $?;;
174335e815aSmrg
1750cfee914Smrg    --) shift
1760cfee914Smrg        break;;
177335e815aSmrg
1780cfee914Smrg    -*) echo "$0: invalid option: $1" >&2
1790cfee914Smrg        exit 1;;
180335e815aSmrg
181f4959950Smrg    *)  break;;
182f4959950Smrg  esac
183f4959950Smrg  shift
184f4959950Smrgdone
185335e815aSmrg
1860cfee914Smrg# We allow the use of options -d and -T together, by making -d
1870cfee914Smrg# take the precedence; this is for compatibility with GNU install.
1880cfee914Smrg
1890cfee914Smrgif test -n "$dir_arg"; then
1900cfee914Smrg  if test -n "$dst_arg"; then
1910cfee914Smrg    echo "$0: target directory not allowed when installing a directory." >&2
1920cfee914Smrg    exit 1
1930cfee914Smrg  fi
1940cfee914Smrgfi
1950cfee914Smrg
196f4959950Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
197f4959950Smrg  # When -d is used, all remaining arguments are directories to create.
198f4959950Smrg  # When -t is used, the destination is already specified.
199f4959950Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
200f4959950Smrg  for arg
201f4959950Smrg  do
202f4959950Smrg    if test -n "$dst_arg"; then
203f4959950Smrg      # $@ is not empty: it contains at least $arg.
204f4959950Smrg      set fnord "$@" "$dst_arg"
205f4959950Smrg      shift # fnord
206f4959950Smrg    fi
207f4959950Smrg    shift # arg
208f4959950Smrg    dst_arg=$arg
2090cfee914Smrg    # Protect names problematic for 'test' and other utilities.
2100cfee914Smrg    case $dst_arg in
2110cfee914Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
2120cfee914Smrg    esac
213f4959950Smrg  done
214f4959950Smrgfi
215335e815aSmrg
216f4959950Smrgif test $# -eq 0; then
217f4959950Smrg  if test -z "$dir_arg"; then
218f4959950Smrg    echo "$0: no input file specified." >&2
219f4959950Smrg    exit 1
220f4959950Smrg  fi
2210cfee914Smrg  # It's OK to call 'install-sh -d' without argument.
222f4959950Smrg  # This can happen when creating conditional directories.
223f4959950Smrg  exit 0
224f4959950Smrgfi
225335e815aSmrg
226f4959950Smrgif test -z "$dir_arg"; then
2270cfee914Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
2280cfee914Smrg    if test ! -d "$dst_arg"; then
2290cfee914Smrg      echo "$0: $dst_arg: Is not a directory." >&2
2300cfee914Smrg      exit 1
2310cfee914Smrg    fi
2320cfee914Smrg  fi
2330cfee914Smrgfi
2340cfee914Smrg
2350cfee914Smrgif test -z "$dir_arg"; then
2360cfee914Smrg  do_exit='(exit $ret); exit $ret'
2370cfee914Smrg  trap "ret=129; $do_exit" 1
2380cfee914Smrg  trap "ret=130; $do_exit" 2
2390cfee914Smrg  trap "ret=141; $do_exit" 13
2400cfee914Smrg  trap "ret=143; $do_exit" 15
241f4959950Smrg
242f4959950Smrg  # Set umask so as not to create temps with too-generous modes.
243f4959950Smrg  # However, 'strip' requires both read and write access to temps.
244f4959950Smrg  case $mode in
245f4959950Smrg    # Optimize common cases.
246f4959950Smrg    *644) cp_umask=133;;
247f4959950Smrg    *755) cp_umask=22;;
248f4959950Smrg
249f4959950Smrg    *[0-7])
250f4959950Smrg      if test -z "$stripcmd"; then
2510cfee914Smrg        u_plus_rw=
252f4959950Smrg      else
2530cfee914Smrg        u_plus_rw='% 200'
254f4959950Smrg      fi
255f4959950Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
256f4959950Smrg    *)
257f4959950Smrg      if test -z "$stripcmd"; then
2580cfee914Smrg        u_plus_rw=
259f4959950Smrg      else
2600cfee914Smrg        u_plus_rw=,u+rw
261f4959950Smrg      fi
262f4959950Smrg      cp_umask=$mode$u_plus_rw;;
263f4959950Smrg  esac
264f4959950Smrgfi
265335e815aSmrg
266f4959950Smrgfor src
267f4959950Smrgdo
2680cfee914Smrg  # Protect names problematic for 'test' and other utilities.
269f4959950Smrg  case $src in
2700cfee914Smrg    -* | [=\(\)!]) src=./$src;;
271f4959950Smrg  esac
272f4959950Smrg
273f4959950Smrg  if test -n "$dir_arg"; then
274f4959950Smrg    dst=$src
275f4959950Smrg    dstdir=$dst
276f4959950Smrg    test -d "$dstdir"
277f4959950Smrg    dstdir_status=$?
2780cfee914Smrg    # Don't chown directories that already exist.
2790cfee914Smrg    if test $dstdir_status = 0; then
2800cfee914Smrg      chowncmd=""
2810cfee914Smrg    fi
282f4959950Smrg  else
283f4959950Smrg
284f4959950Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
285f4959950Smrg    # might cause directories to be created, which would be especially bad
286f4959950Smrg    # if $src (and thus $dsttmp) contains '*'.
287f4959950Smrg    if test ! -f "$src" && test ! -d "$src"; then
288f4959950Smrg      echo "$0: $src does not exist." >&2
289f4959950Smrg      exit 1
290f4959950Smrg    fi
291f4959950Smrg
292f4959950Smrg    if test -z "$dst_arg"; then
293f4959950Smrg      echo "$0: no destination specified." >&2
294f4959950Smrg      exit 1
295f4959950Smrg    fi
296f4959950Smrg    dst=$dst_arg
297335e815aSmrg
2980cfee914Smrg    # If destination is a directory, append the input filename.
299f4959950Smrg    if test -d "$dst"; then
3000cfee914Smrg      if test "$is_target_a_directory" = never; then
3010cfee914Smrg        echo "$0: $dst_arg: Is a directory" >&2
3020cfee914Smrg        exit 1
303f4959950Smrg      fi
304f4959950Smrg      dstdir=$dst
3050cfee914Smrg      dstbase=`basename "$src"`
3060cfee914Smrg      case $dst in
3070cfee914Smrg	*/) dst=$dst$dstbase;;
3080cfee914Smrg	*)  dst=$dst/$dstbase;;
3090cfee914Smrg      esac
310f4959950Smrg      dstdir_status=0
311f4959950Smrg    else
3120cfee914Smrg      dstdir=`dirname "$dst"`
313f4959950Smrg      test -d "$dstdir"
314f4959950Smrg      dstdir_status=$?
315f4959950Smrg    fi
316f4959950Smrg  fi
317f4959950Smrg
3180cfee914Smrg  case $dstdir in
3190cfee914Smrg    */) dstdirslash=$dstdir;;
3200cfee914Smrg    *)  dstdirslash=$dstdir/;;
3210cfee914Smrg  esac
3220cfee914Smrg
323f4959950Smrg  obsolete_mkdir_used=false
324f4959950Smrg
325f4959950Smrg  if test $dstdir_status != 0; then
326f4959950Smrg    case $posix_mkdir in
327f4959950Smrg      '')
3280cfee914Smrg        # With -d, create the new directory with the user-specified mode.
3290cfee914Smrg        # Otherwise, rely on $mkdir_umask.
3300cfee914Smrg        if test -n "$dir_arg"; then
3310cfee914Smrg          mkdir_mode=-m$mode
3320cfee914Smrg        else
3330cfee914Smrg          mkdir_mode=
3340cfee914Smrg        fi
3350cfee914Smrg
3360cfee914Smrg        posix_mkdir=false
3370cfee914Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
3380cfee914Smrg	# here however when possible just to lower collision chance.
3390cfee914Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3400cfee914Smrg
3410cfee914Smrg	trap '
3420cfee914Smrg	  ret=$?
3430cfee914Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
3440cfee914Smrg	  exit $ret
3450cfee914Smrg	' 0
3460cfee914Smrg
3470cfee914Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
3480cfee914Smrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
3490cfee914Smrg	# directory is successfully created first before we actually test
3500cfee914Smrg	# 'mkdir -p'.
3510cfee914Smrg	if (umask $mkdir_umask &&
3520cfee914Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
3530cfee914Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
3540cfee914Smrg	then
3550cfee914Smrg	  if test -z "$dir_arg" || {
3560cfee914Smrg	       # Check for POSIX incompatibilities with -m.
3570cfee914Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3580cfee914Smrg	       # other-writable bit of parent directory when it shouldn't.
3590cfee914Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3600cfee914Smrg	       test_tmpdir="$tmpdir/a"
3610cfee914Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
3620cfee914Smrg	       case $ls_ld_tmpdir in
3630cfee914Smrg		 d????-?r-*) different_mode=700;;
3640cfee914Smrg		 d????-?--*) different_mode=755;;
3650cfee914Smrg		 *) false;;
3660cfee914Smrg	       esac &&
3670cfee914Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
3680cfee914Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
3690cfee914Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3700cfee914Smrg	       }
3710cfee914Smrg	     }
3720cfee914Smrg	  then posix_mkdir=:
3730cfee914Smrg	  fi
3740cfee914Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
375335e815aSmrg	else
3760cfee914Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
3770cfee914Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
378335e815aSmrg	fi
3790cfee914Smrg	trap '' 0;;
380f4959950Smrg    esac
381335e815aSmrg
382f4959950Smrg    if
383f4959950Smrg      $posix_mkdir && (
3840cfee914Smrg        umask $mkdir_umask &&
3850cfee914Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
386f4959950Smrg      )
387f4959950Smrg    then :
388f4959950Smrg    else
389f4959950Smrg
3900cfee914Smrg      # mkdir does not conform to POSIX,
391f4959950Smrg      # or it failed possibly due to a race condition.  Create the
392f4959950Smrg      # directory the slow way, step by step, checking for races as we go.
393f4959950Smrg
394f4959950Smrg      case $dstdir in
3950cfee914Smrg        /*) prefix='/';;
3960cfee914Smrg        [-=\(\)!]*) prefix='./';;
3970cfee914Smrg        *)  prefix='';;
398f4959950Smrg      esac
399f4959950Smrg
400f4959950Smrg      oIFS=$IFS
401f4959950Smrg      IFS=/
4020cfee914Smrg      set -f
403f4959950Smrg      set fnord $dstdir
404f4959950Smrg      shift
4050cfee914Smrg      set +f
406f4959950Smrg      IFS=$oIFS
407f4959950Smrg
408f4959950Smrg      prefixes=
409f4959950Smrg
410f4959950Smrg      for d
411f4959950Smrg      do
4120cfee914Smrg        test X"$d" = X && continue
4130cfee914Smrg
4140cfee914Smrg        prefix=$prefix$d
4150cfee914Smrg        if test -d "$prefix"; then
4160cfee914Smrg          prefixes=
4170cfee914Smrg        else
4180cfee914Smrg          if $posix_mkdir; then
4190cfee914Smrg            (umask $mkdir_umask &&
4200cfee914Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4210cfee914Smrg            # Don't fail if two instances are running concurrently.
4220cfee914Smrg            test -d "$prefix" || exit 1
4230cfee914Smrg          else
4240cfee914Smrg            case $prefix in
4250cfee914Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4260cfee914Smrg              *) qprefix=$prefix;;
4270cfee914Smrg            esac
4280cfee914Smrg            prefixes="$prefixes '$qprefix'"
4290cfee914Smrg          fi
4300cfee914Smrg        fi
4310cfee914Smrg        prefix=$prefix/
432f4959950Smrg      done
433f4959950Smrg
434f4959950Smrg      if test -n "$prefixes"; then
4350cfee914Smrg        # Don't fail if two instances are running concurrently.
4360cfee914Smrg        (umask $mkdir_umask &&
4370cfee914Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
4380cfee914Smrg          test -d "$dstdir" || exit 1
4390cfee914Smrg        obsolete_mkdir_used=true
440f4959950Smrg      fi
441f4959950Smrg    fi
442f4959950Smrg  fi
443f4959950Smrg
444f4959950Smrg  if test -n "$dir_arg"; then
445f4959950Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
446f4959950Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
447f4959950Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
448f4959950Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
449f4959950Smrg  else
450f4959950Smrg
451f4959950Smrg    # Make a couple of temp file names in the proper directory.
4520cfee914Smrg    dsttmp=${dstdirslash}_inst.$$_
4530cfee914Smrg    rmtmp=${dstdirslash}_rm.$$_
454f4959950Smrg
455f4959950Smrg    # Trap to clean up those temp files at exit.
456f4959950Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
457f4959950Smrg
458f4959950Smrg    # Copy the file name to the temp name.
4590cfee914Smrg    (umask $cp_umask &&
4600cfee914Smrg     { test -z "$stripcmd" || {
4610cfee914Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
4620cfee914Smrg	 # which would cause strip to fail.
4630cfee914Smrg	 if test -z "$doit"; then
4640cfee914Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
4650cfee914Smrg	 else
4660cfee914Smrg	   $doit touch "$dsttmp"
4670cfee914Smrg	 fi
4680cfee914Smrg       }
4690cfee914Smrg     } &&
4700cfee914Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
471f4959950Smrg
472f4959950Smrg    # and set any options; do chmod last to preserve setuid bits.
473f4959950Smrg    #
474f4959950Smrg    # If any of these fail, we abort the whole thing.  If we want to
475f4959950Smrg    # ignore errors from any of these, just make sure not to ignore
476f4959950Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
477f4959950Smrg    #
478f4959950Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
479f4959950Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
480f4959950Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
481f4959950Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
482f4959950Smrg
483f4959950Smrg    # If -C, don't bother to copy if it wouldn't change the file.
484f4959950Smrg    if $copy_on_change &&
4850cfee914Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4860cfee914Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
4870cfee914Smrg       set -f &&
488f4959950Smrg       set X $old && old=:$2:$4:$5:$6 &&
489f4959950Smrg       set X $new && new=:$2:$4:$5:$6 &&
4900cfee914Smrg       set +f &&
491f4959950Smrg       test "$old" = "$new" &&
492f4959950Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
493f4959950Smrg    then
494f4959950Smrg      rm -f "$dsttmp"
495f4959950Smrg    else
4960cfee914Smrg      # If $backupsuffix is set, and the file being installed
4970cfee914Smrg      # already exists, attempt a backup.  Don't worry if it fails,
4980cfee914Smrg      # e.g., if mv doesn't support -f.
4990cfee914Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
5000cfee914Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
5010cfee914Smrg      fi
5020cfee914Smrg
503f4959950Smrg      # Rename the file to the real destination.
504f4959950Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
505f4959950Smrg
506f4959950Smrg      # The rename failed, perhaps because mv can't rename something else
507f4959950Smrg      # to itself, or perhaps because mv is so ancient that it does not
508f4959950Smrg      # support -f.
509f4959950Smrg      {
5100cfee914Smrg        # Now remove or move aside any old file at destination location.
5110cfee914Smrg        # We try this two ways since rm can't unlink itself on some
5120cfee914Smrg        # systems and the destination file might be busy for other
5130cfee914Smrg        # reasons.  In this case, the final cleanup might fail but the new
5140cfee914Smrg        # file should still install successfully.
5150cfee914Smrg        {
5160cfee914Smrg          test ! -f "$dst" ||
5170cfee914Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
5180cfee914Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
5190cfee914Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
5200cfee914Smrg          } ||
5210cfee914Smrg          { echo "$0: cannot unlink or rename $dst" >&2
5220cfee914Smrg            (exit 1); exit 1
5230cfee914Smrg          }
5240cfee914Smrg        } &&
5250cfee914Smrg
5260cfee914Smrg        # Now rename the file to the real destination.
5270cfee914Smrg        $doit $mvcmd "$dsttmp" "$dst"
528f4959950Smrg      }
529f4959950Smrg    fi || exit 1
530f4959950Smrg
531f4959950Smrg    trap '' 0
532f4959950Smrg  fi
533f4959950Smrgdone
534335e815aSmrg
535f4959950Smrg# Local variables:
5360cfee914Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
537f4959950Smrg# time-stamp-start: "scriptversion="
538f4959950Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5390cfee914Smrg# time-stamp-time-zone: "UTC0"
540f4959950Smrg# time-stamp-end: "; # UTC"
541f4959950Smrg# End:
542