install-sh revision 765486e8
17d5e3a19Smrg#!/bin/sh
27d5e3a19Smrg# install - install a program, script, or datafile
37d5e3a19Smrg
4765486e8Smrgscriptversion=2009-04-28.21; # UTC
57d5e3a19Smrg
67d5e3a19Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
77d5e3a19Smrg# later released in X11R6 (xc/config/util/install.sh) with the
87d5e3a19Smrg# following copyright and license.
97d5e3a19Smrg#
107d5e3a19Smrg# Copyright (C) 1994 X Consortium
117d5e3a19Smrg#
127d5e3a19Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
137d5e3a19Smrg# of this software and associated documentation files (the "Software"), to
147d5e3a19Smrg# deal in the Software without restriction, including without limitation the
157d5e3a19Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
167d5e3a19Smrg# sell copies of the Software, and to permit persons to whom the Software is
177d5e3a19Smrg# furnished to do so, subject to the following conditions:
187d5e3a19Smrg#
197d5e3a19Smrg# The above copyright notice and this permission notice shall be included in
207d5e3a19Smrg# all copies or substantial portions of the Software.
217d5e3a19Smrg#
227d5e3a19Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
237d5e3a19Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
247d5e3a19Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
257d5e3a19Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
267d5e3a19Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
277d5e3a19Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
287d5e3a19Smrg#
297d5e3a19Smrg# Except as contained in this notice, the name of the X Consortium shall not
307d5e3a19Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
317d5e3a19Smrg# ings in this Software without prior written authorization from the X Consor-
327d5e3a19Smrg# tium.
337d5e3a19Smrg#
347d5e3a19Smrg#
357d5e3a19Smrg# FSF changes to this file are in the public domain.
367d5e3a19Smrg#
377d5e3a19Smrg# Calling this script install-sh is preferred over install.sh, to prevent
387d5e3a19Smrg# `make' implicit rules from creating a file called install from it
397d5e3a19Smrg# when there is no Makefile.
407d5e3a19Smrg#
417d5e3a19Smrg# This script is compatible with the BSD install script, but was written
427d5e3a19Smrg# from scratch.
437d5e3a19Smrg
447d5e3a19Smrgnl='
457d5e3a19Smrg'
467d5e3a19SmrgIFS=" ""	$nl"
477d5e3a19Smrg
487d5e3a19Smrg# set DOITPROG to echo to test this script
497d5e3a19Smrg
507d5e3a19Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
511568b75bSmrgdoit=${DOITPROG-}
527d5e3a19Smrgif test -z "$doit"; then
537d5e3a19Smrg  doit_exec=exec
547d5e3a19Smrgelse
557d5e3a19Smrg  doit_exec=$doit
567d5e3a19Smrgfi
577d5e3a19Smrg
587d5e3a19Smrg# Put in absolute file names if you don't have them in your path;
597d5e3a19Smrg# or use environment vars.
607d5e3a19Smrg
611568b75bSmrgchgrpprog=${CHGRPPROG-chgrp}
621568b75bSmrgchmodprog=${CHMODPROG-chmod}
631568b75bSmrgchownprog=${CHOWNPROG-chown}
641568b75bSmrgcmpprog=${CMPPROG-cmp}
651568b75bSmrgcpprog=${CPPROG-cp}
661568b75bSmrgmkdirprog=${MKDIRPROG-mkdir}
671568b75bSmrgmvprog=${MVPROG-mv}
681568b75bSmrgrmprog=${RMPROG-rm}
691568b75bSmrgstripprog=${STRIPPROG-strip}
701568b75bSmrg
711568b75bSmrgposix_glob='?'
721568b75bSmrginitialize_posix_glob='
731568b75bSmrg  test "$posix_glob" != "?" || {
741568b75bSmrg    if (set -f) 2>/dev/null; then
751568b75bSmrg      posix_glob=
761568b75bSmrg    else
771568b75bSmrg      posix_glob=:
781568b75bSmrg    fi
791568b75bSmrg  }
801568b75bSmrg'
817d5e3a19Smrg
827d5e3a19Smrgposix_mkdir=
837d5e3a19Smrg
847d5e3a19Smrg# Desired mode of installed file.
857d5e3a19Smrgmode=0755
867d5e3a19Smrg
871568b75bSmrgchgrpcmd=
887d5e3a19Smrgchmodcmd=$chmodprog
897d5e3a19Smrgchowncmd=
901568b75bSmrgmvcmd=$mvprog
917d5e3a19Smrgrmcmd="$rmprog -f"
921568b75bSmrgstripcmd=
931568b75bSmrg
947d5e3a19Smrgsrc=
957d5e3a19Smrgdst=
967d5e3a19Smrgdir_arg=
971568b75bSmrgdst_arg=
981568b75bSmrg
991568b75bSmrgcopy_on_change=false
1007d5e3a19Smrgno_target_directory=
1017d5e3a19Smrg
1021568b75bSmrgusage="\
1031568b75bSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
1047d5e3a19Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
1057d5e3a19Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
1067d5e3a19Smrg   or: $0 [OPTION]... -d DIRECTORIES...
1077d5e3a19Smrg
1087d5e3a19SmrgIn the 1st form, copy SRCFILE to DSTFILE.
1097d5e3a19SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1107d5e3a19SmrgIn the 4th, create DIRECTORIES.
1117d5e3a19Smrg
1127d5e3a19SmrgOptions:
1131568b75bSmrg     --help     display this help and exit.
1141568b75bSmrg     --version  display version info and exit.
1151568b75bSmrg
1161568b75bSmrg  -c            (ignored)
1171568b75bSmrg  -C            install only if different (preserve the last data modification time)
1181568b75bSmrg  -d            create directories instead of installing files.
1191568b75bSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1201568b75bSmrg  -m MODE       $chmodprog installed files to MODE.
1211568b75bSmrg  -o USER       $chownprog installed files to USER.
1221568b75bSmrg  -s            $stripprog installed files.
1231568b75bSmrg  -t DIRECTORY  install into DIRECTORY.
1241568b75bSmrg  -T            report an error if DSTFILE is a directory.
1257d5e3a19Smrg
1267d5e3a19SmrgEnvironment variables override the default commands:
1271568b75bSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1281568b75bSmrg  RMPROG STRIPPROG
1297d5e3a19Smrg"
1307d5e3a19Smrg
1317d5e3a19Smrgwhile test $# -ne 0; do
1327d5e3a19Smrg  case $1 in
1331568b75bSmrg    -c) ;;
1341568b75bSmrg
1351568b75bSmrg    -C) copy_on_change=true;;
1367d5e3a19Smrg
1371568b75bSmrg    -d) dir_arg=true;;
1387d5e3a19Smrg
1397d5e3a19Smrg    -g) chgrpcmd="$chgrpprog $2"
1401568b75bSmrg	shift;;
1417d5e3a19Smrg
1427d5e3a19Smrg    --help) echo "$usage"; exit $?;;
1437d5e3a19Smrg
1447d5e3a19Smrg    -m) mode=$2
1457d5e3a19Smrg	case $mode in
1467d5e3a19Smrg	  *' '* | *'	'* | *'
1477d5e3a19Smrg'*	  | *'*'* | *'?'* | *'['*)
1487d5e3a19Smrg	    echo "$0: invalid mode: $mode" >&2
1497d5e3a19Smrg	    exit 1;;
1507d5e3a19Smrg	esac
1511568b75bSmrg	shift;;
1527d5e3a19Smrg
1537d5e3a19Smrg    -o) chowncmd="$chownprog $2"
1541568b75bSmrg	shift;;
1557d5e3a19Smrg
1561568b75bSmrg    -s) stripcmd=$stripprog;;
1577d5e3a19Smrg
1581568b75bSmrg    -t) dst_arg=$2
1591568b75bSmrg	shift;;
1607d5e3a19Smrg
1611568b75bSmrg    -T) no_target_directory=true;;
1627d5e3a19Smrg
1637d5e3a19Smrg    --version) echo "$0 $scriptversion"; exit $?;;
1647d5e3a19Smrg
1657d5e3a19Smrg    --)	shift
1667d5e3a19Smrg	break;;
1677d5e3a19Smrg
1687d5e3a19Smrg    -*)	echo "$0: invalid option: $1" >&2
1697d5e3a19Smrg	exit 1;;
1707d5e3a19Smrg
1717d5e3a19Smrg    *)  break;;
1727d5e3a19Smrg  esac
1731568b75bSmrg  shift
1747d5e3a19Smrgdone
1757d5e3a19Smrg
1761568b75bSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1777d5e3a19Smrg  # When -d is used, all remaining arguments are directories to create.
1787d5e3a19Smrg  # When -t is used, the destination is already specified.
1797d5e3a19Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1807d5e3a19Smrg  for arg
1817d5e3a19Smrg  do
1821568b75bSmrg    if test -n "$dst_arg"; then
1837d5e3a19Smrg      # $@ is not empty: it contains at least $arg.
1841568b75bSmrg      set fnord "$@" "$dst_arg"
1857d5e3a19Smrg      shift # fnord
1867d5e3a19Smrg    fi
1877d5e3a19Smrg    shift # arg
1881568b75bSmrg    dst_arg=$arg
1897d5e3a19Smrg  done
1907d5e3a19Smrgfi
1917d5e3a19Smrg
1927d5e3a19Smrgif test $# -eq 0; then
1937d5e3a19Smrg  if test -z "$dir_arg"; then
1947d5e3a19Smrg    echo "$0: no input file specified." >&2
1957d5e3a19Smrg    exit 1
1967d5e3a19Smrg  fi
1977d5e3a19Smrg  # It's OK to call `install-sh -d' without argument.
1987d5e3a19Smrg  # This can happen when creating conditional directories.
1997d5e3a19Smrg  exit 0
2007d5e3a19Smrgfi
2017d5e3a19Smrg
2027d5e3a19Smrgif test -z "$dir_arg"; then
2037d5e3a19Smrg  trap '(exit $?); exit' 1 2 13 15
2047d5e3a19Smrg
2057d5e3a19Smrg  # Set umask so as not to create temps with too-generous modes.
2067d5e3a19Smrg  # However, 'strip' requires both read and write access to temps.
2077d5e3a19Smrg  case $mode in
2087d5e3a19Smrg    # Optimize common cases.
2097d5e3a19Smrg    *644) cp_umask=133;;
2107d5e3a19Smrg    *755) cp_umask=22;;
2117d5e3a19Smrg
2127d5e3a19Smrg    *[0-7])
2137d5e3a19Smrg      if test -z "$stripcmd"; then
2147d5e3a19Smrg	u_plus_rw=
2157d5e3a19Smrg      else
2167d5e3a19Smrg	u_plus_rw='% 200'
2177d5e3a19Smrg      fi
2187d5e3a19Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2197d5e3a19Smrg    *)
2207d5e3a19Smrg      if test -z "$stripcmd"; then
2217d5e3a19Smrg	u_plus_rw=
2227d5e3a19Smrg      else
2237d5e3a19Smrg	u_plus_rw=,u+rw
2247d5e3a19Smrg      fi
2257d5e3a19Smrg      cp_umask=$mode$u_plus_rw;;
2267d5e3a19Smrg  esac
2277d5e3a19Smrgfi
2287d5e3a19Smrg
2297d5e3a19Smrgfor src
2307d5e3a19Smrgdo
2317d5e3a19Smrg  # Protect names starting with `-'.
2327d5e3a19Smrg  case $src in
2331568b75bSmrg    -*) src=./$src;;
2347d5e3a19Smrg  esac
2357d5e3a19Smrg
2367d5e3a19Smrg  if test -n "$dir_arg"; then
2377d5e3a19Smrg    dst=$src
2387d5e3a19Smrg    dstdir=$dst
2397d5e3a19Smrg    test -d "$dstdir"
2407d5e3a19Smrg    dstdir_status=$?
2417d5e3a19Smrg  else
2427d5e3a19Smrg
2437d5e3a19Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2447d5e3a19Smrg    # might cause directories to be created, which would be especially bad
2457d5e3a19Smrg    # if $src (and thus $dsttmp) contains '*'.
2467d5e3a19Smrg    if test ! -f "$src" && test ! -d "$src"; then
2477d5e3a19Smrg      echo "$0: $src does not exist." >&2
2487d5e3a19Smrg      exit 1
2497d5e3a19Smrg    fi
2507d5e3a19Smrg
2511568b75bSmrg    if test -z "$dst_arg"; then
2527d5e3a19Smrg      echo "$0: no destination specified." >&2
2537d5e3a19Smrg      exit 1
2547d5e3a19Smrg    fi
2557d5e3a19Smrg
2561568b75bSmrg    dst=$dst_arg
2577d5e3a19Smrg    # Protect names starting with `-'.
2587d5e3a19Smrg    case $dst in
2591568b75bSmrg      -*) dst=./$dst;;
2607d5e3a19Smrg    esac
2617d5e3a19Smrg
2627d5e3a19Smrg    # If destination is a directory, append the input filename; won't work
2637d5e3a19Smrg    # if double slashes aren't ignored.
2647d5e3a19Smrg    if test -d "$dst"; then
2657d5e3a19Smrg      if test -n "$no_target_directory"; then
2661568b75bSmrg	echo "$0: $dst_arg: Is a directory" >&2
2677d5e3a19Smrg	exit 1
2687d5e3a19Smrg      fi
2697d5e3a19Smrg      dstdir=$dst
2707d5e3a19Smrg      dst=$dstdir/`basename "$src"`
2717d5e3a19Smrg      dstdir_status=0
2727d5e3a19Smrg    else
2737d5e3a19Smrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2747d5e3a19Smrg      dstdir=`
2757d5e3a19Smrg	(dirname "$dst") 2>/dev/null ||
2767d5e3a19Smrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2777d5e3a19Smrg	     X"$dst" : 'X\(//\)[^/]' \| \
2787d5e3a19Smrg	     X"$dst" : 'X\(//\)$' \| \
2797d5e3a19Smrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2807d5e3a19Smrg	echo X"$dst" |
2817d5e3a19Smrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2827d5e3a19Smrg		   s//\1/
2837d5e3a19Smrg		   q
2847d5e3a19Smrg		 }
2857d5e3a19Smrg		 /^X\(\/\/\)[^/].*/{
2867d5e3a19Smrg		   s//\1/
2877d5e3a19Smrg		   q
2887d5e3a19Smrg		 }
2897d5e3a19Smrg		 /^X\(\/\/\)$/{
2907d5e3a19Smrg		   s//\1/
2917d5e3a19Smrg		   q
2927d5e3a19Smrg		 }
2937d5e3a19Smrg		 /^X\(\/\).*/{
2947d5e3a19Smrg		   s//\1/
2957d5e3a19Smrg		   q
2967d5e3a19Smrg		 }
2977d5e3a19Smrg		 s/.*/./; q'
2987d5e3a19Smrg      `
2997d5e3a19Smrg
3007d5e3a19Smrg      test -d "$dstdir"
3017d5e3a19Smrg      dstdir_status=$?
3027d5e3a19Smrg    fi
3037d5e3a19Smrg  fi
3047d5e3a19Smrg
3057d5e3a19Smrg  obsolete_mkdir_used=false
3067d5e3a19Smrg
3077d5e3a19Smrg  if test $dstdir_status != 0; then
3087d5e3a19Smrg    case $posix_mkdir in
3097d5e3a19Smrg      '')
3107d5e3a19Smrg	# Create intermediate dirs using mode 755 as modified by the umask.
3117d5e3a19Smrg	# This is like FreeBSD 'install' as of 1997-10-28.
3127d5e3a19Smrg	umask=`umask`
3137d5e3a19Smrg	case $stripcmd.$umask in
3147d5e3a19Smrg	  # Optimize common cases.
3157d5e3a19Smrg	  *[2367][2367]) mkdir_umask=$umask;;
3167d5e3a19Smrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3177d5e3a19Smrg
3187d5e3a19Smrg	  *[0-7])
3197d5e3a19Smrg	    mkdir_umask=`expr $umask + 22 \
3207d5e3a19Smrg	      - $umask % 100 % 40 + $umask % 20 \
3217d5e3a19Smrg	      - $umask % 10 % 4 + $umask % 2
3227d5e3a19Smrg	    `;;
3237d5e3a19Smrg	  *) mkdir_umask=$umask,go-w;;
3247d5e3a19Smrg	esac
3257d5e3a19Smrg
3267d5e3a19Smrg	# With -d, create the new directory with the user-specified mode.
3277d5e3a19Smrg	# Otherwise, rely on $mkdir_umask.
3287d5e3a19Smrg	if test -n "$dir_arg"; then
3297d5e3a19Smrg	  mkdir_mode=-m$mode
3307d5e3a19Smrg	else
3317d5e3a19Smrg	  mkdir_mode=
3327d5e3a19Smrg	fi
3337d5e3a19Smrg
3347d5e3a19Smrg	posix_mkdir=false
3357d5e3a19Smrg	case $umask in
3367d5e3a19Smrg	  *[123567][0-7][0-7])
3377d5e3a19Smrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3387d5e3a19Smrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3397d5e3a19Smrg	    ;;
3407d5e3a19Smrg	  *)
3417d5e3a19Smrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3427d5e3a19Smrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3437d5e3a19Smrg
3447d5e3a19Smrg	    if (umask $mkdir_umask &&
3457d5e3a19Smrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3467d5e3a19Smrg	    then
3477d5e3a19Smrg	      if test -z "$dir_arg" || {
3487d5e3a19Smrg		   # Check for POSIX incompatibilities with -m.
3497d5e3a19Smrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3507d5e3a19Smrg		   # other-writeable bit of parent directory when it shouldn't.
3517d5e3a19Smrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3527d5e3a19Smrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3537d5e3a19Smrg		   case $ls_ld_tmpdir in
3547d5e3a19Smrg		     d????-?r-*) different_mode=700;;
3557d5e3a19Smrg		     d????-?--*) different_mode=755;;
3567d5e3a19Smrg		     *) false;;
3577d5e3a19Smrg		   esac &&
3587d5e3a19Smrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3597d5e3a19Smrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3607d5e3a19Smrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3617d5e3a19Smrg		   }
3627d5e3a19Smrg		 }
3637d5e3a19Smrg	      then posix_mkdir=:
3647d5e3a19Smrg	      fi
3657d5e3a19Smrg	      rmdir "$tmpdir/d" "$tmpdir"
3667d5e3a19Smrg	    else
3677d5e3a19Smrg	      # Remove any dirs left behind by ancient mkdir implementations.
3687d5e3a19Smrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3697d5e3a19Smrg	    fi
3707d5e3a19Smrg	    trap '' 0;;
3717d5e3a19Smrg	esac;;
3727d5e3a19Smrg    esac
3737d5e3a19Smrg
3747d5e3a19Smrg    if
3757d5e3a19Smrg      $posix_mkdir && (
3767d5e3a19Smrg	umask $mkdir_umask &&
3777d5e3a19Smrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3787d5e3a19Smrg      )
3797d5e3a19Smrg    then :
3807d5e3a19Smrg    else
3817d5e3a19Smrg
3827d5e3a19Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3837d5e3a19Smrg      # or it failed possibly due to a race condition.  Create the
3847d5e3a19Smrg      # directory the slow way, step by step, checking for races as we go.
3857d5e3a19Smrg
3867d5e3a19Smrg      case $dstdir in
3871568b75bSmrg	/*) prefix='/';;
3881568b75bSmrg	-*) prefix='./';;
3891568b75bSmrg	*)  prefix='';;
3907d5e3a19Smrg      esac
3917d5e3a19Smrg
3921568b75bSmrg      eval "$initialize_posix_glob"
3937d5e3a19Smrg
3947d5e3a19Smrg      oIFS=$IFS
3957d5e3a19Smrg      IFS=/
3961568b75bSmrg      $posix_glob set -f
3977d5e3a19Smrg      set fnord $dstdir
3987d5e3a19Smrg      shift
3991568b75bSmrg      $posix_glob set +f
4007d5e3a19Smrg      IFS=$oIFS
4017d5e3a19Smrg
4027d5e3a19Smrg      prefixes=
4037d5e3a19Smrg
4047d5e3a19Smrg      for d
4057d5e3a19Smrg      do
4067d5e3a19Smrg	test -z "$d" && continue
4077d5e3a19Smrg
4087d5e3a19Smrg	prefix=$prefix$d
4097d5e3a19Smrg	if test -d "$prefix"; then
4107d5e3a19Smrg	  prefixes=
4117d5e3a19Smrg	else
4127d5e3a19Smrg	  if $posix_mkdir; then
4137d5e3a19Smrg	    (umask=$mkdir_umask &&
4147d5e3a19Smrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4157d5e3a19Smrg	    # Don't fail if two instances are running concurrently.
4167d5e3a19Smrg	    test -d "$prefix" || exit 1
4177d5e3a19Smrg	  else
4187d5e3a19Smrg	    case $prefix in
4197d5e3a19Smrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4207d5e3a19Smrg	      *) qprefix=$prefix;;
4217d5e3a19Smrg	    esac
4227d5e3a19Smrg	    prefixes="$prefixes '$qprefix'"
4237d5e3a19Smrg	  fi
4247d5e3a19Smrg	fi
4257d5e3a19Smrg	prefix=$prefix/
4267d5e3a19Smrg      done
4277d5e3a19Smrg
4287d5e3a19Smrg      if test -n "$prefixes"; then
4297d5e3a19Smrg	# Don't fail if two instances are running concurrently.
4307d5e3a19Smrg	(umask $mkdir_umask &&
4317d5e3a19Smrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4327d5e3a19Smrg	  test -d "$dstdir" || exit 1
4337d5e3a19Smrg	obsolete_mkdir_used=true
4347d5e3a19Smrg      fi
4357d5e3a19Smrg    fi
4367d5e3a19Smrg  fi
4377d5e3a19Smrg
4387d5e3a19Smrg  if test -n "$dir_arg"; then
4397d5e3a19Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4407d5e3a19Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4417d5e3a19Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4427d5e3a19Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4437d5e3a19Smrg  else
4447d5e3a19Smrg
4457d5e3a19Smrg    # Make a couple of temp file names in the proper directory.
4467d5e3a19Smrg    dsttmp=$dstdir/_inst.$$_
4477d5e3a19Smrg    rmtmp=$dstdir/_rm.$$_
4487d5e3a19Smrg
4497d5e3a19Smrg    # Trap to clean up those temp files at exit.
4507d5e3a19Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4517d5e3a19Smrg
4527d5e3a19Smrg    # Copy the file name to the temp name.
4537d5e3a19Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4547d5e3a19Smrg
4557d5e3a19Smrg    # and set any options; do chmod last to preserve setuid bits.
4567d5e3a19Smrg    #
4577d5e3a19Smrg    # If any of these fail, we abort the whole thing.  If we want to
4587d5e3a19Smrg    # ignore errors from any of these, just make sure not to ignore
4597d5e3a19Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4607d5e3a19Smrg    #
4611568b75bSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4621568b75bSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4631568b75bSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4641568b75bSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4651568b75bSmrg
4661568b75bSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4671568b75bSmrg    if $copy_on_change &&
4681568b75bSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
4691568b75bSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
4701568b75bSmrg
4711568b75bSmrg       eval "$initialize_posix_glob" &&
4721568b75bSmrg       $posix_glob set -f &&
4731568b75bSmrg       set X $old && old=:$2:$4:$5:$6 &&
4741568b75bSmrg       set X $new && new=:$2:$4:$5:$6 &&
4751568b75bSmrg       $posix_glob set +f &&
4761568b75bSmrg
4771568b75bSmrg       test "$old" = "$new" &&
4781568b75bSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4791568b75bSmrg    then
4801568b75bSmrg      rm -f "$dsttmp"
4811568b75bSmrg    else
4821568b75bSmrg      # Rename the file to the real destination.
4831568b75bSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4841568b75bSmrg
4851568b75bSmrg      # The rename failed, perhaps because mv can't rename something else
4861568b75bSmrg      # to itself, or perhaps because mv is so ancient that it does not
4871568b75bSmrg      # support -f.
4881568b75bSmrg      {
4891568b75bSmrg	# Now remove or move aside any old file at destination location.
4901568b75bSmrg	# We try this two ways since rm can't unlink itself on some
4911568b75bSmrg	# systems and the destination file might be busy for other
4921568b75bSmrg	# reasons.  In this case, the final cleanup might fail but the new
4931568b75bSmrg	# file should still install successfully.
4941568b75bSmrg	{
4951568b75bSmrg	  test ! -f "$dst" ||
4961568b75bSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
4971568b75bSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4981568b75bSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4991568b75bSmrg	  } ||
5001568b75bSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
5011568b75bSmrg	    (exit 1); exit 1
5021568b75bSmrg	  }
5031568b75bSmrg	} &&
5041568b75bSmrg
5051568b75bSmrg	# Now rename the file to the real destination.
5061568b75bSmrg	$doit $mvcmd "$dsttmp" "$dst"
5071568b75bSmrg      }
5081568b75bSmrg    fi || exit 1
5097d5e3a19Smrg
5107d5e3a19Smrg    trap '' 0
5117d5e3a19Smrg  fi
5127d5e3a19Smrgdone
5137d5e3a19Smrg
5147d5e3a19Smrg# Local variables:
5157d5e3a19Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
5167d5e3a19Smrg# time-stamp-start: "scriptversion="
5177d5e3a19Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
518765486e8Smrg# time-stamp-time-zone: "UTC"
519765486e8Smrg# time-stamp-end: "; # UTC"
5207d5e3a19Smrg# End:
521