install-sh revision f55e6a01
1c35d236eSmrg#!/bin/sh
2c35d236eSmrg# install - install a program, script, or datafile
3c35d236eSmrg
4f55e6a01Smrgscriptversion=2006-12-25.00
5c35d236eSmrg
6c35d236eSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7c35d236eSmrg# later released in X11R6 (xc/config/util/install.sh) with the
8c35d236eSmrg# following copyright and license.
9c35d236eSmrg#
10c35d236eSmrg# Copyright (C) 1994 X Consortium
11c35d236eSmrg#
12c35d236eSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13c35d236eSmrg# of this software and associated documentation files (the "Software"), to
14c35d236eSmrg# deal in the Software without restriction, including without limitation the
15c35d236eSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16c35d236eSmrg# sell copies of the Software, and to permit persons to whom the Software is
17c35d236eSmrg# furnished to do so, subject to the following conditions:
18c35d236eSmrg#
19c35d236eSmrg# The above copyright notice and this permission notice shall be included in
20c35d236eSmrg# all copies or substantial portions of the Software.
21c35d236eSmrg#
22c35d236eSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23c35d236eSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24c35d236eSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25c35d236eSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26c35d236eSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27c35d236eSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28c35d236eSmrg#
29c35d236eSmrg# Except as contained in this notice, the name of the X Consortium shall not
30c35d236eSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
31c35d236eSmrg# ings in this Software without prior written authorization from the X Consor-
32c35d236eSmrg# tium.
33c35d236eSmrg#
34c35d236eSmrg#
35c35d236eSmrg# FSF changes to this file are in the public domain.
36c35d236eSmrg#
37c35d236eSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38c35d236eSmrg# `make' implicit rules from creating a file called install from it
39c35d236eSmrg# when there is no Makefile.
40c35d236eSmrg#
41c35d236eSmrg# This script is compatible with the BSD install script, but was written
424f6cd06fSmrg# from scratch.
434f6cd06fSmrg
444f6cd06fSmrgnl='
454f6cd06fSmrg'
464f6cd06fSmrgIFS=" ""	$nl"
47c35d236eSmrg
48c35d236eSmrg# set DOITPROG to echo to test this script
49c35d236eSmrg
50c35d236eSmrg# Don't use :- since 4.3BSD and earlier shells don't like it.
51f55e6a01Smrgdoit=${DOITPROG-}
524f6cd06fSmrgif test -z "$doit"; then
534f6cd06fSmrg  doit_exec=exec
544f6cd06fSmrgelse
554f6cd06fSmrg  doit_exec=$doit
564f6cd06fSmrgfi
57c35d236eSmrg
584f6cd06fSmrg# Put in absolute file names if you don't have them in your path;
594f6cd06fSmrg# or use environment vars.
60c35d236eSmrg
61f55e6a01Smrgchgrpprog=${CHGRPPROG-chgrp}
62f55e6a01Smrgchmodprog=${CHMODPROG-chmod}
63f55e6a01Smrgchownprog=${CHOWNPROG-chown}
64f55e6a01Smrgcmpprog=${CMPPROG-cmp}
65f55e6a01Smrgcpprog=${CPPROG-cp}
66f55e6a01Smrgmkdirprog=${MKDIRPROG-mkdir}
67f55e6a01Smrgmvprog=${MVPROG-mv}
68f55e6a01Smrgrmprog=${RMPROG-rm}
69f55e6a01Smrgstripprog=${STRIPPROG-strip}
70f55e6a01Smrg
71f55e6a01Smrgposix_glob='?'
72f55e6a01Smrginitialize_posix_glob='
73f55e6a01Smrg  test "$posix_glob" != "?" || {
74f55e6a01Smrg    if (set -f) 2>/dev/null; then
75f55e6a01Smrg      posix_glob=
76f55e6a01Smrg    else
77f55e6a01Smrg      posix_glob=:
78f55e6a01Smrg    fi
79f55e6a01Smrg  }
80f55e6a01Smrg'
81c35d236eSmrg
824f6cd06fSmrgposix_mkdir=
834f6cd06fSmrg
844f6cd06fSmrg# Desired mode of installed file.
854f6cd06fSmrgmode=0755
864f6cd06fSmrg
87f55e6a01Smrgchgrpcmd=
884f6cd06fSmrgchmodcmd=$chmodprog
89c35d236eSmrgchowncmd=
90f55e6a01Smrgmvcmd=$mvprog
91c35d236eSmrgrmcmd="$rmprog -f"
92f55e6a01Smrgstripcmd=
93f55e6a01Smrg
94c35d236eSmrgsrc=
95c35d236eSmrgdst=
96c35d236eSmrgdir_arg=
97f55e6a01Smrgdst_arg=
98f55e6a01Smrg
99f55e6a01Smrgcopy_on_change=false
100c35d236eSmrgno_target_directory=
101c35d236eSmrg
102f55e6a01Smrgusage="\
103f55e6a01SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
104c35d236eSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
105c35d236eSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
106c35d236eSmrg   or: $0 [OPTION]... -d DIRECTORIES...
107c35d236eSmrg
108c35d236eSmrgIn the 1st form, copy SRCFILE to DSTFILE.
109c35d236eSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
110c35d236eSmrgIn the 4th, create DIRECTORIES.
111c35d236eSmrg
112c35d236eSmrgOptions:
113f55e6a01Smrg     --help     display this help and exit.
114f55e6a01Smrg     --version  display version info and exit.
115f55e6a01Smrg
116f55e6a01Smrg  -c            (ignored)
117f55e6a01Smrg  -C            install only if different (preserve the last data modification time)
118f55e6a01Smrg  -d            create directories instead of installing files.
119f55e6a01Smrg  -g GROUP      $chgrpprog installed files to GROUP.
120f55e6a01Smrg  -m MODE       $chmodprog installed files to MODE.
121f55e6a01Smrg  -o USER       $chownprog installed files to USER.
122f55e6a01Smrg  -s            $stripprog installed files.
123f55e6a01Smrg  -t DIRECTORY  install into DIRECTORY.
124f55e6a01Smrg  -T            report an error if DSTFILE is a directory.
125c35d236eSmrg
126c35d236eSmrgEnvironment variables override the default commands:
127f55e6a01Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
128f55e6a01Smrg  RMPROG STRIPPROG
129c35d236eSmrg"
130c35d236eSmrg
1314f6cd06fSmrgwhile test $# -ne 0; do
132c35d236eSmrg  case $1 in
133f55e6a01Smrg    -c) ;;
134f55e6a01Smrg
135f55e6a01Smrg    -C) copy_on_change=true;;
136c35d236eSmrg
137f55e6a01Smrg    -d) dir_arg=true;;
138c35d236eSmrg
139c35d236eSmrg    -g) chgrpcmd="$chgrpprog $2"
140f55e6a01Smrg	shift;;
141c35d236eSmrg
142c35d236eSmrg    --help) echo "$usage"; exit $?;;
143c35d236eSmrg
1444f6cd06fSmrg    -m) mode=$2
1454f6cd06fSmrg	case $mode in
1464f6cd06fSmrg	  *' '* | *'	'* | *'
1474f6cd06fSmrg'*	  | *'*'* | *'?'* | *'['*)
1484f6cd06fSmrg	    echo "$0: invalid mode: $mode" >&2
1494f6cd06fSmrg	    exit 1;;
1504f6cd06fSmrg	esac
151f55e6a01Smrg	shift;;
152c35d236eSmrg
153c35d236eSmrg    -o) chowncmd="$chownprog $2"
154f55e6a01Smrg	shift;;
155c35d236eSmrg
156f55e6a01Smrg    -s) stripcmd=$stripprog;;
157c35d236eSmrg
158f55e6a01Smrg    -t) dst_arg=$2
159f55e6a01Smrg	shift;;
160c35d236eSmrg
161f55e6a01Smrg    -T) no_target_directory=true;;
162c35d236eSmrg
163c35d236eSmrg    --version) echo "$0 $scriptversion"; exit $?;;
164c35d236eSmrg
1654f6cd06fSmrg    --)	shift
166c35d236eSmrg	break;;
1674f6cd06fSmrg
1684f6cd06fSmrg    -*)	echo "$0: invalid option: $1" >&2
1694f6cd06fSmrg	exit 1;;
1704f6cd06fSmrg
1714f6cd06fSmrg    *)  break;;
172c35d236eSmrg  esac
173f55e6a01Smrg  shift
174c35d236eSmrgdone
175c35d236eSmrg
176f55e6a01Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1774f6cd06fSmrg  # When -d is used, all remaining arguments are directories to create.
1784f6cd06fSmrg  # When -t is used, the destination is already specified.
1794f6cd06fSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1804f6cd06fSmrg  for arg
1814f6cd06fSmrg  do
182f55e6a01Smrg    if test -n "$dst_arg"; then
1834f6cd06fSmrg      # $@ is not empty: it contains at least $arg.
184f55e6a01Smrg      set fnord "$@" "$dst_arg"
1854f6cd06fSmrg      shift # fnord
1864f6cd06fSmrg    fi
1874f6cd06fSmrg    shift # arg
188f55e6a01Smrg    dst_arg=$arg
1894f6cd06fSmrg  done
1904f6cd06fSmrgfi
1914f6cd06fSmrg
1924f6cd06fSmrgif test $# -eq 0; then
193c35d236eSmrg  if test -z "$dir_arg"; then
194c35d236eSmrg    echo "$0: no input file specified." >&2
195c35d236eSmrg    exit 1
196c35d236eSmrg  fi
197c35d236eSmrg  # It's OK to call `install-sh -d' without argument.
198c35d236eSmrg  # This can happen when creating conditional directories.
199c35d236eSmrg  exit 0
200c35d236eSmrgfi
201c35d236eSmrg
2024f6cd06fSmrgif test -z "$dir_arg"; then
2034f6cd06fSmrg  trap '(exit $?); exit' 1 2 13 15
2044f6cd06fSmrg
2054f6cd06fSmrg  # Set umask so as not to create temps with too-generous modes.
2064f6cd06fSmrg  # However, 'strip' requires both read and write access to temps.
2074f6cd06fSmrg  case $mode in
2084f6cd06fSmrg    # Optimize common cases.
2094f6cd06fSmrg    *644) cp_umask=133;;
2104f6cd06fSmrg    *755) cp_umask=22;;
2114f6cd06fSmrg
2124f6cd06fSmrg    *[0-7])
2134f6cd06fSmrg      if test -z "$stripcmd"; then
2144f6cd06fSmrg	u_plus_rw=
2154f6cd06fSmrg      else
2164f6cd06fSmrg	u_plus_rw='% 200'
2174f6cd06fSmrg      fi
2184f6cd06fSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2194f6cd06fSmrg    *)
2204f6cd06fSmrg      if test -z "$stripcmd"; then
2214f6cd06fSmrg	u_plus_rw=
2224f6cd06fSmrg      else
2234f6cd06fSmrg	u_plus_rw=,u+rw
2244f6cd06fSmrg      fi
2254f6cd06fSmrg      cp_umask=$mode$u_plus_rw;;
2264f6cd06fSmrg  esac
2274f6cd06fSmrgfi
2284f6cd06fSmrg
229c35d236eSmrgfor src
230c35d236eSmrgdo
231c35d236eSmrg  # Protect names starting with `-'.
232c35d236eSmrg  case $src in
233f55e6a01Smrg    -*) src=./$src;;
234c35d236eSmrg  esac
235c35d236eSmrg
236c35d236eSmrg  if test -n "$dir_arg"; then
237c35d236eSmrg    dst=$src
2384f6cd06fSmrg    dstdir=$dst
2394f6cd06fSmrg    test -d "$dstdir"
2404f6cd06fSmrg    dstdir_status=$?
241c35d236eSmrg  else
2424f6cd06fSmrg
243c35d236eSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
244c35d236eSmrg    # might cause directories to be created, which would be especially bad
245c35d236eSmrg    # if $src (and thus $dsttmp) contains '*'.
246c35d236eSmrg    if test ! -f "$src" && test ! -d "$src"; then
247c35d236eSmrg      echo "$0: $src does not exist." >&2
248c35d236eSmrg      exit 1
249c35d236eSmrg    fi
250c35d236eSmrg
251f55e6a01Smrg    if test -z "$dst_arg"; then
252c35d236eSmrg      echo "$0: no destination specified." >&2
253c35d236eSmrg      exit 1
254c35d236eSmrg    fi
255c35d236eSmrg
256f55e6a01Smrg    dst=$dst_arg
257c35d236eSmrg    # Protect names starting with `-'.
258c35d236eSmrg    case $dst in
259f55e6a01Smrg      -*) dst=./$dst;;
260c35d236eSmrg    esac
261c35d236eSmrg
262c35d236eSmrg    # If destination is a directory, append the input filename; won't work
263c35d236eSmrg    # if double slashes aren't ignored.
264c35d236eSmrg    if test -d "$dst"; then
265c35d236eSmrg      if test -n "$no_target_directory"; then
266f55e6a01Smrg	echo "$0: $dst_arg: Is a directory" >&2
267c35d236eSmrg	exit 1
268c35d236eSmrg      fi
2694f6cd06fSmrg      dstdir=$dst
2704f6cd06fSmrg      dst=$dstdir/`basename "$src"`
2714f6cd06fSmrg      dstdir_status=0
2724f6cd06fSmrg    else
2734f6cd06fSmrg      # Prefer dirname, but fall back on a substitute if dirname fails.
2744f6cd06fSmrg      dstdir=`
2754f6cd06fSmrg	(dirname "$dst") 2>/dev/null ||
2764f6cd06fSmrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
2774f6cd06fSmrg	     X"$dst" : 'X\(//\)[^/]' \| \
2784f6cd06fSmrg	     X"$dst" : 'X\(//\)$' \| \
2794f6cd06fSmrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
2804f6cd06fSmrg	echo X"$dst" |
2814f6cd06fSmrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
2824f6cd06fSmrg		   s//\1/
2834f6cd06fSmrg		   q
2844f6cd06fSmrg		 }
2854f6cd06fSmrg		 /^X\(\/\/\)[^/].*/{
2864f6cd06fSmrg		   s//\1/
2874f6cd06fSmrg		   q
2884f6cd06fSmrg		 }
2894f6cd06fSmrg		 /^X\(\/\/\)$/{
2904f6cd06fSmrg		   s//\1/
2914f6cd06fSmrg		   q
2924f6cd06fSmrg		 }
2934f6cd06fSmrg		 /^X\(\/\).*/{
2944f6cd06fSmrg		   s//\1/
2954f6cd06fSmrg		   q
2964f6cd06fSmrg		 }
2974f6cd06fSmrg		 s/.*/./; q'
2984f6cd06fSmrg      `
2994f6cd06fSmrg
3004f6cd06fSmrg      test -d "$dstdir"
3014f6cd06fSmrg      dstdir_status=$?
302c35d236eSmrg    fi
303c35d236eSmrg  fi
304c35d236eSmrg
3054f6cd06fSmrg  obsolete_mkdir_used=false
3064f6cd06fSmrg
3074f6cd06fSmrg  if test $dstdir_status != 0; then
3084f6cd06fSmrg    case $posix_mkdir in
3094f6cd06fSmrg      '')
3104f6cd06fSmrg	# Create intermediate dirs using mode 755 as modified by the umask.
3114f6cd06fSmrg	# This is like FreeBSD 'install' as of 1997-10-28.
3124f6cd06fSmrg	umask=`umask`
3134f6cd06fSmrg	case $stripcmd.$umask in
3144f6cd06fSmrg	  # Optimize common cases.
3154f6cd06fSmrg	  *[2367][2367]) mkdir_umask=$umask;;
3164f6cd06fSmrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3174f6cd06fSmrg
3184f6cd06fSmrg	  *[0-7])
3194f6cd06fSmrg	    mkdir_umask=`expr $umask + 22 \
3204f6cd06fSmrg	      - $umask % 100 % 40 + $umask % 20 \
3214f6cd06fSmrg	      - $umask % 10 % 4 + $umask % 2
3224f6cd06fSmrg	    `;;
3234f6cd06fSmrg	  *) mkdir_umask=$umask,go-w;;
3244f6cd06fSmrg	esac
3254f6cd06fSmrg
3264f6cd06fSmrg	# With -d, create the new directory with the user-specified mode.
3274f6cd06fSmrg	# Otherwise, rely on $mkdir_umask.
3284f6cd06fSmrg	if test -n "$dir_arg"; then
3294f6cd06fSmrg	  mkdir_mode=-m$mode
3304f6cd06fSmrg	else
3314f6cd06fSmrg	  mkdir_mode=
3324f6cd06fSmrg	fi
3334f6cd06fSmrg
3344f6cd06fSmrg	posix_mkdir=false
3354f6cd06fSmrg	case $umask in
3364f6cd06fSmrg	  *[123567][0-7][0-7])
3374f6cd06fSmrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
3384f6cd06fSmrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3394f6cd06fSmrg	    ;;
3404f6cd06fSmrg	  *)
3414f6cd06fSmrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3424f6cd06fSmrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3434f6cd06fSmrg
3444f6cd06fSmrg	    if (umask $mkdir_umask &&
3454f6cd06fSmrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3464f6cd06fSmrg	    then
3474f6cd06fSmrg	      if test -z "$dir_arg" || {
3484f6cd06fSmrg		   # Check for POSIX incompatibilities with -m.
3494f6cd06fSmrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3504f6cd06fSmrg		   # other-writeable bit of parent directory when it shouldn't.
3514f6cd06fSmrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3524f6cd06fSmrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3534f6cd06fSmrg		   case $ls_ld_tmpdir in
3544f6cd06fSmrg		     d????-?r-*) different_mode=700;;
3554f6cd06fSmrg		     d????-?--*) different_mode=755;;
3564f6cd06fSmrg		     *) false;;
3574f6cd06fSmrg		   esac &&
3584f6cd06fSmrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3594f6cd06fSmrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3604f6cd06fSmrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3614f6cd06fSmrg		   }
3624f6cd06fSmrg		 }
3634f6cd06fSmrg	      then posix_mkdir=:
3644f6cd06fSmrg	      fi
3654f6cd06fSmrg	      rmdir "$tmpdir/d" "$tmpdir"
3664f6cd06fSmrg	    else
3674f6cd06fSmrg	      # Remove any dirs left behind by ancient mkdir implementations.
3684f6cd06fSmrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3694f6cd06fSmrg	    fi
3704f6cd06fSmrg	    trap '' 0;;
3714f6cd06fSmrg	esac;;
3724f6cd06fSmrg    esac
373c35d236eSmrg
3744f6cd06fSmrg    if
3754f6cd06fSmrg      $posix_mkdir && (
3764f6cd06fSmrg	umask $mkdir_umask &&
3774f6cd06fSmrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3784f6cd06fSmrg      )
3794f6cd06fSmrg    then :
3804f6cd06fSmrg    else
381c35d236eSmrg
3824f6cd06fSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3834f6cd06fSmrg      # or it failed possibly due to a race condition.  Create the
3844f6cd06fSmrg      # directory the slow way, step by step, checking for races as we go.
3854f6cd06fSmrg
3864f6cd06fSmrg      case $dstdir in
387f55e6a01Smrg	/*) prefix='/';;
388f55e6a01Smrg	-*) prefix='./';;
389f55e6a01Smrg	*)  prefix='';;
3904f6cd06fSmrg      esac
3914f6cd06fSmrg
392f55e6a01Smrg      eval "$initialize_posix_glob"
3934f6cd06fSmrg
3944f6cd06fSmrg      oIFS=$IFS
3954f6cd06fSmrg      IFS=/
396f55e6a01Smrg      $posix_glob set -f
3974f6cd06fSmrg      set fnord $dstdir
398c35d236eSmrg      shift
399f55e6a01Smrg      $posix_glob set +f
4004f6cd06fSmrg      IFS=$oIFS
4014f6cd06fSmrg
4024f6cd06fSmrg      prefixes=
4034f6cd06fSmrg
4044f6cd06fSmrg      for d
4054f6cd06fSmrg      do
4064f6cd06fSmrg	test -z "$d" && continue
4074f6cd06fSmrg
4084f6cd06fSmrg	prefix=$prefix$d
4094f6cd06fSmrg	if test -d "$prefix"; then
4104f6cd06fSmrg	  prefixes=
4114f6cd06fSmrg	else
4124f6cd06fSmrg	  if $posix_mkdir; then
4134f6cd06fSmrg	    (umask=$mkdir_umask &&
4144f6cd06fSmrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
4154f6cd06fSmrg	    # Don't fail if two instances are running concurrently.
4164f6cd06fSmrg	    test -d "$prefix" || exit 1
4174f6cd06fSmrg	  else
4184f6cd06fSmrg	    case $prefix in
4194f6cd06fSmrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4204f6cd06fSmrg	      *) qprefix=$prefix;;
4214f6cd06fSmrg	    esac
4224f6cd06fSmrg	    prefixes="$prefixes '$qprefix'"
4234f6cd06fSmrg	  fi
4244f6cd06fSmrg	fi
4254f6cd06fSmrg	prefix=$prefix/
4264f6cd06fSmrg      done
4274f6cd06fSmrg
4284f6cd06fSmrg      if test -n "$prefixes"; then
4294f6cd06fSmrg	# Don't fail if two instances are running concurrently.
4304f6cd06fSmrg	(umask $mkdir_umask &&
4314f6cd06fSmrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
4324f6cd06fSmrg	  test -d "$dstdir" || exit 1
4334f6cd06fSmrg	obsolete_mkdir_used=true
434c35d236eSmrg      fi
4354f6cd06fSmrg    fi
436c35d236eSmrg  fi
437c35d236eSmrg
438c35d236eSmrg  if test -n "$dir_arg"; then
4394f6cd06fSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4404f6cd06fSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4414f6cd06fSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4424f6cd06fSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
443c35d236eSmrg  else
444c35d236eSmrg
445c35d236eSmrg    # Make a couple of temp file names in the proper directory.
446c35d236eSmrg    dsttmp=$dstdir/_inst.$$_
447c35d236eSmrg    rmtmp=$dstdir/_rm.$$_
448c35d236eSmrg
449c35d236eSmrg    # Trap to clean up those temp files at exit.
450c35d236eSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
451c35d236eSmrg
452c35d236eSmrg    # Copy the file name to the temp name.
4534f6cd06fSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
454c35d236eSmrg
455c35d236eSmrg    # and set any options; do chmod last to preserve setuid bits.
456c35d236eSmrg    #
457c35d236eSmrg    # If any of these fail, we abort the whole thing.  If we want to
458c35d236eSmrg    # ignore errors from any of these, just make sure not to ignore
459c35d236eSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
460c35d236eSmrg    #
461f55e6a01Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
462f55e6a01Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
463f55e6a01Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
464f55e6a01Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
465f55e6a01Smrg
466f55e6a01Smrg    # If -C, don't bother to copy if it wouldn't change the file.
467f55e6a01Smrg    if $copy_on_change &&
468f55e6a01Smrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
469f55e6a01Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
470f55e6a01Smrg
471f55e6a01Smrg       eval "$initialize_posix_glob" &&
472f55e6a01Smrg       $posix_glob set -f &&
473f55e6a01Smrg       set X $old && old=:$2:$4:$5:$6 &&
474f55e6a01Smrg       set X $new && new=:$2:$4:$5:$6 &&
475f55e6a01Smrg       $posix_glob set +f &&
476f55e6a01Smrg
477f55e6a01Smrg       test "$old" = "$new" &&
478f55e6a01Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
479f55e6a01Smrg    then
480f55e6a01Smrg      rm -f "$dsttmp"
481f55e6a01Smrg    else
482f55e6a01Smrg      # Rename the file to the real destination.
483f55e6a01Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
484f55e6a01Smrg
485f55e6a01Smrg      # The rename failed, perhaps because mv can't rename something else
486f55e6a01Smrg      # to itself, or perhaps because mv is so ancient that it does not
487f55e6a01Smrg      # support -f.
488f55e6a01Smrg      {
489f55e6a01Smrg	# Now remove or move aside any old file at destination location.
490f55e6a01Smrg	# We try this two ways since rm can't unlink itself on some
491f55e6a01Smrg	# systems and the destination file might be busy for other
492f55e6a01Smrg	# reasons.  In this case, the final cleanup might fail but the new
493f55e6a01Smrg	# file should still install successfully.
494f55e6a01Smrg	{
495f55e6a01Smrg	  test ! -f "$dst" ||
496f55e6a01Smrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
497f55e6a01Smrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
498f55e6a01Smrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
499f55e6a01Smrg	  } ||
500f55e6a01Smrg	  { echo "$0: cannot unlink or rename $dst" >&2
501f55e6a01Smrg	    (exit 1); exit 1
502f55e6a01Smrg	  }
503f55e6a01Smrg	} &&
504f55e6a01Smrg
505f55e6a01Smrg	# Now rename the file to the real destination.
506f55e6a01Smrg	$doit $mvcmd "$dsttmp" "$dst"
507f55e6a01Smrg      }
508f55e6a01Smrg    fi || exit 1
509c35d236eSmrg
5104f6cd06fSmrg    trap '' 0
5114f6cd06fSmrg  fi
5124f6cd06fSmrgdone
513c35d236eSmrg
514c35d236eSmrg# Local variables:
515c35d236eSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
516c35d236eSmrg# time-stamp-start: "scriptversion="
517c35d236eSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
518c35d236eSmrg# time-stamp-end: "$"
519c35d236eSmrg# End:
520