install-sh revision 26df5c7c
1a1d141d5Smrg#!/bin/sh
2a1d141d5Smrg# install - install a program, script, or datafile
32ddb6cf1Smrg
426df5c7cSmrgscriptversion=2020-11-14.01; # UTC
52ddb6cf1Smrg
6a1d141d5Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7a1d141d5Smrg# later released in X11R6 (xc/config/util/install.sh) with the
8a1d141d5Smrg# following copyright and license.
9a1d141d5Smrg#
10a1d141d5Smrg# Copyright (C) 1994 X Consortium
11a1d141d5Smrg#
12a1d141d5Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13a1d141d5Smrg# of this software and associated documentation files (the "Software"), to
14a1d141d5Smrg# deal in the Software without restriction, including without limitation the
15a1d141d5Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16a1d141d5Smrg# sell copies of the Software, and to permit persons to whom the Software is
17a1d141d5Smrg# furnished to do so, subject to the following conditions:
18a1d141d5Smrg#
19a1d141d5Smrg# The above copyright notice and this permission notice shall be included in
20a1d141d5Smrg# all copies or substantial portions of the Software.
21a1d141d5Smrg#
22a1d141d5Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23a1d141d5Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24a1d141d5Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25a1d141d5Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26a1d141d5Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27a1d141d5Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28a1d141d5Smrg#
29a1d141d5Smrg# Except as contained in this notice, the name of the X Consortium shall not
30a1d141d5Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
31a1d141d5Smrg# ings in this Software without prior written authorization from the X Consor-
32a1d141d5Smrg# tium.
33a1d141d5Smrg#
34a1d141d5Smrg#
35a1d141d5Smrg# FSF changes to this file are in the public domain.
36a1d141d5Smrg#
37a1d141d5Smrg# Calling this script install-sh is preferred over install.sh, to prevent
38054b3d00Smrg# 'make' implicit rules from creating a file called install from it
39a1d141d5Smrg# when there is no Makefile.
40a1d141d5Smrg#
41a1d141d5Smrg# This script is compatible with the BSD install script, but was written
422ddb6cf1Smrg# from scratch.
43a1d141d5Smrg
44054b3d00Smrgtab='	'
452ddb6cf1Smrgnl='
462ddb6cf1Smrg'
47054b3d00SmrgIFS=" $tab$nl"
48a1d141d5Smrg
49054b3d00Smrg# Set DOITPROG to "echo" to test this script.
50a1d141d5Smrg
512ddb6cf1Smrgdoit=${DOITPROG-}
52054b3d00Smrgdoit_exec=${doit:-exec}
53a1d141d5Smrg
542ddb6cf1Smrg# Put in absolute file names if you don't have them in your path;
552ddb6cf1Smrg# or use environment vars.
562ddb6cf1Smrg
572ddb6cf1Smrgchgrpprog=${CHGRPPROG-chgrp}
582ddb6cf1Smrgchmodprog=${CHMODPROG-chmod}
592ddb6cf1Smrgchownprog=${CHOWNPROG-chown}
602ddb6cf1Smrgcmpprog=${CMPPROG-cmp}
612ddb6cf1Smrgcpprog=${CPPROG-cp}
622ddb6cf1Smrgmkdirprog=${MKDIRPROG-mkdir}
632ddb6cf1Smrgmvprog=${MVPROG-mv}
642ddb6cf1Smrgrmprog=${RMPROG-rm}
652ddb6cf1Smrgstripprog=${STRIPPROG-strip}
662ddb6cf1Smrg
672ddb6cf1Smrgposix_mkdir=
682ddb6cf1Smrg
692ddb6cf1Smrg# Desired mode of installed file.
702ddb6cf1Smrgmode=0755
712ddb6cf1Smrg
7226df5c7cSmrg# Create dirs (including intermediate dirs) using mode 755.
7326df5c7cSmrg# This is like GNU 'install' as of coreutils 8.32 (2020).
7426df5c7cSmrgmkdir_umask=22
7526df5c7cSmrg
7626df5c7cSmrgbackupsuffix=
772ddb6cf1Smrgchgrpcmd=
782ddb6cf1Smrgchmodcmd=$chmodprog
792ddb6cf1Smrgchowncmd=
802ddb6cf1Smrgmvcmd=$mvprog
812ddb6cf1Smrgrmcmd="$rmprog -f"
822ddb6cf1Smrgstripcmd=
83a1d141d5Smrg
842ddb6cf1Smrgsrc=
852ddb6cf1Smrgdst=
862ddb6cf1Smrgdir_arg=
872ddb6cf1Smrgdst_arg=
88a1d141d5Smrg
892ddb6cf1Smrgcopy_on_change=false
90054b3d00Smrgis_target_a_directory=possibly
91a1d141d5Smrg
922ddb6cf1Smrgusage="\
932ddb6cf1SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
942ddb6cf1Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
952ddb6cf1Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
962ddb6cf1Smrg   or: $0 [OPTION]... -d DIRECTORIES...
97a1d141d5Smrg
982ddb6cf1SmrgIn the 1st form, copy SRCFILE to DSTFILE.
992ddb6cf1SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1002ddb6cf1SmrgIn the 4th, create DIRECTORIES.
101a1d141d5Smrg
1022ddb6cf1SmrgOptions:
1032ddb6cf1Smrg     --help     display this help and exit.
1042ddb6cf1Smrg     --version  display version info and exit.
105a1d141d5Smrg
1062ddb6cf1Smrg  -c            (ignored)
10726df5c7cSmrg  -C            install only if different (preserve data modification time)
1082ddb6cf1Smrg  -d            create directories instead of installing files.
1092ddb6cf1Smrg  -g GROUP      $chgrpprog installed files to GROUP.
1102ddb6cf1Smrg  -m MODE       $chmodprog installed files to MODE.
1112ddb6cf1Smrg  -o USER       $chownprog installed files to USER.
11226df5c7cSmrg  -p            pass -p to $cpprog.
1132ddb6cf1Smrg  -s            $stripprog installed files.
11426df5c7cSmrg  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
1152ddb6cf1Smrg  -t DIRECTORY  install into DIRECTORY.
1162ddb6cf1Smrg  -T            report an error if DSTFILE is a directory.
117a1d141d5Smrg
1182ddb6cf1SmrgEnvironment variables override the default commands:
1192ddb6cf1Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1202ddb6cf1Smrg  RMPROG STRIPPROG
12126df5c7cSmrg
12226df5c7cSmrgBy default, rm is invoked with -f; when overridden with RMPROG,
12326df5c7cSmrgit's up to you to specify -f if you want it.
12426df5c7cSmrg
12526df5c7cSmrgIf -S is not specified, no backups are attempted.
12626df5c7cSmrg
12726df5c7cSmrgEmail bug reports to bug-automake@gnu.org.
12826df5c7cSmrgAutomake home page: https://www.gnu.org/software/automake/
1292ddb6cf1Smrg"
130a1d141d5Smrg
1312ddb6cf1Smrgwhile test $# -ne 0; do
1322ddb6cf1Smrg  case $1 in
1332ddb6cf1Smrg    -c) ;;
134a1d141d5Smrg
1352ddb6cf1Smrg    -C) copy_on_change=true;;
136a1d141d5Smrg
1372ddb6cf1Smrg    -d) dir_arg=true;;
138a1d141d5Smrg
1392ddb6cf1Smrg    -g) chgrpcmd="$chgrpprog $2"
140054b3d00Smrg        shift;;
141a1d141d5Smrg
1422ddb6cf1Smrg    --help) echo "$usage"; exit $?;;
143a1d141d5Smrg
1442ddb6cf1Smrg    -m) mode=$2
145054b3d00Smrg        case $mode in
146054b3d00Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
147054b3d00Smrg            echo "$0: invalid mode: $mode" >&2
148054b3d00Smrg            exit 1;;
149054b3d00Smrg        esac
150054b3d00Smrg        shift;;
151a1d141d5Smrg
1522ddb6cf1Smrg    -o) chowncmd="$chownprog $2"
153054b3d00Smrg        shift;;
154a1d141d5Smrg
15526df5c7cSmrg    -p) cpprog="$cpprog -p";;
15626df5c7cSmrg
1572ddb6cf1Smrg    -s) stripcmd=$stripprog;;
158a1d141d5Smrg
15926df5c7cSmrg    -S) backupsuffix="$2"
16026df5c7cSmrg        shift;;
16126df5c7cSmrg
162054b3d00Smrg    -t)
163054b3d00Smrg        is_target_a_directory=always
164054b3d00Smrg        dst_arg=$2
165054b3d00Smrg        # Protect names problematic for 'test' and other utilities.
166054b3d00Smrg        case $dst_arg in
167054b3d00Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
168054b3d00Smrg        esac
169054b3d00Smrg        shift;;
170a1d141d5Smrg
171054b3d00Smrg    -T) is_target_a_directory=never;;
172a1d141d5Smrg
1732ddb6cf1Smrg    --version) echo "$0 $scriptversion"; exit $?;;
174a1d141d5Smrg
175054b3d00Smrg    --) shift
176054b3d00Smrg        break;;
177a1d141d5Smrg
178054b3d00Smrg    -*) echo "$0: invalid option: $1" >&2
179054b3d00Smrg        exit 1;;
180a1d141d5Smrg
1812ddb6cf1Smrg    *)  break;;
1822ddb6cf1Smrg  esac
1832ddb6cf1Smrg  shift
1842ddb6cf1Smrgdone
185a1d141d5Smrg
186054b3d00Smrg# We allow the use of options -d and -T together, by making -d
187054b3d00Smrg# take the precedence; this is for compatibility with GNU install.
188054b3d00Smrg
189054b3d00Smrgif test -n "$dir_arg"; then
190054b3d00Smrg  if test -n "$dst_arg"; then
191054b3d00Smrg    echo "$0: target directory not allowed when installing a directory." >&2
192054b3d00Smrg    exit 1
193054b3d00Smrg  fi
194054b3d00Smrgfi
195054b3d00Smrg
1962ddb6cf1Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1972ddb6cf1Smrg  # When -d is used, all remaining arguments are directories to create.
1982ddb6cf1Smrg  # When -t is used, the destination is already specified.
1992ddb6cf1Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
2002ddb6cf1Smrg  for arg
2012ddb6cf1Smrg  do
2022ddb6cf1Smrg    if test -n "$dst_arg"; then
2032ddb6cf1Smrg      # $@ is not empty: it contains at least $arg.
2042ddb6cf1Smrg      set fnord "$@" "$dst_arg"
2052ddb6cf1Smrg      shift # fnord
2062ddb6cf1Smrg    fi
2072ddb6cf1Smrg    shift # arg
2082ddb6cf1Smrg    dst_arg=$arg
209054b3d00Smrg    # Protect names problematic for 'test' and other utilities.
210054b3d00Smrg    case $dst_arg in
211054b3d00Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
212054b3d00Smrg    esac
2132ddb6cf1Smrg  done
2142ddb6cf1Smrgfi
215a1d141d5Smrg
2162ddb6cf1Smrgif test $# -eq 0; then
2172ddb6cf1Smrg  if test -z "$dir_arg"; then
2182ddb6cf1Smrg    echo "$0: no input file specified." >&2
2192ddb6cf1Smrg    exit 1
2202ddb6cf1Smrg  fi
221054b3d00Smrg  # It's OK to call 'install-sh -d' without argument.
2222ddb6cf1Smrg  # This can happen when creating conditional directories.
2232ddb6cf1Smrg  exit 0
2242ddb6cf1Smrgfi
225a1d141d5Smrg
2262ddb6cf1Smrgif test -z "$dir_arg"; then
227054b3d00Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
228054b3d00Smrg    if test ! -d "$dst_arg"; then
229054b3d00Smrg      echo "$0: $dst_arg: Is not a directory." >&2
230054b3d00Smrg      exit 1
231054b3d00Smrg    fi
232054b3d00Smrg  fi
233054b3d00Smrgfi
234054b3d00Smrg
235054b3d00Smrgif test -z "$dir_arg"; then
236054b3d00Smrg  do_exit='(exit $ret); exit $ret'
237054b3d00Smrg  trap "ret=129; $do_exit" 1
238054b3d00Smrg  trap "ret=130; $do_exit" 2
239054b3d00Smrg  trap "ret=141; $do_exit" 13
240054b3d00Smrg  trap "ret=143; $do_exit" 15
2412ddb6cf1Smrg
2422ddb6cf1Smrg  # Set umask so as not to create temps with too-generous modes.
2432ddb6cf1Smrg  # However, 'strip' requires both read and write access to temps.
2442ddb6cf1Smrg  case $mode in
2452ddb6cf1Smrg    # Optimize common cases.
2462ddb6cf1Smrg    *644) cp_umask=133;;
2472ddb6cf1Smrg    *755) cp_umask=22;;
2482ddb6cf1Smrg
2492ddb6cf1Smrg    *[0-7])
2502ddb6cf1Smrg      if test -z "$stripcmd"; then
251054b3d00Smrg        u_plus_rw=
2522ddb6cf1Smrg      else
253054b3d00Smrg        u_plus_rw='% 200'
2542ddb6cf1Smrg      fi
2552ddb6cf1Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2562ddb6cf1Smrg    *)
2572ddb6cf1Smrg      if test -z "$stripcmd"; then
258054b3d00Smrg        u_plus_rw=
2592ddb6cf1Smrg      else
260054b3d00Smrg        u_plus_rw=,u+rw
2612ddb6cf1Smrg      fi
2622ddb6cf1Smrg      cp_umask=$mode$u_plus_rw;;
2632ddb6cf1Smrg  esac
2642ddb6cf1Smrgfi
265a1d141d5Smrg
2662ddb6cf1Smrgfor src
2672ddb6cf1Smrgdo
268054b3d00Smrg  # Protect names problematic for 'test' and other utilities.
2692ddb6cf1Smrg  case $src in
270054b3d00Smrg    -* | [=\(\)!]) src=./$src;;
2712ddb6cf1Smrg  esac
2722ddb6cf1Smrg
2732ddb6cf1Smrg  if test -n "$dir_arg"; then
2742ddb6cf1Smrg    dst=$src
2752ddb6cf1Smrg    dstdir=$dst
2762ddb6cf1Smrg    test -d "$dstdir"
2772ddb6cf1Smrg    dstdir_status=$?
27826df5c7cSmrg    # Don't chown directories that already exist.
27926df5c7cSmrg    if test $dstdir_status = 0; then
28026df5c7cSmrg      chowncmd=""
28126df5c7cSmrg    fi
2822ddb6cf1Smrg  else
2832ddb6cf1Smrg
2842ddb6cf1Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2852ddb6cf1Smrg    # might cause directories to be created, which would be especially bad
2862ddb6cf1Smrg    # if $src (and thus $dsttmp) contains '*'.
2872ddb6cf1Smrg    if test ! -f "$src" && test ! -d "$src"; then
2882ddb6cf1Smrg      echo "$0: $src does not exist." >&2
2892ddb6cf1Smrg      exit 1
2902ddb6cf1Smrg    fi
2912ddb6cf1Smrg
2922ddb6cf1Smrg    if test -z "$dst_arg"; then
2932ddb6cf1Smrg      echo "$0: no destination specified." >&2
2942ddb6cf1Smrg      exit 1
2952ddb6cf1Smrg    fi
2962ddb6cf1Smrg    dst=$dst_arg
297a1d141d5Smrg
29826df5c7cSmrg    # If destination is a directory, append the input filename.
2992ddb6cf1Smrg    if test -d "$dst"; then
300054b3d00Smrg      if test "$is_target_a_directory" = never; then
301054b3d00Smrg        echo "$0: $dst_arg: Is a directory" >&2
302054b3d00Smrg        exit 1
3032ddb6cf1Smrg      fi
3042ddb6cf1Smrg      dstdir=$dst
30526df5c7cSmrg      dstbase=`basename "$src"`
30626df5c7cSmrg      case $dst in
30726df5c7cSmrg	*/) dst=$dst$dstbase;;
30826df5c7cSmrg	*)  dst=$dst/$dstbase;;
30926df5c7cSmrg      esac
3102ddb6cf1Smrg      dstdir_status=0
3112ddb6cf1Smrg    else
312054b3d00Smrg      dstdir=`dirname "$dst"`
3132ddb6cf1Smrg      test -d "$dstdir"
3142ddb6cf1Smrg      dstdir_status=$?
3152ddb6cf1Smrg    fi
3162ddb6cf1Smrg  fi
3172ddb6cf1Smrg
31826df5c7cSmrg  case $dstdir in
31926df5c7cSmrg    */) dstdirslash=$dstdir;;
32026df5c7cSmrg    *)  dstdirslash=$dstdir/;;
32126df5c7cSmrg  esac
32226df5c7cSmrg
3232ddb6cf1Smrg  obsolete_mkdir_used=false
3242ddb6cf1Smrg
3252ddb6cf1Smrg  if test $dstdir_status != 0; then
3262ddb6cf1Smrg    case $posix_mkdir in
3272ddb6cf1Smrg      '')
328054b3d00Smrg        # With -d, create the new directory with the user-specified mode.
329054b3d00Smrg        # Otherwise, rely on $mkdir_umask.
330054b3d00Smrg        if test -n "$dir_arg"; then
331054b3d00Smrg          mkdir_mode=-m$mode
332054b3d00Smrg        else
333054b3d00Smrg          mkdir_mode=
334054b3d00Smrg        fi
335054b3d00Smrg
336054b3d00Smrg        posix_mkdir=false
33726df5c7cSmrg	# The $RANDOM variable is not portable (e.g., dash).  Use it
33826df5c7cSmrg	# here however when possible just to lower collision chance.
33926df5c7cSmrg	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34026df5c7cSmrg
34126df5c7cSmrg	trap '
34226df5c7cSmrg	  ret=$?
34326df5c7cSmrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
34426df5c7cSmrg	  exit $ret
34526df5c7cSmrg	' 0
34626df5c7cSmrg
34726df5c7cSmrg	# Because "mkdir -p" follows existing symlinks and we likely work
34826df5c7cSmrg	# directly in world-writeable /tmp, make sure that the '$tmpdir'
34926df5c7cSmrg	# directory is successfully created first before we actually test
35026df5c7cSmrg	# 'mkdir -p'.
35126df5c7cSmrg	if (umask $mkdir_umask &&
35226df5c7cSmrg	    $mkdirprog $mkdir_mode "$tmpdir" &&
35326df5c7cSmrg	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
35426df5c7cSmrg	then
35526df5c7cSmrg	  if test -z "$dir_arg" || {
35626df5c7cSmrg	       # Check for POSIX incompatibilities with -m.
35726df5c7cSmrg	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35826df5c7cSmrg	       # other-writable bit of parent directory when it shouldn't.
35926df5c7cSmrg	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
36026df5c7cSmrg	       test_tmpdir="$tmpdir/a"
36126df5c7cSmrg	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
36226df5c7cSmrg	       case $ls_ld_tmpdir in
36326df5c7cSmrg		 d????-?r-*) different_mode=700;;
36426df5c7cSmrg		 d????-?--*) different_mode=755;;
36526df5c7cSmrg		 *) false;;
36626df5c7cSmrg	       esac &&
36726df5c7cSmrg	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
36826df5c7cSmrg		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
36926df5c7cSmrg		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
37026df5c7cSmrg	       }
37126df5c7cSmrg	     }
37226df5c7cSmrg	  then posix_mkdir=:
37326df5c7cSmrg	  fi
37426df5c7cSmrg	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
37526df5c7cSmrg	else
37626df5c7cSmrg	  # Remove any dirs left behind by ancient mkdir implementations.
37726df5c7cSmrg	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
37826df5c7cSmrg	fi
37926df5c7cSmrg	trap '' 0;;
3802ddb6cf1Smrg    esac
381a1d141d5Smrg
3822ddb6cf1Smrg    if
3832ddb6cf1Smrg      $posix_mkdir && (
384054b3d00Smrg        umask $mkdir_umask &&
385054b3d00Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3862ddb6cf1Smrg      )
3872ddb6cf1Smrg    then :
3882ddb6cf1Smrg    else
3892ddb6cf1Smrg
39026df5c7cSmrg      # mkdir does not conform to POSIX,
3912ddb6cf1Smrg      # or it failed possibly due to a race condition.  Create the
3922ddb6cf1Smrg      # directory the slow way, step by step, checking for races as we go.
3932ddb6cf1Smrg
3942ddb6cf1Smrg      case $dstdir in
395054b3d00Smrg        /*) prefix='/';;
396054b3d00Smrg        [-=\(\)!]*) prefix='./';;
397054b3d00Smrg        *)  prefix='';;
3982ddb6cf1Smrg      esac
3992ddb6cf1Smrg
4002ddb6cf1Smrg      oIFS=$IFS
4012ddb6cf1Smrg      IFS=/
402054b3d00Smrg      set -f
4032ddb6cf1Smrg      set fnord $dstdir
4042ddb6cf1Smrg      shift
405054b3d00Smrg      set +f
4062ddb6cf1Smrg      IFS=$oIFS
4072ddb6cf1Smrg
4082ddb6cf1Smrg      prefixes=
4092ddb6cf1Smrg
4102ddb6cf1Smrg      for d
4112ddb6cf1Smrg      do
412054b3d00Smrg        test X"$d" = X && continue
413054b3d00Smrg
414054b3d00Smrg        prefix=$prefix$d
415054b3d00Smrg        if test -d "$prefix"; then
416054b3d00Smrg          prefixes=
417054b3d00Smrg        else
418054b3d00Smrg          if $posix_mkdir; then
41926df5c7cSmrg            (umask $mkdir_umask &&
420054b3d00Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
421054b3d00Smrg            # Don't fail if two instances are running concurrently.
422054b3d00Smrg            test -d "$prefix" || exit 1
423054b3d00Smrg          else
424054b3d00Smrg            case $prefix in
425054b3d00Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
426054b3d00Smrg              *) qprefix=$prefix;;
427054b3d00Smrg            esac
428054b3d00Smrg            prefixes="$prefixes '$qprefix'"
429054b3d00Smrg          fi
430054b3d00Smrg        fi
431054b3d00Smrg        prefix=$prefix/
4322ddb6cf1Smrg      done
4332ddb6cf1Smrg
4342ddb6cf1Smrg      if test -n "$prefixes"; then
435054b3d00Smrg        # Don't fail if two instances are running concurrently.
436054b3d00Smrg        (umask $mkdir_umask &&
437054b3d00Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
438054b3d00Smrg          test -d "$dstdir" || exit 1
439054b3d00Smrg        obsolete_mkdir_used=true
4402ddb6cf1Smrg      fi
4412ddb6cf1Smrg    fi
4422ddb6cf1Smrg  fi
4432ddb6cf1Smrg
4442ddb6cf1Smrg  if test -n "$dir_arg"; then
4452ddb6cf1Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4462ddb6cf1Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4472ddb6cf1Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4482ddb6cf1Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4492ddb6cf1Smrg  else
4502ddb6cf1Smrg
4512ddb6cf1Smrg    # Make a couple of temp file names in the proper directory.
45226df5c7cSmrg    dsttmp=${dstdirslash}_inst.$$_
45326df5c7cSmrg    rmtmp=${dstdirslash}_rm.$$_
4542ddb6cf1Smrg
4552ddb6cf1Smrg    # Trap to clean up those temp files at exit.
4562ddb6cf1Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4572ddb6cf1Smrg
4582ddb6cf1Smrg    # Copy the file name to the temp name.
45926df5c7cSmrg    (umask $cp_umask &&
46026df5c7cSmrg     { test -z "$stripcmd" || {
46126df5c7cSmrg	 # Create $dsttmp read-write so that cp doesn't create it read-only,
46226df5c7cSmrg	 # which would cause strip to fail.
46326df5c7cSmrg	 if test -z "$doit"; then
46426df5c7cSmrg	   : >"$dsttmp" # No need to fork-exec 'touch'.
46526df5c7cSmrg	 else
46626df5c7cSmrg	   $doit touch "$dsttmp"
46726df5c7cSmrg	 fi
46826df5c7cSmrg       }
46926df5c7cSmrg     } &&
47026df5c7cSmrg     $doit_exec $cpprog "$src" "$dsttmp") &&
4712ddb6cf1Smrg
4722ddb6cf1Smrg    # and set any options; do chmod last to preserve setuid bits.
4732ddb6cf1Smrg    #
4742ddb6cf1Smrg    # If any of these fail, we abort the whole thing.  If we want to
4752ddb6cf1Smrg    # ignore errors from any of these, just make sure not to ignore
4762ddb6cf1Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4772ddb6cf1Smrg    #
4782ddb6cf1Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4792ddb6cf1Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4802ddb6cf1Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4812ddb6cf1Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4822ddb6cf1Smrg
4832ddb6cf1Smrg    # If -C, don't bother to copy if it wouldn't change the file.
4842ddb6cf1Smrg    if $copy_on_change &&
485054b3d00Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
486054b3d00Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
487054b3d00Smrg       set -f &&
4882ddb6cf1Smrg       set X $old && old=:$2:$4:$5:$6 &&
4892ddb6cf1Smrg       set X $new && new=:$2:$4:$5:$6 &&
490054b3d00Smrg       set +f &&
4912ddb6cf1Smrg       test "$old" = "$new" &&
4922ddb6cf1Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4932ddb6cf1Smrg    then
4942ddb6cf1Smrg      rm -f "$dsttmp"
4952ddb6cf1Smrg    else
49626df5c7cSmrg      # If $backupsuffix is set, and the file being installed
49726df5c7cSmrg      # already exists, attempt a backup.  Don't worry if it fails,
49826df5c7cSmrg      # e.g., if mv doesn't support -f.
49926df5c7cSmrg      if test -n "$backupsuffix" && test -f "$dst"; then
50026df5c7cSmrg        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
50126df5c7cSmrg      fi
50226df5c7cSmrg
5032ddb6cf1Smrg      # Rename the file to the real destination.
5042ddb6cf1Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
5052ddb6cf1Smrg
5062ddb6cf1Smrg      # The rename failed, perhaps because mv can't rename something else
5072ddb6cf1Smrg      # to itself, or perhaps because mv is so ancient that it does not
5082ddb6cf1Smrg      # support -f.
5092ddb6cf1Smrg      {
510054b3d00Smrg        # Now remove or move aside any old file at destination location.
511054b3d00Smrg        # We try this two ways since rm can't unlink itself on some
512054b3d00Smrg        # systems and the destination file might be busy for other
513054b3d00Smrg        # reasons.  In this case, the final cleanup might fail but the new
514054b3d00Smrg        # file should still install successfully.
515054b3d00Smrg        {
516054b3d00Smrg          test ! -f "$dst" ||
51726df5c7cSmrg          $doit $rmcmd "$dst" 2>/dev/null ||
518054b3d00Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
51926df5c7cSmrg            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
520054b3d00Smrg          } ||
521054b3d00Smrg          { echo "$0: cannot unlink or rename $dst" >&2
522054b3d00Smrg            (exit 1); exit 1
523054b3d00Smrg          }
524054b3d00Smrg        } &&
525054b3d00Smrg
526054b3d00Smrg        # Now rename the file to the real destination.
527054b3d00Smrg        $doit $mvcmd "$dsttmp" "$dst"
5282ddb6cf1Smrg      }
5292ddb6cf1Smrg    fi || exit 1
5302ddb6cf1Smrg
5312ddb6cf1Smrg    trap '' 0
5322ddb6cf1Smrg  fi
5332ddb6cf1Smrgdone
534a1d141d5Smrg
5352ddb6cf1Smrg# Local variables:
53626df5c7cSmrg# eval: (add-hook 'before-save-hook 'time-stamp)
5372ddb6cf1Smrg# time-stamp-start: "scriptversion="
5382ddb6cf1Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
53926df5c7cSmrg# time-stamp-time-zone: "UTC0"
5402ddb6cf1Smrg# time-stamp-end: "; # UTC"
5412ddb6cf1Smrg# End:
542