install-sh revision 289166
1251188Smarcel#!/bin/sh
229088Smarkm# install - install a program, script, or datafile
329088Smarkm
429088Smarkmscriptversion=2011-01-19.21; # UTC
529088Smarkm
629088Smarkm# This originates from X11R5 (mit/util/scripts/install.sh), which was
729088Smarkm# later released in X11R6 (xc/config/util/install.sh) with the
829088Smarkm# following copyright and license.
929088Smarkm#
1029088Smarkm# Copyright (C) 1994 X Consortium
1129088Smarkm#
1229088Smarkm# Permission is hereby granted, free of charge, to any person obtaining a copy
1329088Smarkm# of this software and associated documentation files (the "Software"), to
1429088Smarkm# deal in the Software without restriction, including without limitation the
1529088Smarkm# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1629088Smarkm# sell copies of the Software, and to permit persons to whom the Software is
1729088Smarkm# furnished to do so, subject to the following conditions:
1829088Smarkm#
1929088Smarkm# The above copyright notice and this permission notice shall be included in
2029088Smarkm# all copies or substantial portions of the Software.
2129088Smarkm#
2229088Smarkm# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2329088Smarkm# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2429088Smarkm# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2529088Smarkm# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2629088Smarkm# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2729088Smarkm# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2829088Smarkm#
2929088Smarkm# Except as contained in this notice, the name of the X Consortium shall not
3029088Smarkm# be used in advertising or otherwise to promote the sale, use or other deal-
3129088Smarkm# ings in this Software without prior written authorization from the X Consor-
3229088Smarkm# tium.
3329088Smarkm#
34114630Sobrien#
3529088Smarkm# FSF changes to this file are in the public domain.
3629181Smarkm#
3731622Scharnier# Calling this script install-sh is preferred over install.sh, to prevent
38114630Sobrien# `make' implicit rules from creating a file called install from it
39114630Sobrien# when there is no Makefile.
40114630Sobrien#
4129088Smarkm# This script is compatible with the BSD install script, but was written
4287139Smarkm# from scratch.
4387139Smarkm
4487139Smarkmnl='
4587139Smarkm'
4687139SmarkmIFS=" ""	$nl"
4729088Smarkm
4829088Smarkm# set DOITPROG to echo to test this script
49275508Sngie
50275508Sngie# Don't use :- since 4.3BSD and earlier shells don't like it.
5129088Smarkmdoit=${DOITPROG-}
5287139Smarkmif test -z "$doit"; then
5329088Smarkm  doit_exec=exec
5429088Smarkmelse
5529088Smarkm  doit_exec=$doit
5687139Smarkmfi
5729181Smarkm
5829181Smarkm# Put in absolute file names if you don't have them in your path;
5987139Smarkm# or use environment vars.
6087139Smarkm
6129181Smarkmchgrpprog=${CHGRPPROG-chgrp}
6229088Smarkmchmodprog=${CHMODPROG-chmod}
6329088Smarkmchownprog=${CHOWNPROG-chown}
6429088Smarkmcmpprog=${CMPPROG-cmp}
6529088Smarkmcpprog=${CPPROG-cp}
6629088Smarkmmkdirprog=${MKDIRPROG-mkdir}
6729088Smarkmmvprog=${MVPROG-mv}
6829088Smarkmrmprog=${RMPROG-rm}
6929088Smarkmstripprog=${STRIPPROG-strip}
7029088Smarkm
7129088Smarkmposix_glob='?'
7229088Smarkminitialize_posix_glob='
7329088Smarkm  test "$posix_glob" != "?" || {
7429088Smarkm    if (set -f) 2>/dev/null; then
7529088Smarkm      posix_glob=
7629088Smarkm    else
7729088Smarkm      posix_glob=:
7829088Smarkm    fi
7929088Smarkm  }
8029088Smarkm'
8129088Smarkm
8229088Smarkmposix_mkdir=
8329088Smarkm
8429088Smarkm# Desired mode of installed file.
8529088Smarkmmode=0755
8629088Smarkm
8729088Smarkmchgrpcmd=
8829088Smarkmchmodcmd=$chmodprog
8929088Smarkmchowncmd=
9029088Smarkmmvcmd=$mvprog
9129088Smarkmrmcmd="$rmprog -f"
9229088Smarkmstripcmd=
9329088Smarkm
9429088Smarkmsrc=
9529088Smarkmdst=
9629088Smarkmdir_arg=
9729088Smarkmdst_arg=
9829088Smarkm
9929088Smarkmcopy_on_change=false
10029088Smarkmno_target_directory=
10129088Smarkm
10229088Smarkmusage="\
10329088SmarkmUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
10429088Smarkm   or: $0 [OPTION]... SRCFILES... DIRECTORY
10529088Smarkm   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
10629088Smarkm   or: $0 [OPTION]... -d DIRECTORIES...
10729088Smarkm
10829088SmarkmIn the 1st form, copy SRCFILE to DSTFILE.
10929088SmarkmIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
11029088SmarkmIn the 4th, create DIRECTORIES.
11129088Smarkm
11229088SmarkmOptions:
11329088Smarkm     --help     display this help and exit.
11429088Smarkm     --version  display version info and exit.
11529088Smarkm
11629088Smarkm  -c            (ignored)
11729088Smarkm  -C            install only if different (preserve the last data modification time)
11829088Smarkm  -d            create directories instead of installing files.
11929088Smarkm  -g GROUP      $chgrpprog installed files to GROUP.
12029088Smarkm  -m MODE       $chmodprog installed files to MODE.
12129088Smarkm  -o USER       $chownprog installed files to USER.
12229088Smarkm  -s            $stripprog installed files.
12329088Smarkm  -t DIRECTORY  install into DIRECTORY.
12429088Smarkm  -T            report an error if DSTFILE is a directory.
12529088Smarkm
12629088SmarkmEnvironment variables override the default commands:
12729088Smarkm  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
12831622Scharnier  RMPROG STRIPPROG
12931622Scharnier"
13031622Scharnier
13187155Smarkmwhile test $# -ne 0; do
13287155Smarkm  case $1 in
13387155Smarkm    -c) ;;
13431622Scharnier
13529088Smarkm    -C) copy_on_change=true;;
13629088Smarkm
13729088Smarkm    -d) dir_arg=true;;
13829088Smarkm
13929088Smarkm    -g) chgrpcmd="$chgrpprog $2"
14029088Smarkm	shift;;
14129088Smarkm
14229088Smarkm    --help) echo "$usage"; exit $?;;
14329088Smarkm
14429088Smarkm    -m) mode=$2
14529088Smarkm	case $mode in
14687139Smarkm	  *' '* | *'	'* | *'
14787139Smarkm'*	  | *'*'* | *'?'* | *'['*)
14829088Smarkm	    echo "$0: invalid mode: $mode" >&2
14929088Smarkm	    exit 1;;
15029088Smarkm	esac
15129088Smarkm	shift;;
15229088Smarkm
15329088Smarkm    -o) chowncmd="$chownprog $2"
15429088Smarkm	shift;;
15529088Smarkm
15629088Smarkm    -s) stripcmd=$stripprog;;
15729088Smarkm
15829088Smarkm    -t) dst_arg=$2
15929088Smarkm	# Protect names problematic for `test' and other utilities.
16029088Smarkm	case $dst_arg in
16129088Smarkm	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
16229088Smarkm	esac
16387139Smarkm	shift;;
16487139Smarkm
16529088Smarkm    -T) no_target_directory=true;;
16629088Smarkm
16729088Smarkm    --version) echo "$0 $scriptversion"; exit $?;;
16829088Smarkm
16929088Smarkm    --)	shift
17029088Smarkm	break;;
17129088Smarkm
17229088Smarkm    -*)	echo "$0: invalid option: $1" >&2
17387139Smarkm	exit 1;;
17487139Smarkm
17529088Smarkm    *)  break;;
17629088Smarkm  esac
17729088Smarkm  shift
17829088Smarkmdone
17929088Smarkm
18029088Smarkmif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
18129088Smarkm  # When -d is used, all remaining arguments are directories to create.
18229088Smarkm  # When -t is used, the destination is already specified.
18329088Smarkm  # Otherwise, the last argument is the destination.  Remove it from $@.
18429088Smarkm  for arg
18529088Smarkm  do
18629088Smarkm    if test -n "$dst_arg"; then
18729088Smarkm      # $@ is not empty: it contains at least $arg.
18829088Smarkm      set fnord "$@" "$dst_arg"
18929088Smarkm      shift # fnord
19029088Smarkm    fi
19129088Smarkm    shift # arg
19229088Smarkm    dst_arg=$arg
19329088Smarkm    # Protect names problematic for `test' and other utilities.
19429088Smarkm    case $dst_arg in
19529088Smarkm      -* | [=\(\)!]) dst_arg=./$dst_arg;;
19629088Smarkm    esac
19729088Smarkm  done
19829088Smarkmfi
19929088Smarkm
20029088Smarkmif test $# -eq 0; then
20129088Smarkm  if test -z "$dir_arg"; then
20229088Smarkm    echo "$0: no input file specified." >&2
20329088Smarkm    exit 1
20429088Smarkm  fi
20529088Smarkm  # It's OK to call `install-sh -d' without argument.
20629088Smarkm  # This can happen when creating conditional directories.
20729088Smarkm  exit 0
20829088Smarkmfi
20929088Smarkm
21087139Smarkmif test -z "$dir_arg"; then
21187139Smarkm  do_exit='(exit $ret); exit $ret'
21229088Smarkm  trap "ret=129; $do_exit" 1
21329088Smarkm  trap "ret=130; $do_exit" 2
21429088Smarkm  trap "ret=141; $do_exit" 13
21529088Smarkm  trap "ret=143; $do_exit" 15
21629088Smarkm
21729088Smarkm  # Set umask so as not to create temps with too-generous modes.
21829088Smarkm  # However, 'strip' requires both read and write access to temps.
21929088Smarkm  case $mode in
22029088Smarkm    # Optimize common cases.
22129088Smarkm    *644) cp_umask=133;;
22229088Smarkm    *755) cp_umask=22;;
22329088Smarkm
22429088Smarkm    *[0-7])
22529088Smarkm      if test -z "$stripcmd"; then
22629088Smarkm	u_plus_rw=
22729088Smarkm      else
22829088Smarkm	u_plus_rw='% 200'
22929088Smarkm      fi
23029088Smarkm      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
23129088Smarkm    *)
23229088Smarkm      if test -z "$stripcmd"; then
23329088Smarkm	u_plus_rw=
23429088Smarkm      else
23529088Smarkm	u_plus_rw=,u+rw
23629088Smarkm      fi
23729088Smarkm      cp_umask=$mode$u_plus_rw;;
23829088Smarkm  esac
23929088Smarkmfi
24029088Smarkm
24129088Smarkmfor src
24229088Smarkmdo
24329088Smarkm  # Protect names problematic for `test' and other utilities.
24429088Smarkm  case $src in
24529088Smarkm    -* | [=\(\)!]) src=./$src;;
24629088Smarkm  esac
24729088Smarkm
24829088Smarkm  if test -n "$dir_arg"; then
24929088Smarkm    dst=$src
25029088Smarkm    dstdir=$dst
25129088Smarkm    test -d "$dstdir"
25229088Smarkm    dstdir_status=$?
25329088Smarkm  else
25429088Smarkm
25529088Smarkm    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
25629088Smarkm    # might cause directories to be created, which would be especially bad
25729088Smarkm    # if $src (and thus $dsttmp) contains '*'.
25829088Smarkm    if test ! -f "$src" && test ! -d "$src"; then
25929088Smarkm      echo "$0: $src does not exist." >&2
26029088Smarkm      exit 1
26129088Smarkm    fi
26229088Smarkm
26329088Smarkm    if test -z "$dst_arg"; then
26429088Smarkm      echo "$0: no destination specified." >&2
26529088Smarkm      exit 1
26629088Smarkm    fi
26729088Smarkm    dst=$dst_arg
26829088Smarkm
26929088Smarkm    # If destination is a directory, append the input filename; won't work
27029088Smarkm    # if double slashes aren't ignored.
27129088Smarkm    if test -d "$dst"; then
27229088Smarkm      if test -n "$no_target_directory"; then
27329088Smarkm	echo "$0: $dst_arg: Is a directory" >&2
27429088Smarkm	exit 1
27529088Smarkm      fi
27629088Smarkm      dstdir=$dst
27729088Smarkm      dst=$dstdir/`basename "$src"`
27829088Smarkm      dstdir_status=0
27929088Smarkm    else
28029088Smarkm      # Prefer dirname, but fall back on a substitute if dirname fails.
28129088Smarkm      dstdir=`
28229088Smarkm	(dirname "$dst") 2>/dev/null ||
28329088Smarkm	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
28429088Smarkm	     X"$dst" : 'X\(//\)[^/]' \| \
28529088Smarkm	     X"$dst" : 'X\(//\)$' \| \
28629088Smarkm	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
28729088Smarkm	echo X"$dst" |
28887139Smarkm	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
28987139Smarkm		   s//\1/
29087139Smarkm		   q
29129088Smarkm		 }
29229088Smarkm		 /^X\(\/\/\)[^/].*/{
29329088Smarkm		   s//\1/
29429088Smarkm		   q
29529088Smarkm		 }
29629088Smarkm		 /^X\(\/\/\)$/{
29729088Smarkm		   s//\1/
29829088Smarkm		   q
29929088Smarkm		 }
30029088Smarkm		 /^X\(\/\).*/{
30129088Smarkm		   s//\1/
30229088Smarkm		   q
30329088Smarkm		 }
30429088Smarkm		 s/.*/./; q'
30529088Smarkm      `
30629088Smarkm
30729088Smarkm      test -d "$dstdir"
30829088Smarkm      dstdir_status=$?
30929088Smarkm    fi
31029088Smarkm  fi
31129088Smarkm
31229088Smarkm  obsolete_mkdir_used=false
31329088Smarkm
31429088Smarkm  if test $dstdir_status != 0; then
31529088Smarkm    case $posix_mkdir in
31629088Smarkm      '')
31729088Smarkm	# Create intermediate dirs using mode 755 as modified by the umask.
31829088Smarkm	# This is like FreeBSD 'install' as of 1997-10-28.
31929088Smarkm	umask=`umask`
32029088Smarkm	case $stripcmd.$umask in
32129088Smarkm	  # Optimize common cases.
32229088Smarkm	  *[2367][2367]) mkdir_umask=$umask;;
32329088Smarkm	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
32429088Smarkm
32529088Smarkm	  *[0-7])
32629088Smarkm	    mkdir_umask=`expr $umask + 22 \
32729088Smarkm	      - $umask % 100 % 40 + $umask % 20 \
32829088Smarkm	      - $umask % 10 % 4 + $umask % 2
32929088Smarkm	    `;;
33029088Smarkm	  *) mkdir_umask=$umask,go-w;;
33129088Smarkm	esac
33229088Smarkm
33329088Smarkm	# With -d, create the new directory with the user-specified mode.
33429088Smarkm	# Otherwise, rely on $mkdir_umask.
33529088Smarkm	if test -n "$dir_arg"; then
33629088Smarkm	  mkdir_mode=-m$mode
33729088Smarkm	else
33829088Smarkm	  mkdir_mode=
33929088Smarkm	fi
34029088Smarkm
34129088Smarkm	posix_mkdir=false
34229088Smarkm	case $umask in
34329088Smarkm	  *[123567][0-7][0-7])
34429088Smarkm	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
34529088Smarkm	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
34629088Smarkm	    ;;
34729088Smarkm	  *)
34829088Smarkm	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34929088Smarkm	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
35029088Smarkm
35129088Smarkm	    if (umask $mkdir_umask &&
35229088Smarkm		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
35329088Smarkm	    then
35429088Smarkm	      if test -z "$dir_arg" || {
35529088Smarkm		   # Check for POSIX incompatibilities with -m.
35629088Smarkm		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
35729088Smarkm		   # other-writeable bit of parent directory when it shouldn't.
35829088Smarkm		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
35929088Smarkm		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
36029088Smarkm		   case $ls_ld_tmpdir in
36129088Smarkm		     d????-?r-*) different_mode=700;;
36229088Smarkm		     d????-?--*) different_mode=755;;
36329088Smarkm		     *) false;;
36429088Smarkm		   esac &&
36529088Smarkm		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
36629088Smarkm		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
36729088Smarkm		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
36829088Smarkm		   }
36929088Smarkm		 }
37029088Smarkm	      then posix_mkdir=:
37129088Smarkm	      fi
37229088Smarkm	      rmdir "$tmpdir/d" "$tmpdir"
37329088Smarkm	    else
37429088Smarkm	      # Remove any dirs left behind by ancient mkdir implementations.
37529088Smarkm	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
37629088Smarkm	    fi
37729088Smarkm	    trap '' 0;;
37829088Smarkm	esac;;
37929088Smarkm    esac
38029088Smarkm
38129088Smarkm    if
38229088Smarkm      $posix_mkdir && (
383184935Sed	umask $mkdir_umask &&
38429088Smarkm	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
38587139Smarkm      )
38687139Smarkm    then :
38729088Smarkm    else
38887139Smarkm
389184935Sed      # The umask is ridiculous, or mkdir does not conform to POSIX,
39029088Smarkm      # or it failed possibly due to a race condition.  Create the
391184935Sed      # directory the slow way, step by step, checking for races as we go.
392184935Sed
393184935Sed      case $dstdir in
394184935Sed	/*) prefix='/';;
395184935Sed	[-=\(\)!]*) prefix='./';;
396184935Sed	*)  prefix='';;
39729088Smarkm      esac
398184935Sed
399184935Sed      eval "$initialize_posix_glob"
400184935Sed
401184935Sed      oIFS=$IFS
402184935Sed      IFS=/
403184935Sed      $posix_glob set -f
404184935Sed      set fnord $dstdir
405184938Sed      shift
406184938Sed      $posix_glob set +f
40729088Smarkm      IFS=$oIFS
408184935Sed
40929088Smarkm      prefixes=
41029088Smarkm
41129088Smarkm      for d
41229088Smarkm      do
41329088Smarkm	test X"$d" = X && continue
41429088Smarkm
41529088Smarkm	prefix=$prefix$d
41629088Smarkm	if test -d "$prefix"; then
41729088Smarkm	  prefixes=
41829088Smarkm	else
41929088Smarkm	  if $posix_mkdir; then
42029088Smarkm	    (umask=$mkdir_umask &&
42129088Smarkm	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
42229088Smarkm	    # Don't fail if two instances are running concurrently.
42329088Smarkm	    test -d "$prefix" || exit 1
42429088Smarkm	  else
42529088Smarkm	    case $prefix in
42629088Smarkm	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
42729088Smarkm	      *) qprefix=$prefix;;
42829088Smarkm	    esac
42929088Smarkm	    prefixes="$prefixes '$qprefix'"
43029088Smarkm	  fi
43129088Smarkm	fi
43229088Smarkm	prefix=$prefix/
43329088Smarkm      done
43487139Smarkm
43587139Smarkm      if test -n "$prefixes"; then
43629088Smarkm	# Don't fail if two instances are running concurrently.
43729088Smarkm	(umask $mkdir_umask &&
43829088Smarkm	 eval "\$doit_exec \$mkdirprog $prefixes") ||
43929088Smarkm	  test -d "$dstdir" || exit 1
44029088Smarkm	obsolete_mkdir_used=true
44129088Smarkm      fi
44229088Smarkm    fi
44329088Smarkm  fi
44487139Smarkm
44587139Smarkm  if test -n "$dir_arg"; then
44629088Smarkm    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
44729088Smarkm    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
44829088Smarkm    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
44929088Smarkm      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
45029088Smarkm  else
45129088Smarkm
45229088Smarkm    # Make a couple of temp file names in the proper directory.
45329088Smarkm    dsttmp=$dstdir/_inst.$$_
45429088Smarkm    rmtmp=$dstdir/_rm.$$_
45529088Smarkm
45629088Smarkm    # Trap to clean up those temp files at exit.
45729088Smarkm    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
45829088Smarkm
45929088Smarkm    # Copy the file name to the temp name.
46029088Smarkm    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
46129088Smarkm
46287139Smarkm    # and set any options; do chmod last to preserve setuid bits.
46387139Smarkm    #
46429088Smarkm    # If any of these fail, we abort the whole thing.  If we want to
46529088Smarkm    # ignore errors from any of these, just make sure not to ignore
46629088Smarkm    # errors from the above "$doit $cpprog $src $dsttmp" command.
46729088Smarkm    #
46829088Smarkm    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
46929088Smarkm    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
47029088Smarkm    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
47129088Smarkm    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
47287139Smarkm
47387139Smarkm    # If -C, don't bother to copy if it wouldn't change the file.
47429088Smarkm    if $copy_on_change &&
47529088Smarkm       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
47629088Smarkm       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
47729088Smarkm
47829088Smarkm       eval "$initialize_posix_glob" &&
47929088Smarkm       $posix_glob set -f &&
48029088Smarkm       set X $old && old=:$2:$4:$5:$6 &&
48129088Smarkm       set X $new && new=:$2:$4:$5:$6 &&
48287139Smarkm       $posix_glob set +f &&
48387139Smarkm
48429088Smarkm       test "$old" = "$new" &&
48529088Smarkm       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
48629088Smarkm    then
48729088Smarkm      rm -f "$dsttmp"
48829088Smarkm    else
48929088Smarkm      # Rename the file to the real destination.
49029088Smarkm      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
49129088Smarkm
49229088Smarkm      # The rename failed, perhaps because mv can't rename something else
49329088Smarkm      # to itself, or perhaps because mv is so ancient that it does not
49429088Smarkm      # support -f.
49529088Smarkm      {
49687139Smarkm	# Now remove or move aside any old file at destination location.
49787139Smarkm	# We try this two ways since rm can't unlink itself on some
49829088Smarkm	# systems and the destination file might be busy for other
49929088Smarkm	# reasons.  In this case, the final cleanup might fail but the new
50029088Smarkm	# file should still install successfully.
50129088Smarkm	{
50229088Smarkm	  test ! -f "$dst" ||
50329088Smarkm	  $doit $rmcmd -f "$dst" 2>/dev/null ||
50429088Smarkm	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
50529088Smarkm	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
50629088Smarkm	  } ||
50729088Smarkm	  { echo "$0: cannot unlink or rename $dst" >&2
50829088Smarkm	    (exit 1); exit 1
50929088Smarkm	  }
51029088Smarkm	} &&
51129088Smarkm
51287139Smarkm	# Now rename the file to the real destination.
51387139Smarkm	$doit $mvcmd "$dsttmp" "$dst"
51429088Smarkm      }
51529088Smarkm    fi || exit 1
51629088Smarkm
51729088Smarkm    trap '' 0
51829088Smarkm  fi
51929088Smarkmdone
52029088Smarkm
52129088Smarkm# Local variables:
52287139Smarkm# eval: (add-hook 'write-file-hooks 'time-stamp)
52387139Smarkm# time-stamp-start: "scriptversion="
52487139Smarkm# time-stamp-format: "%:y-%02m-%02d.%02H"
52587139Smarkm# time-stamp-time-zone: "UTC"
52629088Smarkm# time-stamp-end: "; # UTC"
52729088Smarkm# End:
52829088Smarkm