install-sh revision 7d575c90
1fdb3d228Smrg#!/bin/sh
2fdb3d228Smrg# install - install a program, script, or datafile
39b41ff1aSmrg
47d575c90Smrgscriptversion=2011-01-19.21; # UTC
59b41ff1aSmrg
6fdb3d228Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7fdb3d228Smrg# later released in X11R6 (xc/config/util/install.sh) with the
8fdb3d228Smrg# following copyright and license.
9fdb3d228Smrg#
10fdb3d228Smrg# Copyright (C) 1994 X Consortium
11fdb3d228Smrg#
12fdb3d228Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13fdb3d228Smrg# of this software and associated documentation files (the "Software"), to
14fdb3d228Smrg# deal in the Software without restriction, including without limitation the
15fdb3d228Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16fdb3d228Smrg# sell copies of the Software, and to permit persons to whom the Software is
17fdb3d228Smrg# furnished to do so, subject to the following conditions:
18fdb3d228Smrg#
19fdb3d228Smrg# The above copyright notice and this permission notice shall be included in
20fdb3d228Smrg# all copies or substantial portions of the Software.
21fdb3d228Smrg#
22fdb3d228Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23fdb3d228Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24fdb3d228Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25fdb3d228Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26fdb3d228Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27fdb3d228Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28fdb3d228Smrg#
29fdb3d228Smrg# Except as contained in this notice, the name of the X Consortium shall not
30fdb3d228Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
31fdb3d228Smrg# ings in this Software without prior written authorization from the X Consor-
32fdb3d228Smrg# tium.
33fdb3d228Smrg#
34fdb3d228Smrg#
35fdb3d228Smrg# FSF changes to this file are in the public domain.
36fdb3d228Smrg#
37fdb3d228Smrg# Calling this script install-sh is preferred over install.sh, to prevent
38fdb3d228Smrg# `make' implicit rules from creating a file called install from it
39fdb3d228Smrg# when there is no Makefile.
40fdb3d228Smrg#
41fdb3d228Smrg# This script is compatible with the BSD install script, but was written
429b41ff1aSmrg# from scratch.
43fdb3d228Smrg
449b41ff1aSmrgnl='
459b41ff1aSmrg'
469b41ff1aSmrgIFS=" ""	$nl"
47fdb3d228Smrg
48fdb3d228Smrg# set DOITPROG to echo to test this script
49fdb3d228Smrg
50fdb3d228Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
519b41ff1aSmrgdoit=${DOITPROG-}
529b41ff1aSmrgif test -z "$doit"; then
539b41ff1aSmrg  doit_exec=exec
54fdb3d228Smrgelse
559b41ff1aSmrg  doit_exec=$doit
56fdb3d228Smrgfi
57fdb3d228Smrg
589b41ff1aSmrg# Put in absolute file names if you don't have them in your path;
599b41ff1aSmrg# or use environment vars.
609b41ff1aSmrg
619b41ff1aSmrgchgrpprog=${CHGRPPROG-chgrp}
629b41ff1aSmrgchmodprog=${CHMODPROG-chmod}
639b41ff1aSmrgchownprog=${CHOWNPROG-chown}
649b41ff1aSmrgcmpprog=${CMPPROG-cmp}
659b41ff1aSmrgcpprog=${CPPROG-cp}
669b41ff1aSmrgmkdirprog=${MKDIRPROG-mkdir}
679b41ff1aSmrgmvprog=${MVPROG-mv}
689b41ff1aSmrgrmprog=${RMPROG-rm}
699b41ff1aSmrgstripprog=${STRIPPROG-strip}
709b41ff1aSmrg
719b41ff1aSmrgposix_glob='?'
729b41ff1aSmrginitialize_posix_glob='
739b41ff1aSmrg  test "$posix_glob" != "?" || {
749b41ff1aSmrg    if (set -f) 2>/dev/null; then
759b41ff1aSmrg      posix_glob=
769b41ff1aSmrg    else
779b41ff1aSmrg      posix_glob=:
789b41ff1aSmrg    fi
799b41ff1aSmrg  }
809b41ff1aSmrg'
819b41ff1aSmrg
829b41ff1aSmrgposix_mkdir=
839b41ff1aSmrg
849b41ff1aSmrg# Desired mode of installed file.
859b41ff1aSmrgmode=0755
869b41ff1aSmrg
879b41ff1aSmrgchgrpcmd=
889b41ff1aSmrgchmodcmd=$chmodprog
899b41ff1aSmrgchowncmd=
909b41ff1aSmrgmvcmd=$mvprog
919b41ff1aSmrgrmcmd="$rmprog -f"
929b41ff1aSmrgstripcmd=
93fdb3d228Smrg
949b41ff1aSmrgsrc=
959b41ff1aSmrgdst=
969b41ff1aSmrgdir_arg=
979b41ff1aSmrgdst_arg=
98fdb3d228Smrg
999b41ff1aSmrgcopy_on_change=false
1009b41ff1aSmrgno_target_directory=
101fdb3d228Smrg
1029b41ff1aSmrgusage="\
1039b41ff1aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
1049b41ff1aSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
1059b41ff1aSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
1069b41ff1aSmrg   or: $0 [OPTION]... -d DIRECTORIES...
107fdb3d228Smrg
1089b41ff1aSmrgIn the 1st form, copy SRCFILE to DSTFILE.
1099b41ff1aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
1109b41ff1aSmrgIn the 4th, create DIRECTORIES.
111fdb3d228Smrg
1129b41ff1aSmrgOptions:
1139b41ff1aSmrg     --help     display this help and exit.
1149b41ff1aSmrg     --version  display version info and exit.
115fdb3d228Smrg
1169b41ff1aSmrg  -c            (ignored)
1179b41ff1aSmrg  -C            install only if different (preserve the last data modification time)
1189b41ff1aSmrg  -d            create directories instead of installing files.
1199b41ff1aSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1209b41ff1aSmrg  -m MODE       $chmodprog installed files to MODE.
1219b41ff1aSmrg  -o USER       $chownprog installed files to USER.
1229b41ff1aSmrg  -s            $stripprog installed files.
1239b41ff1aSmrg  -t DIRECTORY  install into DIRECTORY.
1249b41ff1aSmrg  -T            report an error if DSTFILE is a directory.
125fdb3d228Smrg
1269b41ff1aSmrgEnvironment variables override the default commands:
1279b41ff1aSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1289b41ff1aSmrg  RMPROG STRIPPROG
1299b41ff1aSmrg"
130fdb3d228Smrg
1319b41ff1aSmrgwhile test $# -ne 0; do
1329b41ff1aSmrg  case $1 in
1339b41ff1aSmrg    -c) ;;
134fdb3d228Smrg
1359b41ff1aSmrg    -C) copy_on_change=true;;
136fdb3d228Smrg
1379b41ff1aSmrg    -d) dir_arg=true;;
138fdb3d228Smrg
1399b41ff1aSmrg    -g) chgrpcmd="$chgrpprog $2"
1409b41ff1aSmrg	shift;;
141fdb3d228Smrg
1429b41ff1aSmrg    --help) echo "$usage"; exit $?;;
143fdb3d228Smrg
1449b41ff1aSmrg    -m) mode=$2
1459b41ff1aSmrg	case $mode in
1469b41ff1aSmrg	  *' '* | *'	'* | *'
1479b41ff1aSmrg'*	  | *'*'* | *'?'* | *'['*)
1489b41ff1aSmrg	    echo "$0: invalid mode: $mode" >&2
1499b41ff1aSmrg	    exit 1;;
1509b41ff1aSmrg	esac
1519b41ff1aSmrg	shift;;
152fdb3d228Smrg
1539b41ff1aSmrg    -o) chowncmd="$chownprog $2"
1549b41ff1aSmrg	shift;;
155fdb3d228Smrg
1569b41ff1aSmrg    -s) stripcmd=$stripprog;;
157fdb3d228Smrg
1589b41ff1aSmrg    -t) dst_arg=$2
1597d575c90Smrg	# Protect names problematic for `test' and other utilities.
1607d575c90Smrg	case $dst_arg in
1617d575c90Smrg	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
1627d575c90Smrg	esac
1639b41ff1aSmrg	shift;;
164fdb3d228Smrg
1659b41ff1aSmrg    -T) no_target_directory=true;;
166fdb3d228Smrg
1679b41ff1aSmrg    --version) echo "$0 $scriptversion"; exit $?;;
168fdb3d228Smrg
1699b41ff1aSmrg    --)	shift
1709b41ff1aSmrg	break;;
171fdb3d228Smrg
1729b41ff1aSmrg    -*)	echo "$0: invalid option: $1" >&2
1739b41ff1aSmrg	exit 1;;
174fdb3d228Smrg
1759b41ff1aSmrg    *)  break;;
1769b41ff1aSmrg  esac
1779b41ff1aSmrg  shift
1789b41ff1aSmrgdone
179fdb3d228Smrg
1809b41ff1aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1819b41ff1aSmrg  # When -d is used, all remaining arguments are directories to create.
1829b41ff1aSmrg  # When -t is used, the destination is already specified.
1839b41ff1aSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1849b41ff1aSmrg  for arg
1859b41ff1aSmrg  do
1869b41ff1aSmrg    if test -n "$dst_arg"; then
1879b41ff1aSmrg      # $@ is not empty: it contains at least $arg.
1889b41ff1aSmrg      set fnord "$@" "$dst_arg"
1899b41ff1aSmrg      shift # fnord
1909b41ff1aSmrg    fi
1919b41ff1aSmrg    shift # arg
1929b41ff1aSmrg    dst_arg=$arg
1937d575c90Smrg    # Protect names problematic for `test' and other utilities.
1947d575c90Smrg    case $dst_arg in
1957d575c90Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1967d575c90Smrg    esac
1979b41ff1aSmrg  done
1989b41ff1aSmrgfi
199fdb3d228Smrg
2009b41ff1aSmrgif test $# -eq 0; then
2019b41ff1aSmrg  if test -z "$dir_arg"; then
2029b41ff1aSmrg    echo "$0: no input file specified." >&2
2039b41ff1aSmrg    exit 1
2049b41ff1aSmrg  fi
2059b41ff1aSmrg  # It's OK to call `install-sh -d' without argument.
2069b41ff1aSmrg  # This can happen when creating conditional directories.
2079b41ff1aSmrg  exit 0
2089b41ff1aSmrgfi
209fdb3d228Smrg
2109b41ff1aSmrgif test -z "$dir_arg"; then
2117d575c90Smrg  do_exit='(exit $ret); exit $ret'
2127d575c90Smrg  trap "ret=129; $do_exit" 1
2137d575c90Smrg  trap "ret=130; $do_exit" 2
2147d575c90Smrg  trap "ret=141; $do_exit" 13
2157d575c90Smrg  trap "ret=143; $do_exit" 15
2169b41ff1aSmrg
2179b41ff1aSmrg  # Set umask so as not to create temps with too-generous modes.
2189b41ff1aSmrg  # However, 'strip' requires both read and write access to temps.
2199b41ff1aSmrg  case $mode in
2209b41ff1aSmrg    # Optimize common cases.
2219b41ff1aSmrg    *644) cp_umask=133;;
2229b41ff1aSmrg    *755) cp_umask=22;;
2239b41ff1aSmrg
2249b41ff1aSmrg    *[0-7])
2259b41ff1aSmrg      if test -z "$stripcmd"; then
2269b41ff1aSmrg	u_plus_rw=
2279b41ff1aSmrg      else
2289b41ff1aSmrg	u_plus_rw='% 200'
2299b41ff1aSmrg      fi
2309b41ff1aSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2319b41ff1aSmrg    *)
2329b41ff1aSmrg      if test -z "$stripcmd"; then
2339b41ff1aSmrg	u_plus_rw=
2349b41ff1aSmrg      else
2359b41ff1aSmrg	u_plus_rw=,u+rw
2369b41ff1aSmrg      fi
2379b41ff1aSmrg      cp_umask=$mode$u_plus_rw;;
2389b41ff1aSmrg  esac
2399b41ff1aSmrgfi
240fdb3d228Smrg
2419b41ff1aSmrgfor src
2429b41ff1aSmrgdo
2437d575c90Smrg  # Protect names problematic for `test' and other utilities.
2449b41ff1aSmrg  case $src in
2457d575c90Smrg    -* | [=\(\)!]) src=./$src;;
2469b41ff1aSmrg  esac
2479b41ff1aSmrg
2489b41ff1aSmrg  if test -n "$dir_arg"; then
2499b41ff1aSmrg    dst=$src
2509b41ff1aSmrg    dstdir=$dst
2519b41ff1aSmrg    test -d "$dstdir"
2529b41ff1aSmrg    dstdir_status=$?
2539b41ff1aSmrg  else
2549b41ff1aSmrg
2559b41ff1aSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2569b41ff1aSmrg    # might cause directories to be created, which would be especially bad
2579b41ff1aSmrg    # if $src (and thus $dsttmp) contains '*'.
2589b41ff1aSmrg    if test ! -f "$src" && test ! -d "$src"; then
2599b41ff1aSmrg      echo "$0: $src does not exist." >&2
2609b41ff1aSmrg      exit 1
2619b41ff1aSmrg    fi
2629b41ff1aSmrg
2639b41ff1aSmrg    if test -z "$dst_arg"; then
2649b41ff1aSmrg      echo "$0: no destination specified." >&2
2659b41ff1aSmrg      exit 1
2669b41ff1aSmrg    fi
2679b41ff1aSmrg    dst=$dst_arg
268fdb3d228Smrg
2699b41ff1aSmrg    # If destination is a directory, append the input filename; won't work
2709b41ff1aSmrg    # if double slashes aren't ignored.
2719b41ff1aSmrg    if test -d "$dst"; then
2729b41ff1aSmrg      if test -n "$no_target_directory"; then
2739b41ff1aSmrg	echo "$0: $dst_arg: Is a directory" >&2
2749b41ff1aSmrg	exit 1
2759b41ff1aSmrg      fi
2769b41ff1aSmrg      dstdir=$dst
2779b41ff1aSmrg      dst=$dstdir/`basename "$src"`
2789b41ff1aSmrg      dstdir_status=0
2799b41ff1aSmrg    else
2809b41ff1aSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2819b41ff1aSmrg      dstdir=`
2829b41ff1aSmrg	(dirname "$dst") 2>/dev/null ||
2839b41ff1aSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2849b41ff1aSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
2859b41ff1aSmrg	     X"$dst" : 'X\(//\)$' \| \
2869b41ff1aSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2879b41ff1aSmrg	echo X"$dst" |
2889b41ff1aSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2899b41ff1aSmrg		   s//\1/
2909b41ff1aSmrg		   q
2919b41ff1aSmrg		 }
2929b41ff1aSmrg		 /^X\(\/\/\)[^/].*/{
2939b41ff1aSmrg		   s//\1/
2949b41ff1aSmrg		   q
2959b41ff1aSmrg		 }
2969b41ff1aSmrg		 /^X\(\/\/\)$/{
2979b41ff1aSmrg		   s//\1/
2989b41ff1aSmrg		   q
2999b41ff1aSmrg		 }
3009b41ff1aSmrg		 /^X\(\/\).*/{
3019b41ff1aSmrg		   s//\1/
3029b41ff1aSmrg		   q
3039b41ff1aSmrg		 }
3049b41ff1aSmrg		 s/.*/./; q'
3059b41ff1aSmrg      `
3069b41ff1aSmrg
3079b41ff1aSmrg      test -d "$dstdir"
3089b41ff1aSmrg      dstdir_status=$?
3099b41ff1aSmrg    fi
3109b41ff1aSmrg  fi
3119b41ff1aSmrg
3129b41ff1aSmrg  obsolete_mkdir_used=false
3139b41ff1aSmrg
3149b41ff1aSmrg  if test $dstdir_status != 0; then
3159b41ff1aSmrg    case $posix_mkdir in
3169b41ff1aSmrg      '')
3179b41ff1aSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
3189b41ff1aSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
3199b41ff1aSmrg	umask=`umask`
3209b41ff1aSmrg	case $stripcmd.$umask in
3219b41ff1aSmrg	  # Optimize common cases.
3229b41ff1aSmrg	  *[2367][2367]) mkdir_umask=$umask;;
3239b41ff1aSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3249b41ff1aSmrg
3259b41ff1aSmrg	  *[0-7])
3269b41ff1aSmrg	    mkdir_umask=`expr $umask + 22 \
3279b41ff1aSmrg	      - $umask % 100 % 40 + $umask % 20 \
3289b41ff1aSmrg	      - $umask % 10 % 4 + $umask % 2
3299b41ff1aSmrg	    `;;
3309b41ff1aSmrg	  *) mkdir_umask=$umask,go-w;;
3319b41ff1aSmrg	esac
3329b41ff1aSmrg
3339b41ff1aSmrg	# With -d, create the new directory with the user-specified mode.
3349b41ff1aSmrg	# Otherwise, rely on $mkdir_umask.
3359b41ff1aSmrg	if test -n "$dir_arg"; then
3369b41ff1aSmrg	  mkdir_mode=-m$mode
337fdb3d228Smrg	else
3389b41ff1aSmrg	  mkdir_mode=
339fdb3d228Smrg	fi
340fdb3d228Smrg
3419b41ff1aSmrg	posix_mkdir=false
3429b41ff1aSmrg	case $umask in
3439b41ff1aSmrg	  *[123567][0-7][0-7])
3449b41ff1aSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3459b41ff1aSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3469b41ff1aSmrg	    ;;
3479b41ff1aSmrg	  *)
3489b41ff1aSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3499b41ff1aSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3509b41ff1aSmrg
3519b41ff1aSmrg	    if (umask $mkdir_umask &&
3529b41ff1aSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3539b41ff1aSmrg	    then
3549b41ff1aSmrg	      if test -z "$dir_arg" || {
3559b41ff1aSmrg		   # Check for POSIX incompatibilities with -m.
3569b41ff1aSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3579b41ff1aSmrg		   # other-writeable bit of parent directory when it shouldn't.
3589b41ff1aSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3599b41ff1aSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3609b41ff1aSmrg		   case $ls_ld_tmpdir in
3619b41ff1aSmrg		     d????-?r-*) different_mode=700;;
3629b41ff1aSmrg		     d????-?--*) different_mode=755;;
3639b41ff1aSmrg		     *) false;;
3649b41ff1aSmrg		   esac &&
3659b41ff1aSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3669b41ff1aSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3679b41ff1aSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3689b41ff1aSmrg		   }
3699b41ff1aSmrg		 }
3709b41ff1aSmrg	      then posix_mkdir=:
3719b41ff1aSmrg	      fi
3729b41ff1aSmrg	      rmdir "$tmpdir/d" "$tmpdir"
3739b41ff1aSmrg	    else
3749b41ff1aSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
3759b41ff1aSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3769b41ff1aSmrg	    fi
3779b41ff1aSmrg	    trap '' 0;;
3789b41ff1aSmrg	esac;;
3799b41ff1aSmrg    esac
380fdb3d228Smrg
3819b41ff1aSmrg    if
3829b41ff1aSmrg      $posix_mkdir && (
3839b41ff1aSmrg	umask $mkdir_umask &&
3849b41ff1aSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3859b41ff1aSmrg      )
3869b41ff1aSmrg    then :
3879b41ff1aSmrg    else
3889b41ff1aSmrg
3899b41ff1aSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3909b41ff1aSmrg      # or it failed possibly due to a race condition.  Create the
3919b41ff1aSmrg      # directory the slow way, step by step, checking for races as we go.
3929b41ff1aSmrg
3939b41ff1aSmrg      case $dstdir in
3949b41ff1aSmrg	/*) prefix='/';;
3957d575c90Smrg	[-=\(\)!]*) prefix='./';;
3969b41ff1aSmrg	*)  prefix='';;
3979b41ff1aSmrg      esac
3989b41ff1aSmrg
3999b41ff1aSmrg      eval "$initialize_posix_glob"
4009b41ff1aSmrg
4019b41ff1aSmrg      oIFS=$IFS
4029b41ff1aSmrg      IFS=/
4039b41ff1aSmrg      $posix_glob set -f
4049b41ff1aSmrg      set fnord $dstdir
4059b41ff1aSmrg      shift
4069b41ff1aSmrg      $posix_glob set +f
4079b41ff1aSmrg      IFS=$oIFS
4089b41ff1aSmrg
4099b41ff1aSmrg      prefixes=
4109b41ff1aSmrg
4119b41ff1aSmrg      for d
4129b41ff1aSmrg      do
4137d575c90Smrg	test X"$d" = X && continue
4149b41ff1aSmrg
4159b41ff1aSmrg	prefix=$prefix$d
4169b41ff1aSmrg	if test -d "$prefix"; then
4179b41ff1aSmrg	  prefixes=
4189b41ff1aSmrg	else
4199b41ff1aSmrg	  if $posix_mkdir; then
4209b41ff1aSmrg	    (umask=$mkdir_umask &&
4219b41ff1aSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4229b41ff1aSmrg	    # Don't fail if two instances are running concurrently.
4239b41ff1aSmrg	    test -d "$prefix" || exit 1
4249b41ff1aSmrg	  else
4259b41ff1aSmrg	    case $prefix in
4269b41ff1aSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4279b41ff1aSmrg	      *) qprefix=$prefix;;
4289b41ff1aSmrg	    esac
4299b41ff1aSmrg	    prefixes="$prefixes '$qprefix'"
4309b41ff1aSmrg	  fi
4319b41ff1aSmrg	fi
4329b41ff1aSmrg	prefix=$prefix/
4339b41ff1aSmrg      done
4349b41ff1aSmrg
4359b41ff1aSmrg      if test -n "$prefixes"; then
4369b41ff1aSmrg	# Don't fail if two instances are running concurrently.
4379b41ff1aSmrg	(umask $mkdir_umask &&
4389b41ff1aSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4399b41ff1aSmrg	  test -d "$dstdir" || exit 1
4409b41ff1aSmrg	obsolete_mkdir_used=true
4419b41ff1aSmrg      fi
4429b41ff1aSmrg    fi
4439b41ff1aSmrg  fi
4449b41ff1aSmrg
4459b41ff1aSmrg  if test -n "$dir_arg"; then
4469b41ff1aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4479b41ff1aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4489b41ff1aSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4499b41ff1aSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4509b41ff1aSmrg  else
4519b41ff1aSmrg
4529b41ff1aSmrg    # Make a couple of temp file names in the proper directory.
4539b41ff1aSmrg    dsttmp=$dstdir/_inst.$$_
4549b41ff1aSmrg    rmtmp=$dstdir/_rm.$$_
4559b41ff1aSmrg
4569b41ff1aSmrg    # Trap to clean up those temp files at exit.
4579b41ff1aSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4589b41ff1aSmrg
4599b41ff1aSmrg    # Copy the file name to the temp name.
4609b41ff1aSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4619b41ff1aSmrg
4629b41ff1aSmrg    # and set any options; do chmod last to preserve setuid bits.
4639b41ff1aSmrg    #
4649b41ff1aSmrg    # If any of these fail, we abort the whole thing.  If we want to
4659b41ff1aSmrg    # ignore errors from any of these, just make sure not to ignore
4669b41ff1aSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4679b41ff1aSmrg    #
4689b41ff1aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4699b41ff1aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4709b41ff1aSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4719b41ff1aSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4729b41ff1aSmrg
4739b41ff1aSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4749b41ff1aSmrg    if $copy_on_change &&
4759b41ff1aSmrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
4769b41ff1aSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
4779b41ff1aSmrg
4789b41ff1aSmrg       eval "$initialize_posix_glob" &&
4799b41ff1aSmrg       $posix_glob set -f &&
4809b41ff1aSmrg       set X $old && old=:$2:$4:$5:$6 &&
4819b41ff1aSmrg       set X $new && new=:$2:$4:$5:$6 &&
4829b41ff1aSmrg       $posix_glob set +f &&
4839b41ff1aSmrg
4849b41ff1aSmrg       test "$old" = "$new" &&
4859b41ff1aSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4869b41ff1aSmrg    then
4879b41ff1aSmrg      rm -f "$dsttmp"
4889b41ff1aSmrg    else
4899b41ff1aSmrg      # Rename the file to the real destination.
4909b41ff1aSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4919b41ff1aSmrg
4929b41ff1aSmrg      # The rename failed, perhaps because mv can't rename something else
4939b41ff1aSmrg      # to itself, or perhaps because mv is so ancient that it does not
4949b41ff1aSmrg      # support -f.
4959b41ff1aSmrg      {
4969b41ff1aSmrg	# Now remove or move aside any old file at destination location.
4979b41ff1aSmrg	# We try this two ways since rm can't unlink itself on some
4989b41ff1aSmrg	# systems and the destination file might be busy for other
4999b41ff1aSmrg	# reasons.  In this case, the final cleanup might fail but the new
5009b41ff1aSmrg	# file should still install successfully.
5019b41ff1aSmrg	{
5029b41ff1aSmrg	  test ! -f "$dst" ||
5039b41ff1aSmrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
5049b41ff1aSmrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
5059b41ff1aSmrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
5069b41ff1aSmrg	  } ||
5079b41ff1aSmrg	  { echo "$0: cannot unlink or rename $dst" >&2
5089b41ff1aSmrg	    (exit 1); exit 1
5099b41ff1aSmrg	  }
5109b41ff1aSmrg	} &&
5119b41ff1aSmrg
5129b41ff1aSmrg	# Now rename the file to the real destination.
5139b41ff1aSmrg	$doit $mvcmd "$dsttmp" "$dst"
5149b41ff1aSmrg      }
5159b41ff1aSmrg    fi || exit 1
5169b41ff1aSmrg
5179b41ff1aSmrg    trap '' 0
5189b41ff1aSmrg  fi
5199b41ff1aSmrgdone
520fdb3d228Smrg
5219b41ff1aSmrg# Local variables:
5229b41ff1aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
5239b41ff1aSmrg# time-stamp-start: "scriptversion="
5249b41ff1aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
5259b41ff1aSmrg# time-stamp-time-zone: "UTC"
5269b41ff1aSmrg# time-stamp-end: "; # UTC"
5279b41ff1aSmrg# End:
528