install-sh revision 43c16309
1ffab5952Smrg#!/bin/sh
2ffab5952Smrg# install - install a program, script, or datafile
3ffab5952Smrg
443c16309Smrgscriptversion=2011-01-19.21; # UTC
5ffab5952Smrg
6ffab5952Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7ffab5952Smrg# later released in X11R6 (xc/config/util/install.sh) with the
8ffab5952Smrg# following copyright and license.
9ffab5952Smrg#
10ffab5952Smrg# Copyright (C) 1994 X Consortium
11ffab5952Smrg#
12ffab5952Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13ffab5952Smrg# of this software and associated documentation files (the "Software"), to
14ffab5952Smrg# deal in the Software without restriction, including without limitation the
15ffab5952Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16ffab5952Smrg# sell copies of the Software, and to permit persons to whom the Software is
17ffab5952Smrg# furnished to do so, subject to the following conditions:
18ffab5952Smrg#
19ffab5952Smrg# The above copyright notice and this permission notice shall be included in
20ffab5952Smrg# all copies or substantial portions of the Software.
21ffab5952Smrg#
22ffab5952Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23ffab5952Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24ffab5952Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25ffab5952Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26ffab5952Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27ffab5952Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28ffab5952Smrg#
29ffab5952Smrg# Except as contained in this notice, the name of the X Consortium shall not
30ffab5952Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
31ffab5952Smrg# ings in this Software without prior written authorization from the X Consor-
32ffab5952Smrg# tium.
33ffab5952Smrg#
34ffab5952Smrg#
35ffab5952Smrg# FSF changes to this file are in the public domain.
36ffab5952Smrg#
37ffab5952Smrg# Calling this script install-sh is preferred over install.sh, to prevent
38ffab5952Smrg# `make' implicit rules from creating a file called install from it
39ffab5952Smrg# when there is no Makefile.
40ffab5952Smrg#
41ffab5952Smrg# This script is compatible with the BSD install script, but was written
42ffab5952Smrg# from scratch.
43ffab5952Smrg
44ffab5952Smrgnl='
45ffab5952Smrg'
46ffab5952SmrgIFS=" ""	$nl"
47ffab5952Smrg
48ffab5952Smrg# set DOITPROG to echo to test this script
49ffab5952Smrg
50ffab5952Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
51ffab5952Smrgdoit=${DOITPROG-}
52ffab5952Smrgif test -z "$doit"; then
53ffab5952Smrg  doit_exec=exec
54ffab5952Smrgelse
55ffab5952Smrg  doit_exec=$doit
56ffab5952Smrgfi
57ffab5952Smrg
58ffab5952Smrg# Put in absolute file names if you don't have them in your path;
59ffab5952Smrg# or use environment vars.
60ffab5952Smrg
61ffab5952Smrgchgrpprog=${CHGRPPROG-chgrp}
62ffab5952Smrgchmodprog=${CHMODPROG-chmod}
63ffab5952Smrgchownprog=${CHOWNPROG-chown}
64ffab5952Smrgcmpprog=${CMPPROG-cmp}
65ffab5952Smrgcpprog=${CPPROG-cp}
66ffab5952Smrgmkdirprog=${MKDIRPROG-mkdir}
67ffab5952Smrgmvprog=${MVPROG-mv}
68ffab5952Smrgrmprog=${RMPROG-rm}
69ffab5952Smrgstripprog=${STRIPPROG-strip}
70ffab5952Smrg
71ffab5952Smrgposix_glob='?'
72ffab5952Smrginitialize_posix_glob='
73ffab5952Smrg  test "$posix_glob" != "?" || {
74ffab5952Smrg    if (set -f) 2>/dev/null; then
75ffab5952Smrg      posix_glob=
76ffab5952Smrg    else
77ffab5952Smrg      posix_glob=:
78ffab5952Smrg    fi
79ffab5952Smrg  }
80ffab5952Smrg'
81ffab5952Smrg
82ffab5952Smrgposix_mkdir=
83ffab5952Smrg
84ffab5952Smrg# Desired mode of installed file.
85ffab5952Smrgmode=0755
86ffab5952Smrg
87ffab5952Smrgchgrpcmd=
88ffab5952Smrgchmodcmd=$chmodprog
89ffab5952Smrgchowncmd=
90ffab5952Smrgmvcmd=$mvprog
91ffab5952Smrgrmcmd="$rmprog -f"
92ffab5952Smrgstripcmd=
93ffab5952Smrg
94ffab5952Smrgsrc=
95ffab5952Smrgdst=
96ffab5952Smrgdir_arg=
97ffab5952Smrgdst_arg=
98ffab5952Smrg
99ffab5952Smrgcopy_on_change=false
100ffab5952Smrgno_target_directory=
101ffab5952Smrg
102ffab5952Smrgusage="\
103ffab5952SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
104ffab5952Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
105ffab5952Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
106ffab5952Smrg   or: $0 [OPTION]... -d DIRECTORIES...
107ffab5952Smrg
108ffab5952SmrgIn the 1st form, copy SRCFILE to DSTFILE.
109ffab5952SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
110ffab5952SmrgIn the 4th, create DIRECTORIES.
111ffab5952Smrg
112ffab5952SmrgOptions:
113ffab5952Smrg     --help     display this help and exit.
114ffab5952Smrg     --version  display version info and exit.
115ffab5952Smrg
116ffab5952Smrg  -c            (ignored)
117ffab5952Smrg  -C            install only if different (preserve the last data modification time)
118ffab5952Smrg  -d            create directories instead of installing files.
119ffab5952Smrg  -g GROUP      $chgrpprog installed files to GROUP.
120ffab5952Smrg  -m MODE       $chmodprog installed files to MODE.
121ffab5952Smrg  -o USER       $chownprog installed files to USER.
122ffab5952Smrg  -s            $stripprog installed files.
123ffab5952Smrg  -t DIRECTORY  install into DIRECTORY.
124ffab5952Smrg  -T            report an error if DSTFILE is a directory.
125ffab5952Smrg
126ffab5952SmrgEnvironment variables override the default commands:
127ffab5952Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
128ffab5952Smrg  RMPROG STRIPPROG
129ffab5952Smrg"
130ffab5952Smrg
131ffab5952Smrgwhile test $# -ne 0; do
132ffab5952Smrg  case $1 in
133ffab5952Smrg    -c) ;;
134ffab5952Smrg
135ffab5952Smrg    -C) copy_on_change=true;;
136ffab5952Smrg
137ffab5952Smrg    -d) dir_arg=true;;
138ffab5952Smrg
139ffab5952Smrg    -g) chgrpcmd="$chgrpprog $2"
140ffab5952Smrg	shift;;
141ffab5952Smrg
142ffab5952Smrg    --help) echo "$usage"; exit $?;;
143ffab5952Smrg
144ffab5952Smrg    -m) mode=$2
145ffab5952Smrg	case $mode in
146ffab5952Smrg	  *' '* | *'	'* | *'
147ffab5952Smrg'*	  | *'*'* | *'?'* | *'['*)
148ffab5952Smrg	    echo "$0: invalid mode: $mode" >&2
149ffab5952Smrg	    exit 1;;
150ffab5952Smrg	esac
151ffab5952Smrg	shift;;
152ffab5952Smrg
153ffab5952Smrg    -o) chowncmd="$chownprog $2"
154ffab5952Smrg	shift;;
155ffab5952Smrg
156ffab5952Smrg    -s) stripcmd=$stripprog;;
157ffab5952Smrg
158ffab5952Smrg    -t) dst_arg=$2
15943c16309Smrg	# Protect names problematic for `test' and other utilities.
16043c16309Smrg	case $dst_arg in
16143c16309Smrg	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
16243c16309Smrg	esac
163ffab5952Smrg	shift;;
164ffab5952Smrg
165ffab5952Smrg    -T) no_target_directory=true;;
166ffab5952Smrg
167ffab5952Smrg    --version) echo "$0 $scriptversion"; exit $?;;
168ffab5952Smrg
169ffab5952Smrg    --)	shift
170ffab5952Smrg	break;;
171ffab5952Smrg
172ffab5952Smrg    -*)	echo "$0: invalid option: $1" >&2
173ffab5952Smrg	exit 1;;
174ffab5952Smrg
175ffab5952Smrg    *)  break;;
176ffab5952Smrg  esac
177ffab5952Smrg  shift
178ffab5952Smrgdone
179ffab5952Smrg
180ffab5952Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
181ffab5952Smrg  # When -d is used, all remaining arguments are directories to create.
182ffab5952Smrg  # When -t is used, the destination is already specified.
183ffab5952Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
184ffab5952Smrg  for arg
185ffab5952Smrg  do
186ffab5952Smrg    if test -n "$dst_arg"; then
187ffab5952Smrg      # $@ is not empty: it contains at least $arg.
188ffab5952Smrg      set fnord "$@" "$dst_arg"
189ffab5952Smrg      shift # fnord
190ffab5952Smrg    fi
191ffab5952Smrg    shift # arg
192ffab5952Smrg    dst_arg=$arg
19343c16309Smrg    # Protect names problematic for `test' and other utilities.
19443c16309Smrg    case $dst_arg in
19543c16309Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
19643c16309Smrg    esac
197ffab5952Smrg  done
198ffab5952Smrgfi
199ffab5952Smrg
200ffab5952Smrgif test $# -eq 0; then
201ffab5952Smrg  if test -z "$dir_arg"; then
202ffab5952Smrg    echo "$0: no input file specified." >&2
203ffab5952Smrg    exit 1
204ffab5952Smrg  fi
205ffab5952Smrg  # It's OK to call `install-sh -d' without argument.
206ffab5952Smrg  # This can happen when creating conditional directories.
207ffab5952Smrg  exit 0
208ffab5952Smrgfi
209ffab5952Smrg
210ffab5952Smrgif test -z "$dir_arg"; then
21143c16309Smrg  do_exit='(exit $ret); exit $ret'
21243c16309Smrg  trap "ret=129; $do_exit" 1
21343c16309Smrg  trap "ret=130; $do_exit" 2
21443c16309Smrg  trap "ret=141; $do_exit" 13
21543c16309Smrg  trap "ret=143; $do_exit" 15
216ffab5952Smrg
217ffab5952Smrg  # Set umask so as not to create temps with too-generous modes.
218ffab5952Smrg  # However, 'strip' requires both read and write access to temps.
219ffab5952Smrg  case $mode in
220ffab5952Smrg    # Optimize common cases.
221ffab5952Smrg    *644) cp_umask=133;;
222ffab5952Smrg    *755) cp_umask=22;;
223ffab5952Smrg
224ffab5952Smrg    *[0-7])
225ffab5952Smrg      if test -z "$stripcmd"; then
226ffab5952Smrg	u_plus_rw=
227ffab5952Smrg      else
228ffab5952Smrg	u_plus_rw='% 200'
229ffab5952Smrg      fi
230ffab5952Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
231ffab5952Smrg    *)
232ffab5952Smrg      if test -z "$stripcmd"; then
233ffab5952Smrg	u_plus_rw=
234ffab5952Smrg      else
235ffab5952Smrg	u_plus_rw=,u+rw
236ffab5952Smrg      fi
237ffab5952Smrg      cp_umask=$mode$u_plus_rw;;
238ffab5952Smrg  esac
239ffab5952Smrgfi
240ffab5952Smrg
241ffab5952Smrgfor src
242ffab5952Smrgdo
24343c16309Smrg  # Protect names problematic for `test' and other utilities.
244ffab5952Smrg  case $src in
24543c16309Smrg    -* | [=\(\)!]) src=./$src;;
246ffab5952Smrg  esac
247ffab5952Smrg
248ffab5952Smrg  if test -n "$dir_arg"; then
249ffab5952Smrg    dst=$src
250ffab5952Smrg    dstdir=$dst
251ffab5952Smrg    test -d "$dstdir"
252ffab5952Smrg    dstdir_status=$?
253ffab5952Smrg  else
254ffab5952Smrg
255ffab5952Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
256ffab5952Smrg    # might cause directories to be created, which would be especially bad
257ffab5952Smrg    # if $src (and thus $dsttmp) contains '*'.
258ffab5952Smrg    if test ! -f "$src" && test ! -d "$src"; then
259ffab5952Smrg      echo "$0: $src does not exist." >&2
260ffab5952Smrg      exit 1
261ffab5952Smrg    fi
262ffab5952Smrg
263ffab5952Smrg    if test -z "$dst_arg"; then
264ffab5952Smrg      echo "$0: no destination specified." >&2
265ffab5952Smrg      exit 1
266ffab5952Smrg    fi
267ffab5952Smrg    dst=$dst_arg
268ffab5952Smrg
269ffab5952Smrg    # If destination is a directory, append the input filename; won't work
270ffab5952Smrg    # if double slashes aren't ignored.
271ffab5952Smrg    if test -d "$dst"; then
272ffab5952Smrg      if test -n "$no_target_directory"; then
273ffab5952Smrg	echo "$0: $dst_arg: Is a directory" >&2
274ffab5952Smrg	exit 1
275ffab5952Smrg      fi
276ffab5952Smrg      dstdir=$dst
277ffab5952Smrg      dst=$dstdir/`basename "$src"`
278ffab5952Smrg      dstdir_status=0
279ffab5952Smrg    else
280ffab5952Smrg      # Prefer dirname, but fall back on a substitute if dirname fails.
281ffab5952Smrg      dstdir=`
282ffab5952Smrg	(dirname "$dst") 2>/dev/null ||
283ffab5952Smrg	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
284ffab5952Smrg	     X"$dst" : 'X\(//\)[^/]' \| \
285ffab5952Smrg	     X"$dst" : 'X\(//\)$' \| \
286ffab5952Smrg	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
287ffab5952Smrg	echo X"$dst" |
288ffab5952Smrg	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
289ffab5952Smrg		   s//\1/
290ffab5952Smrg		   q
291ffab5952Smrg		 }
292ffab5952Smrg		 /^X\(\/\/\)[^/].*/{
293ffab5952Smrg		   s//\1/
294ffab5952Smrg		   q
295ffab5952Smrg		 }
296ffab5952Smrg		 /^X\(\/\/\)$/{
297ffab5952Smrg		   s//\1/
298ffab5952Smrg		   q
299ffab5952Smrg		 }
300ffab5952Smrg		 /^X\(\/\).*/{
301ffab5952Smrg		   s//\1/
302ffab5952Smrg		   q
303ffab5952Smrg		 }
304ffab5952Smrg		 s/.*/./; q'
305ffab5952Smrg      `
306ffab5952Smrg
307ffab5952Smrg      test -d "$dstdir"
308ffab5952Smrg      dstdir_status=$?
309ffab5952Smrg    fi
310ffab5952Smrg  fi
311ffab5952Smrg
312ffab5952Smrg  obsolete_mkdir_used=false
313ffab5952Smrg
314ffab5952Smrg  if test $dstdir_status != 0; then
315ffab5952Smrg    case $posix_mkdir in
316ffab5952Smrg      '')
317ffab5952Smrg	# Create intermediate dirs using mode 755 as modified by the umask.
318ffab5952Smrg	# This is like FreeBSD 'install' as of 1997-10-28.
319ffab5952Smrg	umask=`umask`
320ffab5952Smrg	case $stripcmd.$umask in
321ffab5952Smrg	  # Optimize common cases.
322ffab5952Smrg	  *[2367][2367]) mkdir_umask=$umask;;
323ffab5952Smrg	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
324ffab5952Smrg
325ffab5952Smrg	  *[0-7])
326ffab5952Smrg	    mkdir_umask=`expr $umask + 22 \
327ffab5952Smrg	      - $umask % 100 % 40 + $umask % 20 \
328ffab5952Smrg	      - $umask % 10 % 4 + $umask % 2
329ffab5952Smrg	    `;;
330ffab5952Smrg	  *) mkdir_umask=$umask,go-w;;
331ffab5952Smrg	esac
332ffab5952Smrg
333ffab5952Smrg	# With -d, create the new directory with the user-specified mode.
334ffab5952Smrg	# Otherwise, rely on $mkdir_umask.
335ffab5952Smrg	if test -n "$dir_arg"; then
336ffab5952Smrg	  mkdir_mode=-m$mode
337ffab5952Smrg	else
338ffab5952Smrg	  mkdir_mode=
339ffab5952Smrg	fi
340ffab5952Smrg
341ffab5952Smrg	posix_mkdir=false
342ffab5952Smrg	case $umask in
343ffab5952Smrg	  *[123567][0-7][0-7])
344ffab5952Smrg	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
345ffab5952Smrg	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
346ffab5952Smrg	    ;;
347ffab5952Smrg	  *)
348ffab5952Smrg	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
349ffab5952Smrg	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
350ffab5952Smrg
351ffab5952Smrg	    if (umask $mkdir_umask &&
352ffab5952Smrg		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
353ffab5952Smrg	    then
354ffab5952Smrg	      if test -z "$dir_arg" || {
355ffab5952Smrg		   # Check for POSIX incompatibilities with -m.
356ffab5952Smrg		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
357ffab5952Smrg		   # other-writeable bit of parent directory when it shouldn't.
358ffab5952Smrg		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
359ffab5952Smrg		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
360ffab5952Smrg		   case $ls_ld_tmpdir in
361ffab5952Smrg		     d????-?r-*) different_mode=700;;
362ffab5952Smrg		     d????-?--*) different_mode=755;;
363ffab5952Smrg		     *) false;;
364ffab5952Smrg		   esac &&
365ffab5952Smrg		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
366ffab5952Smrg		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
367ffab5952Smrg		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
368ffab5952Smrg		   }
369ffab5952Smrg		 }
370ffab5952Smrg	      then posix_mkdir=:
371ffab5952Smrg	      fi
372ffab5952Smrg	      rmdir "$tmpdir/d" "$tmpdir"
373ffab5952Smrg	    else
374ffab5952Smrg	      # Remove any dirs left behind by ancient mkdir implementations.
375ffab5952Smrg	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
376ffab5952Smrg	    fi
377ffab5952Smrg	    trap '' 0;;
378ffab5952Smrg	esac;;
379ffab5952Smrg    esac
380ffab5952Smrg
381ffab5952Smrg    if
382ffab5952Smrg      $posix_mkdir && (
383ffab5952Smrg	umask $mkdir_umask &&
384ffab5952Smrg	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
385ffab5952Smrg      )
386ffab5952Smrg    then :
387ffab5952Smrg    else
388ffab5952Smrg
389ffab5952Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
390ffab5952Smrg      # or it failed possibly due to a race condition.  Create the
391ffab5952Smrg      # directory the slow way, step by step, checking for races as we go.
392ffab5952Smrg
393ffab5952Smrg      case $dstdir in
394ffab5952Smrg	/*) prefix='/';;
39543c16309Smrg	[-=\(\)!]*) prefix='./';;
396ffab5952Smrg	*)  prefix='';;
397ffab5952Smrg      esac
398ffab5952Smrg
399ffab5952Smrg      eval "$initialize_posix_glob"
400ffab5952Smrg
401ffab5952Smrg      oIFS=$IFS
402ffab5952Smrg      IFS=/
403ffab5952Smrg      $posix_glob set -f
404ffab5952Smrg      set fnord $dstdir
405ffab5952Smrg      shift
406ffab5952Smrg      $posix_glob set +f
407ffab5952Smrg      IFS=$oIFS
408ffab5952Smrg
409ffab5952Smrg      prefixes=
410ffab5952Smrg
411ffab5952Smrg      for d
412ffab5952Smrg      do
41343c16309Smrg	test X"$d" = X && continue
414ffab5952Smrg
415ffab5952Smrg	prefix=$prefix$d
416ffab5952Smrg	if test -d "$prefix"; then
417ffab5952Smrg	  prefixes=
418ffab5952Smrg	else
419ffab5952Smrg	  if $posix_mkdir; then
420ffab5952Smrg	    (umask=$mkdir_umask &&
421ffab5952Smrg	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
422ffab5952Smrg	    # Don't fail if two instances are running concurrently.
423ffab5952Smrg	    test -d "$prefix" || exit 1
424ffab5952Smrg	  else
425ffab5952Smrg	    case $prefix in
426ffab5952Smrg	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
427ffab5952Smrg	      *) qprefix=$prefix;;
428ffab5952Smrg	    esac
429ffab5952Smrg	    prefixes="$prefixes '$qprefix'"
430ffab5952Smrg	  fi
431ffab5952Smrg	fi
432ffab5952Smrg	prefix=$prefix/
433ffab5952Smrg      done
434ffab5952Smrg
435ffab5952Smrg      if test -n "$prefixes"; then
436ffab5952Smrg	# Don't fail if two instances are running concurrently.
437ffab5952Smrg	(umask $mkdir_umask &&
438ffab5952Smrg	 eval "\$doit_exec \$mkdirprog $prefixes") ||
439ffab5952Smrg	  test -d "$dstdir" || exit 1
440ffab5952Smrg	obsolete_mkdir_used=true
441ffab5952Smrg      fi
442ffab5952Smrg    fi
443ffab5952Smrg  fi
444ffab5952Smrg
445ffab5952Smrg  if test -n "$dir_arg"; then
446ffab5952Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
447ffab5952Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
448ffab5952Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
449ffab5952Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
450ffab5952Smrg  else
451ffab5952Smrg
452ffab5952Smrg    # Make a couple of temp file names in the proper directory.
453ffab5952Smrg    dsttmp=$dstdir/_inst.$$_
454ffab5952Smrg    rmtmp=$dstdir/_rm.$$_
455ffab5952Smrg
456ffab5952Smrg    # Trap to clean up those temp files at exit.
457ffab5952Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
458ffab5952Smrg
459ffab5952Smrg    # Copy the file name to the temp name.
460ffab5952Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
461ffab5952Smrg
462ffab5952Smrg    # and set any options; do chmod last to preserve setuid bits.
463ffab5952Smrg    #
464ffab5952Smrg    # If any of these fail, we abort the whole thing.  If we want to
465ffab5952Smrg    # ignore errors from any of these, just make sure not to ignore
466ffab5952Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
467ffab5952Smrg    #
468ffab5952Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
469ffab5952Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
470ffab5952Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
471ffab5952Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
472ffab5952Smrg
473ffab5952Smrg    # If -C, don't bother to copy if it wouldn't change the file.
474ffab5952Smrg    if $copy_on_change &&
475ffab5952Smrg       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
476ffab5952Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
477ffab5952Smrg
478ffab5952Smrg       eval "$initialize_posix_glob" &&
479ffab5952Smrg       $posix_glob set -f &&
480ffab5952Smrg       set X $old && old=:$2:$4:$5:$6 &&
481ffab5952Smrg       set X $new && new=:$2:$4:$5:$6 &&
482ffab5952Smrg       $posix_glob set +f &&
483ffab5952Smrg
484ffab5952Smrg       test "$old" = "$new" &&
485ffab5952Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
486ffab5952Smrg    then
487ffab5952Smrg      rm -f "$dsttmp"
488ffab5952Smrg    else
489ffab5952Smrg      # Rename the file to the real destination.
490ffab5952Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
491ffab5952Smrg
492ffab5952Smrg      # The rename failed, perhaps because mv can't rename something else
493ffab5952Smrg      # to itself, or perhaps because mv is so ancient that it does not
494ffab5952Smrg      # support -f.
495ffab5952Smrg      {
496ffab5952Smrg	# Now remove or move aside any old file at destination location.
497ffab5952Smrg	# We try this two ways since rm can't unlink itself on some
498ffab5952Smrg	# systems and the destination file might be busy for other
499ffab5952Smrg	# reasons.  In this case, the final cleanup might fail but the new
500ffab5952Smrg	# file should still install successfully.
501ffab5952Smrg	{
502ffab5952Smrg	  test ! -f "$dst" ||
503ffab5952Smrg	  $doit $rmcmd -f "$dst" 2>/dev/null ||
504ffab5952Smrg	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
505ffab5952Smrg	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
506ffab5952Smrg	  } ||
507ffab5952Smrg	  { echo "$0: cannot unlink or rename $dst" >&2
508ffab5952Smrg	    (exit 1); exit 1
509ffab5952Smrg	  }
510ffab5952Smrg	} &&
511ffab5952Smrg
512ffab5952Smrg	# Now rename the file to the real destination.
513ffab5952Smrg	$doit $mvcmd "$dsttmp" "$dst"
514ffab5952Smrg      }
515ffab5952Smrg    fi || exit 1
516ffab5952Smrg
517ffab5952Smrg    trap '' 0
518ffab5952Smrg  fi
519ffab5952Smrgdone
520ffab5952Smrg
521ffab5952Smrg# Local variables:
522ffab5952Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
523ffab5952Smrg# time-stamp-start: "scriptversion="
524ffab5952Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
525ffab5952Smrg# time-stamp-time-zone: "UTC"
526ffab5952Smrg# time-stamp-end: "; # UTC"
527ffab5952Smrg# End:
528