1266e564dSmrg#!/bin/sh
2266e564dSmrg# install - install a program, script, or datafile
3266e564dSmrg
43bf3b463Smrgscriptversion=2024-06-19.01; # UTC
5266e564dSmrg
6266e564dSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7266e564dSmrg# later released in X11R6 (xc/config/util/install.sh) with the
8266e564dSmrg# following copyright and license.
9266e564dSmrg#
10266e564dSmrg# Copyright (C) 1994 X Consortium
11266e564dSmrg#
12266e564dSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13266e564dSmrg# of this software and associated documentation files (the "Software"), to
14266e564dSmrg# deal in the Software without restriction, including without limitation the
15266e564dSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16266e564dSmrg# sell copies of the Software, and to permit persons to whom the Software is
17266e564dSmrg# furnished to do so, subject to the following conditions:
18266e564dSmrg#
19266e564dSmrg# The above copyright notice and this permission notice shall be included in
20266e564dSmrg# all copies or substantial portions of the Software.
21266e564dSmrg#
22266e564dSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23266e564dSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24266e564dSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25266e564dSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26266e564dSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27266e564dSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28266e564dSmrg#
29266e564dSmrg# Except as contained in this notice, the name of the X Consortium shall not
30266e564dSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
31266e564dSmrg# ings in this Software without prior written authorization from the X Consor-
32266e564dSmrg# tium.
33266e564dSmrg#
34266e564dSmrg#
35266e564dSmrg# FSF changes to this file are in the public domain.
36266e564dSmrg#
37266e564dSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38fb5e8d76Smrg# 'make' implicit rules from creating a file called install from it
39266e564dSmrg# when there is no Makefile.
40266e564dSmrg#
41266e564dSmrg# This script is compatible with the BSD install script, but was written
42266e564dSmrg# from scratch.
43266e564dSmrg
44a3129944Smrgtab='	'
45266e564dSmrgnl='
46266e564dSmrg'
47a3129944SmrgIFS=" $tab$nl"
48266e564dSmrg
49a3129944Smrg# Set DOITPROG to "echo" to test this script.
50266e564dSmrg
51c5629e66Smrgdoit=${DOITPROG-}
52a3129944Smrgdoit_exec=${doit:-exec}
53266e564dSmrg
54266e564dSmrg# Put in absolute file names if you don't have them in your path;
55266e564dSmrg# or use environment vars.
56266e564dSmrg
57c5629e66Smrgchgrpprog=${CHGRPPROG-chgrp}
58c5629e66Smrgchmodprog=${CHMODPROG-chmod}
59c5629e66Smrgchownprog=${CHOWNPROG-chown}
60c5629e66Smrgcmpprog=${CMPPROG-cmp}
61c5629e66Smrgcpprog=${CPPROG-cp}
62c5629e66Smrgmkdirprog=${MKDIRPROG-mkdir}
63c5629e66Smrgmvprog=${MVPROG-mv}
64c5629e66Smrgrmprog=${RMPROG-rm}
65c5629e66Smrgstripprog=${STRIPPROG-strip}
66c5629e66Smrg
67266e564dSmrgposix_mkdir=
68266e564dSmrg
69266e564dSmrg# Desired mode of installed file.
70266e564dSmrgmode=0755
71266e564dSmrg
721009a292Smrg# Create dirs (including intermediate dirs) using mode 755.
731009a292Smrg# This is like GNU 'install' as of coreutils 8.32 (2020).
741009a292Smrgmkdir_umask=22
751009a292Smrg
761009a292Smrgbackupsuffix=
77c5629e66Smrgchgrpcmd=
78266e564dSmrgchmodcmd=$chmodprog
79266e564dSmrgchowncmd=
80c5629e66Smrgmvcmd=$mvprog
81266e564dSmrgrmcmd="$rmprog -f"
82c5629e66Smrgstripcmd=
83c5629e66Smrg
84266e564dSmrgsrc=
85266e564dSmrgdst=
86266e564dSmrgdir_arg=
87c5629e66Smrgdst_arg=
88c5629e66Smrg
89c5629e66Smrgcopy_on_change=false
90a3129944Smrgis_target_a_directory=possibly
91266e564dSmrg
92c5629e66Smrgusage="\
93c5629e66SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
94266e564dSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
95266e564dSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
96266e564dSmrg   or: $0 [OPTION]... -d DIRECTORIES...
97266e564dSmrg
98266e564dSmrgIn the 1st form, copy SRCFILE to DSTFILE.
99266e564dSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
100266e564dSmrgIn the 4th, create DIRECTORIES.
101266e564dSmrg
102266e564dSmrgOptions:
103c5629e66Smrg     --help     display this help and exit.
104c5629e66Smrg     --version  display version info and exit.
105c5629e66Smrg
106c5629e66Smrg  -c            (ignored)
1071009a292Smrg  -C            install only if different (preserve data modification time)
108c5629e66Smrg  -d            create directories instead of installing files.
109c5629e66Smrg  -g GROUP      $chgrpprog installed files to GROUP.
110c5629e66Smrg  -m MODE       $chmodprog installed files to MODE.
111c5629e66Smrg  -o USER       $chownprog installed files to USER.
1121009a292Smrg  -p            pass -p to $cpprog.
113c5629e66Smrg  -s            $stripprog installed files.
1141009a292Smrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
115c5629e66Smrg  -t DIRECTORY  install into DIRECTORY.
116c5629e66Smrg  -T            report an error if DSTFILE is a directory.
117266e564dSmrg
118266e564dSmrgEnvironment variables override the default commands:
119c5629e66Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
120c5629e66Smrg  RMPROG STRIPPROG
1211009a292Smrg
1221009a292SmrgBy default, rm is invoked with -f; when overridden with RMPROG,
1231009a292Smrgit's up to you to specify -f if you want it.
1241009a292Smrg
1251009a292SmrgIf -S is not specified, no backups are attempted.
1261009a292Smrg
1273bf3b463SmrgReport bugs to <bug-automake@gnu.org>.
1283bf3b463SmrgGNU Automake home page: <https://www.gnu.org/software/automake/>.
1293bf3b463SmrgGeneral help using GNU software: <https://www.gnu.org/gethelp/>."
130266e564dSmrg
131266e564dSmrgwhile test $# -ne 0; do
132266e564dSmrg  case $1 in
133c5629e66Smrg    -c) ;;
134c5629e66Smrg
135c5629e66Smrg    -C) copy_on_change=true;;
136266e564dSmrg
137c5629e66Smrg    -d) dir_arg=true;;
138266e564dSmrg
139266e564dSmrg    -g) chgrpcmd="$chgrpprog $2"
140a3129944Smrg        shift;;
141266e564dSmrg
142266e564dSmrg    --help) echo "$usage"; exit $?;;
143266e564dSmrg
144266e564dSmrg    -m) mode=$2
145a3129944Smrg        case $mode in
146a3129944Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
147a3129944Smrg            echo "$0: invalid mode: $mode" >&2
148a3129944Smrg            exit 1;;
149a3129944Smrg        esac
150a3129944Smrg        shift;;
151266e564dSmrg
152266e564dSmrg    -o) chowncmd="$chownprog $2"
153a3129944Smrg        shift;;
154266e564dSmrg
1551009a292Smrg    -p) cpprog="$cpprog -p";;
1561009a292Smrg
157c5629e66Smrg    -s) stripcmd=$stripprog;;
158266e564dSmrg
1591009a292Smrg    -S) backupsuffix="$2"
1601009a292Smrg        shift;;
1611009a292Smrg
162a3129944Smrg    -t)
163a3129944Smrg        is_target_a_directory=always
164a3129944Smrg        dst_arg=$2
165a3129944Smrg        # Protect names problematic for 'test' and other utilities.
166a3129944Smrg        case $dst_arg in
167a3129944Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
168a3129944Smrg        esac
169a3129944Smrg        shift;;
170266e564dSmrg
171a3129944Smrg    -T) is_target_a_directory=never;;
172266e564dSmrg
1733bf3b463Smrg    --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;;
174266e564dSmrg
175a3129944Smrg    --) shift
176a3129944Smrg        break;;
177266e564dSmrg
178a3129944Smrg    -*) echo "$0: invalid option: $1" >&2
179a3129944Smrg        exit 1;;
180266e564dSmrg
181266e564dSmrg    *)  break;;
182266e564dSmrg  esac
183c5629e66Smrg  shift
184266e564dSmrgdone
185266e564dSmrg
186a3129944Smrg# We allow the use of options -d and -T together, by making -d
187a3129944Smrg# take the precedence; this is for compatibility with GNU install.
188a3129944Smrg
189a3129944Smrgif test -n "$dir_arg"; then
190a3129944Smrg  if test -n "$dst_arg"; then
191a3129944Smrg    echo "$0: target directory not allowed when installing a directory." >&2
192a3129944Smrg    exit 1
193a3129944Smrg  fi
194a3129944Smrgfi
195a3129944Smrg
196c5629e66Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
197266e564dSmrg  # When -d is used, all remaining arguments are directories to create.
198266e564dSmrg  # When -t is used, the destination is already specified.
199266e564dSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
200266e564dSmrg  for arg
201266e564dSmrg  do
202c5629e66Smrg    if test -n "$dst_arg"; then
203266e564dSmrg      # $@ is not empty: it contains at least $arg.
204c5629e66Smrg      set fnord "$@" "$dst_arg"
205266e564dSmrg      shift # fnord
206266e564dSmrg    fi
207266e564dSmrg    shift # arg
208c5629e66Smrg    dst_arg=$arg
209fb5e8d76Smrg    # Protect names problematic for 'test' and other utilities.
210fb5e8d76Smrg    case $dst_arg in
211fb5e8d76Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
212fb5e8d76Smrg    esac
213266e564dSmrg  done
214266e564dSmrgfi
215266e564dSmrg
216266e564dSmrgif test $# -eq 0; then
217266e564dSmrg  if test -z "$dir_arg"; then
218266e564dSmrg    echo "$0: no input file specified." >&2
219266e564dSmrg    exit 1
220266e564dSmrg  fi
221fb5e8d76Smrg  # It's OK to call 'install-sh -d' without argument.
222266e564dSmrg  # This can happen when creating conditional directories.
223266e564dSmrg  exit 0
224266e564dSmrgfi
225266e564dSmrg
226a3129944Smrgif test -z "$dir_arg"; then
227a3129944Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
228a3129944Smrg    if test ! -d "$dst_arg"; then
229a3129944Smrg      echo "$0: $dst_arg: Is not a directory." >&2
230a3129944Smrg      exit 1
231a3129944Smrg    fi
232a3129944Smrg  fi
233a3129944Smrgfi
234a3129944Smrg
235266e564dSmrgif test -z "$dir_arg"; then
236fb5e8d76Smrg  do_exit='(exit $ret); exit $ret'
237fb5e8d76Smrg  trap "ret=129; $do_exit" 1
238fb5e8d76Smrg  trap "ret=130; $do_exit" 2
239fb5e8d76Smrg  trap "ret=141; $do_exit" 13
240fb5e8d76Smrg  trap "ret=143; $do_exit" 15
241266e564dSmrg
242266e564dSmrg  # Set umask so as not to create temps with too-generous modes.
243266e564dSmrg  # However, 'strip' requires both read and write access to temps.
244266e564dSmrg  case $mode in
245266e564dSmrg    # Optimize common cases.
246266e564dSmrg    *644) cp_umask=133;;
247266e564dSmrg    *755) cp_umask=22;;
248266e564dSmrg
249266e564dSmrg    *[0-7])
250266e564dSmrg      if test -z "$stripcmd"; then
251a3129944Smrg        u_plus_rw=
252266e564dSmrg      else
253a3129944Smrg        u_plus_rw='% 200'
254266e564dSmrg      fi
255266e564dSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
256266e564dSmrg    *)
257266e564dSmrg      if test -z "$stripcmd"; then
258a3129944Smrg        u_plus_rw=
259266e564dSmrg      else
260a3129944Smrg        u_plus_rw=,u+rw
261266e564dSmrg      fi
262266e564dSmrg      cp_umask=$mode$u_plus_rw;;
263266e564dSmrg  esac
264266e564dSmrgfi
265266e564dSmrg
266266e564dSmrgfor src
267266e564dSmrgdo
268fb5e8d76Smrg  # Protect names problematic for 'test' and other utilities.
269266e564dSmrg  case $src in
270fb5e8d76Smrg    -* | [=\(\)!]) src=./$src;;
271266e564dSmrg  esac
272266e564dSmrg
273266e564dSmrg  if test -n "$dir_arg"; then
274266e564dSmrg    dst=$src
275266e564dSmrg    dstdir=$dst
276266e564dSmrg    test -d "$dstdir"
277266e564dSmrg    dstdir_status=$?
2781009a292Smrg    # Don't chown directories that already exist.
2791009a292Smrg    if test $dstdir_status = 0; then
2801009a292Smrg      chowncmd=""
2811009a292Smrg    fi
282266e564dSmrg  else
283266e564dSmrg
284266e564dSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
285266e564dSmrg    # might cause directories to be created, which would be especially bad
286266e564dSmrg    # if $src (and thus $dsttmp) contains '*'.
287266e564dSmrg    if test ! -f "$src" && test ! -d "$src"; then
288266e564dSmrg      echo "$0: $src does not exist." >&2
289266e564dSmrg      exit 1
290266e564dSmrg    fi
291266e564dSmrg
292c5629e66Smrg    if test -z "$dst_arg"; then
293266e564dSmrg      echo "$0: no destination specified." >&2
294266e564dSmrg      exit 1
295266e564dSmrg    fi
296c5629e66Smrg    dst=$dst_arg
297266e564dSmrg
2981009a292Smrg    # If destination is a directory, append the input filename.
299266e564dSmrg    if test -d "$dst"; then
300a3129944Smrg      if test "$is_target_a_directory" = never; then
301a3129944Smrg        echo "$0: $dst_arg: Is a directory" >&2
302a3129944Smrg        exit 1
303266e564dSmrg      fi
304266e564dSmrg      dstdir=$dst
3051009a292Smrg      dstbase=`basename "$src"`
3061009a292Smrg      case $dst in
3071009a292Smrg	*/) dst=$dst$dstbase;;
3081009a292Smrg	*)  dst=$dst/$dstbase;;
3091009a292Smrg      esac
310266e564dSmrg      dstdir_status=0
311266e564dSmrg    else
312a3129944Smrg      dstdir=`dirname "$dst"`
313266e564dSmrg      test -d "$dstdir"
314266e564dSmrg      dstdir_status=$?
315266e564dSmrg    fi
316266e564dSmrg  fi
317266e564dSmrg
3181009a292Smrg  case $dstdir in
3191009a292Smrg    */) dstdirslash=$dstdir;;
3201009a292Smrg    *)  dstdirslash=$dstdir/;;
3211009a292Smrg  esac
3221009a292Smrg
323266e564dSmrg  obsolete_mkdir_used=false
324266e564dSmrg
325266e564dSmrg  if test $dstdir_status != 0; then
326266e564dSmrg    case $posix_mkdir in
327266e564dSmrg      '')
328a3129944Smrg        # With -d, create the new directory with the user-specified mode.
329a3129944Smrg        # Otherwise, rely on $mkdir_umask.
330a3129944Smrg        if test -n "$dir_arg"; then
331a3129944Smrg          mkdir_mode=-m$mode
332a3129944Smrg        else
333a3129944Smrg          mkdir_mode=
334a3129944Smrg        fi
335a3129944Smrg
336a3129944Smrg        posix_mkdir=false
3371009a292Smrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
3381009a292Smrg	# here however when possible just to lower collision chance.
3391009a292Smrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3401009a292Smrg
3411009a292Smrg	trap '
3421009a292Smrg	  ret=$?
3431009a292Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
3441009a292Smrg	  exit $ret
3451009a292Smrg	' 0
3461009a292Smrg
3471009a292Smrg	# Because "mkdir -p" follows existing symlinks and we likely work
3483bf3b463Smrg	# directly in world-writable /tmp, make sure that the '$tmpdir'
3491009a292Smrg	# directory is successfully created first before we actually test
3501009a292Smrg	# 'mkdir -p'.
3511009a292Smrg	if (umask $mkdir_umask &&
3521009a292Smrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
3531009a292Smrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
3541009a292Smrg	then
3551009a292Smrg	  if test -z "$dir_arg" || {
3563bf3b463Smrg	       # Check for POSIX incompatibility with -m.
3571009a292Smrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3581009a292Smrg	       # other-writable bit of parent directory when it shouldn't.
3591009a292Smrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3601009a292Smrg	       test_tmpdir="$tmpdir/a"
3611009a292Smrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
3621009a292Smrg	       case $ls_ld_tmpdir in
3631009a292Smrg		 d????-?r-*) different_mode=700;;
3641009a292Smrg		 d????-?--*) different_mode=755;;
3651009a292Smrg		 *) false;;
3661009a292Smrg	       esac &&
3671009a292Smrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
3681009a292Smrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
3691009a292Smrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3701009a292Smrg	       }
3711009a292Smrg	     }
3721009a292Smrg	  then posix_mkdir=:
3731009a292Smrg	  fi
3741009a292Smrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
3751009a292Smrg	else
3761009a292Smrg	  # Remove any dirs left behind by ancient mkdir implementations.
3771009a292Smrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
3781009a292Smrg	fi
3791009a292Smrg	trap '' 0;;
380266e564dSmrg    esac
381266e564dSmrg
382266e564dSmrg    if
383266e564dSmrg      $posix_mkdir && (
384a3129944Smrg        umask $mkdir_umask &&
385a3129944Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
386266e564dSmrg      )
387266e564dSmrg    then :
388266e564dSmrg    else
389266e564dSmrg
3901009a292Smrg      # mkdir does not conform to POSIX,
391266e564dSmrg      # or it failed possibly due to a race condition.  Create the
392266e564dSmrg      # directory the slow way, step by step, checking for races as we go.
393266e564dSmrg
394266e564dSmrg      case $dstdir in
395a3129944Smrg        /*) prefix='/';;
396a3129944Smrg        [-=\(\)!]*) prefix='./';;
397a3129944Smrg        *)  prefix='';;
398266e564dSmrg      esac
399266e564dSmrg
400266e564dSmrg      oIFS=$IFS
401266e564dSmrg      IFS=/
402a3129944Smrg      set -f
403266e564dSmrg      set fnord $dstdir
404266e564dSmrg      shift
405a3129944Smrg      set +f
406266e564dSmrg      IFS=$oIFS
407266e564dSmrg
408266e564dSmrg      prefixes=
409266e564dSmrg
410266e564dSmrg      for d
411266e564dSmrg      do
412a3129944Smrg        test X"$d" = X && continue
413a3129944Smrg
414a3129944Smrg        prefix=$prefix$d
415a3129944Smrg        if test -d "$prefix"; then
416a3129944Smrg          prefixes=
417a3129944Smrg        else
418a3129944Smrg          if $posix_mkdir; then
4191009a292Smrg            (umask $mkdir_umask &&
420a3129944Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
421a3129944Smrg            # Don't fail if two instances are running concurrently.
422a3129944Smrg            test -d "$prefix" || exit 1
423a3129944Smrg          else
424a3129944Smrg            case $prefix in
425a3129944Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
426a3129944Smrg              *) qprefix=$prefix;;
427a3129944Smrg            esac
428a3129944Smrg            prefixes="$prefixes '$qprefix'"
429a3129944Smrg          fi
430a3129944Smrg        fi
431a3129944Smrg        prefix=$prefix/
432266e564dSmrg      done
433266e564dSmrg
434266e564dSmrg      if test -n "$prefixes"; then
435a3129944Smrg        # Don't fail if two instances are running concurrently.
436a3129944Smrg        (umask $mkdir_umask &&
437a3129944Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
438a3129944Smrg          test -d "$dstdir" || exit 1
439a3129944Smrg        obsolete_mkdir_used=true
440266e564dSmrg      fi
441266e564dSmrg    fi
442266e564dSmrg  fi
443266e564dSmrg
444266e564dSmrg  if test -n "$dir_arg"; then
445266e564dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
446266e564dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
447266e564dSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
448266e564dSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
449266e564dSmrg  else
450266e564dSmrg
451266e564dSmrg    # Make a couple of temp file names in the proper directory.
4521009a292Smrg    dsttmp=${dstdirslash}_inst.$$_
4531009a292Smrg    rmtmp=${dstdirslash}_rm.$$_
454266e564dSmrg
455266e564dSmrg    # Trap to clean up those temp files at exit.
456266e564dSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
457266e564dSmrg
458266e564dSmrg    # Copy the file name to the temp name.
4591009a292Smrg    (umask $cp_umask &&
4601009a292Smrg     { test -z "$stripcmd" || {
4611009a292Smrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
4621009a292Smrg	 # which would cause strip to fail.
4631009a292Smrg	 if test -z "$doit"; then
4641009a292Smrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
4651009a292Smrg	 else
4661009a292Smrg	   $doit touch "$dsttmp"
4671009a292Smrg	 fi
4681009a292Smrg       }
4691009a292Smrg     } &&
4701009a292Smrg     $doit_exec $cpprog "$src" "$dsttmp") &&
471266e564dSmrg
472266e564dSmrg    # and set any options; do chmod last to preserve setuid bits.
473266e564dSmrg    #
474266e564dSmrg    # If any of these fail, we abort the whole thing.  If we want to
475266e564dSmrg    # ignore errors from any of these, just make sure not to ignore
476266e564dSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
477266e564dSmrg    #
478c5629e66Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
479c5629e66Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
480c5629e66Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
481c5629e66Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
482c5629e66Smrg
483c5629e66Smrg    # If -C, don't bother to copy if it wouldn't change the file.
484c5629e66Smrg    if $copy_on_change &&
485a3129944Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
486a3129944Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
487a3129944Smrg       set -f &&
488c5629e66Smrg       set X $old && old=:$2:$4:$5:$6 &&
489c5629e66Smrg       set X $new && new=:$2:$4:$5:$6 &&
490a3129944Smrg       set +f &&
491c5629e66Smrg       test "$old" = "$new" &&
492c5629e66Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
493c5629e66Smrg    then
494c5629e66Smrg      rm -f "$dsttmp"
495c5629e66Smrg    else
4961009a292Smrg      # If $backupsuffix is set, and the file being installed
4971009a292Smrg      # already exists, attempt a backup.  Don't worry if it fails,
4981009a292Smrg      # e.g., if mv doesn't support -f.
4991009a292Smrg      if test -n "$backupsuffix" && test -f "$dst"; then
5001009a292Smrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
5011009a292Smrg      fi
5021009a292Smrg
503c5629e66Smrg      # Rename the file to the real destination.
504c5629e66Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
505c5629e66Smrg
506c5629e66Smrg      # The rename failed, perhaps because mv can't rename something else
507c5629e66Smrg      # to itself, or perhaps because mv is so ancient that it does not
508c5629e66Smrg      # support -f.
509c5629e66Smrg      {
510a3129944Smrg        # Now remove or move aside any old file at destination location.
511a3129944Smrg        # We try this two ways since rm can't unlink itself on some
512a3129944Smrg        # systems and the destination file might be busy for other
513a3129944Smrg        # reasons.  In this case, the final cleanup might fail but the new
514a3129944Smrg        # file should still install successfully.
515a3129944Smrg        {
516a3129944Smrg          test ! -f "$dst" ||
5171009a292Smrg          $doit $rmcmd "$dst" 2>/dev/null ||
518a3129944Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
5191009a292Smrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
520a3129944Smrg          } ||
521a3129944Smrg          { echo "$0: cannot unlink or rename $dst" >&2
522a3129944Smrg            (exit 1); exit 1
523a3129944Smrg          }
524a3129944Smrg        } &&
525a3129944Smrg
526a3129944Smrg        # Now rename the file to the real destination.
527a3129944Smrg        $doit $mvcmd "$dsttmp" "$dst"
528c5629e66Smrg      }
529c5629e66Smrg    fi || exit 1
530266e564dSmrg
531266e564dSmrg    trap '' 0
532266e564dSmrg  fi
533266e564dSmrgdone
534266e564dSmrg
535266e564dSmrg# Local variables:
5361009a292Smrg# eval: (add-hook 'before-save-hook 'time-stamp)
537266e564dSmrg# time-stamp-start: "scriptversion="
538266e564dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5391009a292Smrg# time-stamp-time-zone: "UTC0"
540d17cd367Smrg# time-stamp-end: "; # UTC"
541266e564dSmrg# End:
542