install-sh revision 7e4fd55a
1b8f75c19Smrg#!/bin/sh
2b8f75c19Smrg# install - install a program, script, or datafile
37e4fd55aSmrg
47e4fd55aSmrgscriptversion=2009-04-28.21; # UTC
57e4fd55aSmrg
6b8f75c19Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7b8f75c19Smrg# later released in X11R6 (xc/config/util/install.sh) with the
8b8f75c19Smrg# following copyright and license.
9b8f75c19Smrg#
10b8f75c19Smrg# Copyright (C) 1994 X Consortium
11b8f75c19Smrg#
12b8f75c19Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13b8f75c19Smrg# of this software and associated documentation files (the "Software"), to
14b8f75c19Smrg# deal in the Software without restriction, including without limitation the
15b8f75c19Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16b8f75c19Smrg# sell copies of the Software, and to permit persons to whom the Software is
17b8f75c19Smrg# furnished to do so, subject to the following conditions:
18b8f75c19Smrg#
19b8f75c19Smrg# The above copyright notice and this permission notice shall be included in
20b8f75c19Smrg# all copies or substantial portions of the Software.
21b8f75c19Smrg#
22b8f75c19Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23b8f75c19Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24b8f75c19Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25b8f75c19Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26b8f75c19Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27b8f75c19Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28b8f75c19Smrg#
29b8f75c19Smrg# Except as contained in this notice, the name of the X Consortium shall not
30b8f75c19Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
31b8f75c19Smrg# ings in this Software without prior written authorization from the X Consor-
32b8f75c19Smrg# tium.
33b8f75c19Smrg#
34b8f75c19Smrg#
35b8f75c19Smrg# FSF changes to this file are in the public domain.
36b8f75c19Smrg#
37b8f75c19Smrg# Calling this script install-sh is preferred over install.sh, to prevent
38b8f75c19Smrg# `make' implicit rules from creating a file called install from it
39b8f75c19Smrg# when there is no Makefile.
40b8f75c19Smrg#
41b8f75c19Smrg# This script is compatible with the BSD install script, but was written
427e4fd55aSmrg# from scratch.
43b8f75c19Smrg
447e4fd55aSmrgnl='
457e4fd55aSmrg'
467e4fd55aSmrgIFS=" ""	$nl"
47b8f75c19Smrg
48b8f75c19Smrg# set DOITPROG to echo to test this script
49b8f75c19Smrg
50b8f75c19Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
517e4fd55aSmrgdoit=${DOITPROG-}
527e4fd55aSmrgif test -z "$doit"; then
537e4fd55aSmrg  doit_exec=exec
54b8f75c19Smrgelse
557e4fd55aSmrg  doit_exec=$doit
56b8f75c19Smrgfi
57b8f75c19Smrg
587e4fd55aSmrg# Put in absolute file names if you don't have them in your path;
597e4fd55aSmrg# or use environment vars.
607e4fd55aSmrg
617e4fd55aSmrgchgrpprog=${CHGRPPROG-chgrp}
627e4fd55aSmrgchmodprog=${CHMODPROG-chmod}
637e4fd55aSmrgchownprog=${CHOWNPROG-chown}
647e4fd55aSmrgcmpprog=${CMPPROG-cmp}
657e4fd55aSmrgcpprog=${CPPROG-cp}
667e4fd55aSmrgmkdirprog=${MKDIRPROG-mkdir}
677e4fd55aSmrgmvprog=${MVPROG-mv}
687e4fd55aSmrgrmprog=${RMPROG-rm}
697e4fd55aSmrgstripprog=${STRIPPROG-strip}
707e4fd55aSmrg
717e4fd55aSmrgposix_glob='?'
727e4fd55aSmrginitialize_posix_glob='
737e4fd55aSmrg  test "$posix_glob" != "?" || {
747e4fd55aSmrg    if (set -f) 2>/dev/null; then
757e4fd55aSmrg      posix_glob=
767e4fd55aSmrg    else
777e4fd55aSmrg      posix_glob=:
787e4fd55aSmrg    fi
797e4fd55aSmrg  }
807e4fd55aSmrg'
817e4fd55aSmrg
827e4fd55aSmrgposix_mkdir=
837e4fd55aSmrg
847e4fd55aSmrg# Desired mode of installed file.
857e4fd55aSmrgmode=0755
867e4fd55aSmrg
877e4fd55aSmrgchgrpcmd=
887e4fd55aSmrgchmodcmd=$chmodprog
897e4fd55aSmrgchowncmd=
907e4fd55aSmrgmvcmd=$mvprog
917e4fd55aSmrgrmcmd="$rmprog -f"
927e4fd55aSmrgstripcmd=
93b8f75c19Smrg
947e4fd55aSmrgsrc=
957e4fd55aSmrgdst=
967e4fd55aSmrgdir_arg=
977e4fd55aSmrgdst_arg=
98b8f75c19Smrg
997e4fd55aSmrgcopy_on_change=false
1007e4fd55aSmrgno_target_directory=
101b8f75c19Smrg
1027e4fd55aSmrgusage="\
1037e4fd55aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
1047e4fd55aSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
1057e4fd55aSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
1067e4fd55aSmrg   or: $0 [OPTION]... -d DIRECTORIES...
107b8f75c19Smrg
1087e4fd55aSmrgIn the 1st form, copy SRCFILE to DSTFILE.
1097e4fd55aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1107e4fd55aSmrgIn the 4th, create DIRECTORIES.
111b8f75c19Smrg
1127e4fd55aSmrgOptions:
1137e4fd55aSmrg     --help     display this help and exit.
1147e4fd55aSmrg     --version  display version info and exit.
115b8f75c19Smrg
1167e4fd55aSmrg  -c            (ignored)
1177e4fd55aSmrg  -C            install only if different (preserve the last data modification time)
1187e4fd55aSmrg  -d            create directories instead of installing files.
1197e4fd55aSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1207e4fd55aSmrg  -m MODE       $chmodprog installed files to MODE.
1217e4fd55aSmrg  -o USER       $chownprog installed files to USER.
1227e4fd55aSmrg  -s            $stripprog installed files.
1237e4fd55aSmrg  -t DIRECTORY  install into DIRECTORY.
1247e4fd55aSmrg  -T            report an error if DSTFILE is a directory.
125b8f75c19Smrg
1267e4fd55aSmrgEnvironment variables override the default commands:
1277e4fd55aSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1287e4fd55aSmrg  RMPROG STRIPPROG
1297e4fd55aSmrg"
130b8f75c19Smrg
1317e4fd55aSmrgwhile test $# -ne 0; do
1327e4fd55aSmrg  case $1 in
1337e4fd55aSmrg    -c) ;;
134b8f75c19Smrg
1357e4fd55aSmrg    -C) copy_on_change=true;;
136b8f75c19Smrg
1377e4fd55aSmrg    -d) dir_arg=true;;
138b8f75c19Smrg
1397e4fd55aSmrg    -g) chgrpcmd="$chgrpprog $2"
1407e4fd55aSmrg	shift;;
141b8f75c19Smrg
1427e4fd55aSmrg    --help) echo "$usage"; exit $?;;
143b8f75c19Smrg
1447e4fd55aSmrg    -m) mode=$2
1457e4fd55aSmrg	case $mode in
1467e4fd55aSmrg	  *' '* | *'	'* | *'
1477e4fd55aSmrg'*	  | *'*'* | *'?'* | *'['*)
1487e4fd55aSmrg	    echo "$0: invalid mode: $mode" >&2
1497e4fd55aSmrg	    exit 1;;
1507e4fd55aSmrg	esac
1517e4fd55aSmrg	shift;;
152b8f75c19Smrg
1537e4fd55aSmrg    -o) chowncmd="$chownprog $2"
1547e4fd55aSmrg	shift;;
155b8f75c19Smrg
1567e4fd55aSmrg    -s) stripcmd=$stripprog;;
157b8f75c19Smrg
1587e4fd55aSmrg    -t) dst_arg=$2
1597e4fd55aSmrg	shift;;
160b8f75c19Smrg
1617e4fd55aSmrg    -T) no_target_directory=true;;
162b8f75c19Smrg
1637e4fd55aSmrg    --version) echo "$0 $scriptversion"; exit $?;;
164b8f75c19Smrg
1657e4fd55aSmrg    --)	shift
1667e4fd55aSmrg	break;;
167b8f75c19Smrg
1687e4fd55aSmrg    -*)	echo "$0: invalid option: $1" >&2
1697e4fd55aSmrg	exit 1;;
170b8f75c19Smrg
1717e4fd55aSmrg    *)  break;;
1727e4fd55aSmrg  esac
1737e4fd55aSmrg  shift
1747e4fd55aSmrgdone
175b8f75c19Smrg
1767e4fd55aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1777e4fd55aSmrg  # When -d is used, all remaining arguments are directories to create.
1787e4fd55aSmrg  # When -t is used, the destination is already specified.
1797e4fd55aSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1807e4fd55aSmrg  for arg
1817e4fd55aSmrg  do
1827e4fd55aSmrg    if test -n "$dst_arg"; then
1837e4fd55aSmrg      # $@ is not empty: it contains at least $arg.
1847e4fd55aSmrg      set fnord "$@" "$dst_arg"
1857e4fd55aSmrg      shift # fnord
1867e4fd55aSmrg    fi
1877e4fd55aSmrg    shift # arg
1887e4fd55aSmrg    dst_arg=$arg
1897e4fd55aSmrg  done
1907e4fd55aSmrgfi
191b8f75c19Smrg
1927e4fd55aSmrgif test $# -eq 0; then
1937e4fd55aSmrg  if test -z "$dir_arg"; then
1947e4fd55aSmrg    echo "$0: no input file specified." >&2
1957e4fd55aSmrg    exit 1
1967e4fd55aSmrg  fi
1977e4fd55aSmrg  # It's OK to call `install-sh -d' without argument.
1987e4fd55aSmrg  # This can happen when creating conditional directories.
1997e4fd55aSmrg  exit 0
2007e4fd55aSmrgfi
201b8f75c19Smrg
2027e4fd55aSmrgif test -z "$dir_arg"; then
2037e4fd55aSmrg  trap '(exit $?); exit' 1 2 13 15
2047e4fd55aSmrg
2057e4fd55aSmrg  # Set umask so as not to create temps with too-generous modes.
2067e4fd55aSmrg  # However, 'strip' requires both read and write access to temps.
2077e4fd55aSmrg  case $mode in
2087e4fd55aSmrg    # Optimize common cases.
2097e4fd55aSmrg    *644) cp_umask=133;;
2107e4fd55aSmrg    *755) cp_umask=22;;
2117e4fd55aSmrg
2127e4fd55aSmrg    *[0-7])
2137e4fd55aSmrg      if test -z "$stripcmd"; then
2147e4fd55aSmrg	u_plus_rw=
2157e4fd55aSmrg      else
2167e4fd55aSmrg	u_plus_rw='% 200'
2177e4fd55aSmrg      fi
2187e4fd55aSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2197e4fd55aSmrg    *)
2207e4fd55aSmrg      if test -z "$stripcmd"; then
2217e4fd55aSmrg	u_plus_rw=
2227e4fd55aSmrg      else
2237e4fd55aSmrg	u_plus_rw=,u+rw
2247e4fd55aSmrg      fi
2257e4fd55aSmrg      cp_umask=$mode$u_plus_rw;;
2267e4fd55aSmrg  esac
2277e4fd55aSmrgfi
228b8f75c19Smrg
2297e4fd55aSmrgfor src
2307e4fd55aSmrgdo
2317e4fd55aSmrg  # Protect names starting with `-'.
2327e4fd55aSmrg  case $src in
2337e4fd55aSmrg    -*) src=./$src;;
2347e4fd55aSmrg  esac
2357e4fd55aSmrg
2367e4fd55aSmrg  if test -n "$dir_arg"; then
2377e4fd55aSmrg    dst=$src
2387e4fd55aSmrg    dstdir=$dst
2397e4fd55aSmrg    test -d "$dstdir"
2407e4fd55aSmrg    dstdir_status=$?
2417e4fd55aSmrg  else
2427e4fd55aSmrg
2437e4fd55aSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2447e4fd55aSmrg    # might cause directories to be created, which would be especially bad
2457e4fd55aSmrg    # if $src (and thus $dsttmp) contains '*'.
2467e4fd55aSmrg    if test ! -f "$src" && test ! -d "$src"; then
2477e4fd55aSmrg      echo "$0: $src does not exist." >&2
2487e4fd55aSmrg      exit 1
2497e4fd55aSmrg    fi
2507e4fd55aSmrg
2517e4fd55aSmrg    if test -z "$dst_arg"; then
2527e4fd55aSmrg      echo "$0: no destination specified." >&2
2537e4fd55aSmrg      exit 1
2547e4fd55aSmrg    fi
2557e4fd55aSmrg
2567e4fd55aSmrg    dst=$dst_arg
2577e4fd55aSmrg    # Protect names starting with `-'.
2587e4fd55aSmrg    case $dst in
2597e4fd55aSmrg      -*) dst=./$dst;;
2607e4fd55aSmrg    esac
261b8f75c19Smrg
2627e4fd55aSmrg    # If destination is a directory, append the input filename; won't work
2637e4fd55aSmrg    # if double slashes aren't ignored.
2647e4fd55aSmrg    if test -d "$dst"; then
2657e4fd55aSmrg      if test -n "$no_target_directory"; then
2667e4fd55aSmrg	echo "$0: $dst_arg: Is a directory" >&2
2677e4fd55aSmrg	exit 1
2687e4fd55aSmrg      fi
2697e4fd55aSmrg      dstdir=$dst
2707e4fd55aSmrg      dst=$dstdir/`basename "$src"`
2717e4fd55aSmrg      dstdir_status=0
2727e4fd55aSmrg    else
2737e4fd55aSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2747e4fd55aSmrg      dstdir=`
2757e4fd55aSmrg	(dirname "$dst") 2>/dev/null ||
2767e4fd55aSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2777e4fd55aSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
2787e4fd55aSmrg	     X"$dst" : 'X\(//\)$' \| \
2797e4fd55aSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2807e4fd55aSmrg	echo X"$dst" |
2817e4fd55aSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2827e4fd55aSmrg		   s//\1/
2837e4fd55aSmrg		   q
2847e4fd55aSmrg		 }
2857e4fd55aSmrg		 /^X\(\/\/\)[^/].*/{
2867e4fd55aSmrg		   s//\1/
2877e4fd55aSmrg		   q
2887e4fd55aSmrg		 }
2897e4fd55aSmrg		 /^X\(\/\/\)$/{
2907e4fd55aSmrg		   s//\1/
2917e4fd55aSmrg		   q
2927e4fd55aSmrg		 }
2937e4fd55aSmrg		 /^X\(\/\).*/{
2947e4fd55aSmrg		   s//\1/
2957e4fd55aSmrg		   q
2967e4fd55aSmrg		 }
2977e4fd55aSmrg		 s/.*/./; q'
2987e4fd55aSmrg      `
2997e4fd55aSmrg
3007e4fd55aSmrg      test -d "$dstdir"
3017e4fd55aSmrg      dstdir_status=$?
3027e4fd55aSmrg    fi
3037e4fd55aSmrg  fi
3047e4fd55aSmrg
3057e4fd55aSmrg  obsolete_mkdir_used=false
3067e4fd55aSmrg
3077e4fd55aSmrg  if test $dstdir_status != 0; then
3087e4fd55aSmrg    case $posix_mkdir in
3097e4fd55aSmrg      '')
3107e4fd55aSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
3117e4fd55aSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
3127e4fd55aSmrg	umask=`umask`
3137e4fd55aSmrg	case $stripcmd.$umask in
3147e4fd55aSmrg	  # Optimize common cases.
3157e4fd55aSmrg	  *[2367][2367]) mkdir_umask=$umask;;
3167e4fd55aSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3177e4fd55aSmrg
3187e4fd55aSmrg	  *[0-7])
3197e4fd55aSmrg	    mkdir_umask=`expr $umask + 22 \
3207e4fd55aSmrg	      - $umask % 100 % 40 + $umask % 20 \
3217e4fd55aSmrg	      - $umask % 10 % 4 + $umask % 2
3227e4fd55aSmrg	    `;;
3237e4fd55aSmrg	  *) mkdir_umask=$umask,go-w;;
3247e4fd55aSmrg	esac
3257e4fd55aSmrg
3267e4fd55aSmrg	# With -d, create the new directory with the user-specified mode.
3277e4fd55aSmrg	# Otherwise, rely on $mkdir_umask.
3287e4fd55aSmrg	if test -n "$dir_arg"; then
3297e4fd55aSmrg	  mkdir_mode=-m$mode
330b8f75c19Smrg	else
3317e4fd55aSmrg	  mkdir_mode=
332b8f75c19Smrg	fi
333b8f75c19Smrg
3347e4fd55aSmrg	posix_mkdir=false
3357e4fd55aSmrg	case $umask in
3367e4fd55aSmrg	  *[123567][0-7][0-7])
3377e4fd55aSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3387e4fd55aSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3397e4fd55aSmrg	    ;;
3407e4fd55aSmrg	  *)
3417e4fd55aSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3427e4fd55aSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3437e4fd55aSmrg
3447e4fd55aSmrg	    if (umask $mkdir_umask &&
3457e4fd55aSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3467e4fd55aSmrg	    then
3477e4fd55aSmrg	      if test -z "$dir_arg" || {
3487e4fd55aSmrg		   # Check for POSIX incompatibilities with -m.
3497e4fd55aSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3507e4fd55aSmrg		   # other-writeable bit of parent directory when it shouldn't.
3517e4fd55aSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3527e4fd55aSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3537e4fd55aSmrg		   case $ls_ld_tmpdir in
3547e4fd55aSmrg		     d????-?r-*) different_mode=700;;
3557e4fd55aSmrg		     d????-?--*) different_mode=755;;
3567e4fd55aSmrg		     *) false;;
3577e4fd55aSmrg		   esac &&
3587e4fd55aSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3597e4fd55aSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3607e4fd55aSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3617e4fd55aSmrg		   }
3627e4fd55aSmrg		 }
3637e4fd55aSmrg	      then posix_mkdir=:
3647e4fd55aSmrg	      fi
3657e4fd55aSmrg	      rmdir "$tmpdir/d" "$tmpdir"
3667e4fd55aSmrg	    else
3677e4fd55aSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
3687e4fd55aSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3697e4fd55aSmrg	    fi
3707e4fd55aSmrg	    trap '' 0;;
3717e4fd55aSmrg	esac;;
3727e4fd55aSmrg    esac
373b8f75c19Smrg
3747e4fd55aSmrg    if
3757e4fd55aSmrg      $posix_mkdir && (
3767e4fd55aSmrg	umask $mkdir_umask &&
3777e4fd55aSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3787e4fd55aSmrg      )
3797e4fd55aSmrg    then :
3807e4fd55aSmrg    else
3817e4fd55aSmrg
3827e4fd55aSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3837e4fd55aSmrg      # or it failed possibly due to a race condition.  Create the
3847e4fd55aSmrg      # directory the slow way, step by step, checking for races as we go.
3857e4fd55aSmrg
3867e4fd55aSmrg      case $dstdir in
3877e4fd55aSmrg	/*) prefix='/';;
3887e4fd55aSmrg	-*) prefix='./';;
3897e4fd55aSmrg	*)  prefix='';;
3907e4fd55aSmrg      esac
3917e4fd55aSmrg
3927e4fd55aSmrg      eval "$initialize_posix_glob"
3937e4fd55aSmrg
3947e4fd55aSmrg      oIFS=$IFS
3957e4fd55aSmrg      IFS=/
3967e4fd55aSmrg      $posix_glob set -f
3977e4fd55aSmrg      set fnord $dstdir
3987e4fd55aSmrg      shift
3997e4fd55aSmrg      $posix_glob set +f
4007e4fd55aSmrg      IFS=$oIFS
4017e4fd55aSmrg
4027e4fd55aSmrg      prefixes=
4037e4fd55aSmrg
4047e4fd55aSmrg      for d
4057e4fd55aSmrg      do
4067e4fd55aSmrg	test -z "$d" && continue
4077e4fd55aSmrg
4087e4fd55aSmrg	prefix=$prefix$d
4097e4fd55aSmrg	if test -d "$prefix"; then
4107e4fd55aSmrg	  prefixes=
4117e4fd55aSmrg	else
4127e4fd55aSmrg	  if $posix_mkdir; then
4137e4fd55aSmrg	    (umask=$mkdir_umask &&
4147e4fd55aSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4157e4fd55aSmrg	    # Don't fail if two instances are running concurrently.
4167e4fd55aSmrg	    test -d "$prefix" || exit 1
4177e4fd55aSmrg	  else
4187e4fd55aSmrg	    case $prefix in
4197e4fd55aSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4207e4fd55aSmrg	      *) qprefix=$prefix;;
4217e4fd55aSmrg	    esac
4227e4fd55aSmrg	    prefixes="$prefixes '$qprefix'"
4237e4fd55aSmrg	  fi
4247e4fd55aSmrg	fi
4257e4fd55aSmrg	prefix=$prefix/
4267e4fd55aSmrg      done
4277e4fd55aSmrg
4287e4fd55aSmrg      if test -n "$prefixes"; then
4297e4fd55aSmrg	# Don't fail if two instances are running concurrently.
4307e4fd55aSmrg	(umask $mkdir_umask &&
4317e4fd55aSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4327e4fd55aSmrg	  test -d "$dstdir" || exit 1
4337e4fd55aSmrg	obsolete_mkdir_used=true
4347e4fd55aSmrg      fi
4357e4fd55aSmrg    fi
4367e4fd55aSmrg  fi
4377e4fd55aSmrg
4387e4fd55aSmrg  if test -n "$dir_arg"; then
4397e4fd55aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4407e4fd55aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4417e4fd55aSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4427e4fd55aSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4437e4fd55aSmrg  else
4447e4fd55aSmrg
4457e4fd55aSmrg    # Make a couple of temp file names in the proper directory.
4467e4fd55aSmrg    dsttmp=$dstdir/_inst.$$_
4477e4fd55aSmrg    rmtmp=$dstdir/_rm.$$_
4487e4fd55aSmrg
4497e4fd55aSmrg    # Trap to clean up those temp files at exit.
4507e4fd55aSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4517e4fd55aSmrg
4527e4fd55aSmrg    # Copy the file name to the temp name.
4537e4fd55aSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4547e4fd55aSmrg
4557e4fd55aSmrg    # and set any options; do chmod last to preserve setuid bits.
4567e4fd55aSmrg    #
4577e4fd55aSmrg    # If any of these fail, we abort the whole thing.  If we want to
4587e4fd55aSmrg    # ignore errors from any of these, just make sure not to ignore
4597e4fd55aSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4607e4fd55aSmrg    #
4617e4fd55aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4627e4fd55aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4637e4fd55aSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4647e4fd55aSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4657e4fd55aSmrg
4667e4fd55aSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4677e4fd55aSmrg    if $copy_on_change &&
4687e4fd55aSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
4697e4fd55aSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
4707e4fd55aSmrg
4717e4fd55aSmrg       eval "$initialize_posix_glob" &&
4727e4fd55aSmrg       $posix_glob set -f &&
4737e4fd55aSmrg       set X $old && old=:$2:$4:$5:$6 &&
4747e4fd55aSmrg       set X $new && new=:$2:$4:$5:$6 &&
4757e4fd55aSmrg       $posix_glob set +f &&
4767e4fd55aSmrg
4777e4fd55aSmrg       test "$old" = "$new" &&
4787e4fd55aSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4797e4fd55aSmrg    then
4807e4fd55aSmrg      rm -f "$dsttmp"
4817e4fd55aSmrg    else
4827e4fd55aSmrg      # Rename the file to the real destination.
4837e4fd55aSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4847e4fd55aSmrg
4857e4fd55aSmrg      # The rename failed, perhaps because mv can't rename something else
4867e4fd55aSmrg      # to itself, or perhaps because mv is so ancient that it does not
4877e4fd55aSmrg      # support -f.
4887e4fd55aSmrg      {
4897e4fd55aSmrg	# Now remove or move aside any old file at destination location.
4907e4fd55aSmrg	# We try this two ways since rm can't unlink itself on some
4917e4fd55aSmrg	# systems and the destination file might be busy for other
4927e4fd55aSmrg	# reasons.  In this case, the final cleanup might fail but the new
4937e4fd55aSmrg	# file should still install successfully.
4947e4fd55aSmrg	{
4957e4fd55aSmrg	  test ! -f "$dst" ||
4967e4fd55aSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
4977e4fd55aSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4987e4fd55aSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4997e4fd55aSmrg	  } ||
5007e4fd55aSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
5017e4fd55aSmrg	    (exit 1); exit 1
5027e4fd55aSmrg	  }
5037e4fd55aSmrg	} &&
5047e4fd55aSmrg
5057e4fd55aSmrg	# Now rename the file to the real destination.
5067e4fd55aSmrg	$doit $mvcmd "$dsttmp" "$dst"
5077e4fd55aSmrg      }
5087e4fd55aSmrg    fi || exit 1
5097e4fd55aSmrg
5107e4fd55aSmrg    trap '' 0
5117e4fd55aSmrg  fi
5127e4fd55aSmrgdone
513b8f75c19Smrg
5147e4fd55aSmrg# Local variables:
5157e4fd55aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
5167e4fd55aSmrg# time-stamp-start: "scriptversion="
5177e4fd55aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5187e4fd55aSmrg# time-stamp-time-zone: "UTC"
5197e4fd55aSmrg# time-stamp-end: "; # UTC"
5207e4fd55aSmrg# End:
521