install-sh revision 41fe0c2a
111d341caSmrg#!/bin/sh
211d341caSmrg# install - install a program, script, or datafile
311d341caSmrg
441fe0c2aSmrgscriptversion=2013-12-25.23; # UTC
511d341caSmrg
611d341caSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
711d341caSmrg# later released in X11R6 (xc/config/util/install.sh) with the
811d341caSmrg# following copyright and license.
911d341caSmrg#
1011d341caSmrg# Copyright (C) 1994 X Consortium
1111d341caSmrg#
1211d341caSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1311d341caSmrg# of this software and associated documentation files (the "Software"), to
1411d341caSmrg# deal in the Software without restriction, including without limitation the
1511d341caSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1611d341caSmrg# sell copies of the Software, and to permit persons to whom the Software is
1711d341caSmrg# furnished to do so, subject to the following conditions:
1811d341caSmrg#
1911d341caSmrg# The above copyright notice and this permission notice shall be included in
2011d341caSmrg# all copies or substantial portions of the Software.
2111d341caSmrg#
2211d341caSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2311d341caSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2411d341caSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2511d341caSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2611d341caSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2711d341caSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2811d341caSmrg#
2911d341caSmrg# Except as contained in this notice, the name of the X Consortium shall not
3011d341caSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
3111d341caSmrg# ings in this Software without prior written authorization from the X Consor-
3211d341caSmrg# tium.
3311d341caSmrg#
3411d341caSmrg#
3511d341caSmrg# FSF changes to this file are in the public domain.
3611d341caSmrg#
3711d341caSmrg# Calling this script install-sh is preferred over install.sh, to prevent
381c80d5b0Smrg# 'make' implicit rules from creating a file called install from it
3911d341caSmrg# when there is no Makefile.
4011d341caSmrg#
4111d341caSmrg# This script is compatible with the BSD install script, but was written
424c61c93dSmrg# from scratch.
434c61c93dSmrg
4441fe0c2aSmrgtab='	'
454c61c93dSmrgnl='
464c61c93dSmrg'
4741fe0c2aSmrgIFS=" $tab$nl"
4811d341caSmrg
4941fe0c2aSmrg# Set DOITPROG to "echo" to test this script.
5011d341caSmrg
514c61c93dSmrgdoit=${DOITPROG-}
5241fe0c2aSmrgdoit_exec=${doit:-exec}
5311d341caSmrg
544c61c93dSmrg# Put in absolute file names if you don't have them in your path;
554c61c93dSmrg# or use environment vars.
564c61c93dSmrg
574c61c93dSmrgchgrpprog=${CHGRPPROG-chgrp}
584c61c93dSmrgchmodprog=${CHMODPROG-chmod}
594c61c93dSmrgchownprog=${CHOWNPROG-chown}
604c61c93dSmrgcmpprog=${CMPPROG-cmp}
614c61c93dSmrgcpprog=${CPPROG-cp}
624c61c93dSmrgmkdirprog=${MKDIRPROG-mkdir}
634c61c93dSmrgmvprog=${MVPROG-mv}
644c61c93dSmrgrmprog=${RMPROG-rm}
654c61c93dSmrgstripprog=${STRIPPROG-strip}
664c61c93dSmrg
674c61c93dSmrgposix_mkdir=
684c61c93dSmrg
694c61c93dSmrg# Desired mode of installed file.
704c61c93dSmrgmode=0755
7111d341caSmrg
7211d341caSmrgchgrpcmd=
734c61c93dSmrgchmodcmd=$chmodprog
744c61c93dSmrgchowncmd=
754c61c93dSmrgmvcmd=$mvprog
7611d341caSmrgrmcmd="$rmprog -f"
774c61c93dSmrgstripcmd=
784c61c93dSmrg
7911d341caSmrgsrc=
8011d341caSmrgdst=
8111d341caSmrgdir_arg=
824c61c93dSmrgdst_arg=
834c61c93dSmrg
844c61c93dSmrgcopy_on_change=false
8541fe0c2aSmrgis_target_a_directory=possibly
8611d341caSmrg
874c61c93dSmrgusage="\
884c61c93dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
8911d341caSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9011d341caSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9111d341caSmrg   or: $0 [OPTION]... -d DIRECTORIES...
9211d341caSmrg
9311d341caSmrgIn the 1st form, copy SRCFILE to DSTFILE.
9411d341caSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
9511d341caSmrgIn the 4th, create DIRECTORIES.
9611d341caSmrg
9711d341caSmrgOptions:
984c61c93dSmrg     --help     display this help and exit.
994c61c93dSmrg     --version  display version info and exit.
1004c61c93dSmrg
1014c61c93dSmrg  -c            (ignored)
1024c61c93dSmrg  -C            install only if different (preserve the last data modification time)
1034c61c93dSmrg  -d            create directories instead of installing files.
1044c61c93dSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1054c61c93dSmrg  -m MODE       $chmodprog installed files to MODE.
1064c61c93dSmrg  -o USER       $chownprog installed files to USER.
1074c61c93dSmrg  -s            $stripprog installed files.
1084c61c93dSmrg  -t DIRECTORY  install into DIRECTORY.
1094c61c93dSmrg  -T            report an error if DSTFILE is a directory.
11011d341caSmrg
11111d341caSmrgEnvironment variables override the default commands:
1124c61c93dSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1134c61c93dSmrg  RMPROG STRIPPROG
11411d341caSmrg"
11511d341caSmrg
1164c61c93dSmrgwhile test $# -ne 0; do
11711d341caSmrg  case $1 in
1184c61c93dSmrg    -c) ;;
1194c61c93dSmrg
1204c61c93dSmrg    -C) copy_on_change=true;;
12111d341caSmrg
1224c61c93dSmrg    -d) dir_arg=true;;
12311d341caSmrg
12411d341caSmrg    -g) chgrpcmd="$chgrpprog $2"
12541fe0c2aSmrg        shift;;
12611d341caSmrg
12711d341caSmrg    --help) echo "$usage"; exit $?;;
12811d341caSmrg
1294c61c93dSmrg    -m) mode=$2
13041fe0c2aSmrg        case $mode in
13141fe0c2aSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
13241fe0c2aSmrg            echo "$0: invalid mode: $mode" >&2
13341fe0c2aSmrg            exit 1;;
13441fe0c2aSmrg        esac
13541fe0c2aSmrg        shift;;
13611d341caSmrg
13711d341caSmrg    -o) chowncmd="$chownprog $2"
13841fe0c2aSmrg        shift;;
13911d341caSmrg
1404c61c93dSmrg    -s) stripcmd=$stripprog;;
14111d341caSmrg
14241fe0c2aSmrg    -t)
14341fe0c2aSmrg        is_target_a_directory=always
14441fe0c2aSmrg        dst_arg=$2
14541fe0c2aSmrg        # Protect names problematic for 'test' and other utilities.
14641fe0c2aSmrg        case $dst_arg in
14741fe0c2aSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
14841fe0c2aSmrg        esac
14941fe0c2aSmrg        shift;;
15011d341caSmrg
15141fe0c2aSmrg    -T) is_target_a_directory=never;;
15211d341caSmrg
15311d341caSmrg    --version) echo "$0 $scriptversion"; exit $?;;
15411d341caSmrg
15541fe0c2aSmrg    --) shift
15641fe0c2aSmrg        break;;
1574c61c93dSmrg
15841fe0c2aSmrg    -*) echo "$0: invalid option: $1" >&2
15941fe0c2aSmrg        exit 1;;
1604c61c93dSmrg
1614c61c93dSmrg    *)  break;;
16211d341caSmrg  esac
1634c61c93dSmrg  shift
16411d341caSmrgdone
16511d341caSmrg
16641fe0c2aSmrg# We allow the use of options -d and -T together, by making -d
16741fe0c2aSmrg# take the precedence; this is for compatibility with GNU install.
16841fe0c2aSmrg
16941fe0c2aSmrgif test -n "$dir_arg"; then
17041fe0c2aSmrg  if test -n "$dst_arg"; then
17141fe0c2aSmrg    echo "$0: target directory not allowed when installing a directory." >&2
17241fe0c2aSmrg    exit 1
17341fe0c2aSmrg  fi
17441fe0c2aSmrgfi
17541fe0c2aSmrg
1764c61c93dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1774c61c93dSmrg  # When -d is used, all remaining arguments are directories to create.
1784c61c93dSmrg  # When -t is used, the destination is already specified.
1794c61c93dSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1804c61c93dSmrg  for arg
1814c61c93dSmrg  do
1824c61c93dSmrg    if test -n "$dst_arg"; then
1834c61c93dSmrg      # $@ is not empty: it contains at least $arg.
1844c61c93dSmrg      set fnord "$@" "$dst_arg"
1854c61c93dSmrg      shift # fnord
1864c61c93dSmrg    fi
1874c61c93dSmrg    shift # arg
1884c61c93dSmrg    dst_arg=$arg
1891c80d5b0Smrg    # Protect names problematic for 'test' and other utilities.
1901c80d5b0Smrg    case $dst_arg in
1911c80d5b0Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1921c80d5b0Smrg    esac
1934c61c93dSmrg  done
1944c61c93dSmrgfi
1954c61c93dSmrg
1964c61c93dSmrgif test $# -eq 0; then
19711d341caSmrg  if test -z "$dir_arg"; then
19811d341caSmrg    echo "$0: no input file specified." >&2
19911d341caSmrg    exit 1
20011d341caSmrg  fi
2011c80d5b0Smrg  # It's OK to call 'install-sh -d' without argument.
20211d341caSmrg  # This can happen when creating conditional directories.
20311d341caSmrg  exit 0
20411d341caSmrgfi
20511d341caSmrg
20641fe0c2aSmrgif test -z "$dir_arg"; then
20741fe0c2aSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
20841fe0c2aSmrg    if test ! -d "$dst_arg"; then
20941fe0c2aSmrg      echo "$0: $dst_arg: Is not a directory." >&2
21041fe0c2aSmrg      exit 1
21141fe0c2aSmrg    fi
21241fe0c2aSmrg  fi
21341fe0c2aSmrgfi
21441fe0c2aSmrg
2154c61c93dSmrgif test -z "$dir_arg"; then
2161c80d5b0Smrg  do_exit='(exit $ret); exit $ret'
2171c80d5b0Smrg  trap "ret=129; $do_exit" 1
2181c80d5b0Smrg  trap "ret=130; $do_exit" 2
2191c80d5b0Smrg  trap "ret=141; $do_exit" 13
2201c80d5b0Smrg  trap "ret=143; $do_exit" 15
2214c61c93dSmrg
2224c61c93dSmrg  # Set umask so as not to create temps with too-generous modes.
2234c61c93dSmrg  # However, 'strip' requires both read and write access to temps.
2244c61c93dSmrg  case $mode in
2254c61c93dSmrg    # Optimize common cases.
2264c61c93dSmrg    *644) cp_umask=133;;
2274c61c93dSmrg    *755) cp_umask=22;;
2284c61c93dSmrg
2294c61c93dSmrg    *[0-7])
2304c61c93dSmrg      if test -z "$stripcmd"; then
23141fe0c2aSmrg        u_plus_rw=
2324c61c93dSmrg      else
23341fe0c2aSmrg        u_plus_rw='% 200'
2344c61c93dSmrg      fi
2354c61c93dSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2364c61c93dSmrg    *)
2374c61c93dSmrg      if test -z "$stripcmd"; then
23841fe0c2aSmrg        u_plus_rw=
2394c61c93dSmrg      else
24041fe0c2aSmrg        u_plus_rw=,u+rw
2414c61c93dSmrg      fi
2424c61c93dSmrg      cp_umask=$mode$u_plus_rw;;
2434c61c93dSmrg  esac
2444c61c93dSmrgfi
2454c61c93dSmrg
24611d341caSmrgfor src
24711d341caSmrgdo
2481c80d5b0Smrg  # Protect names problematic for 'test' and other utilities.
24911d341caSmrg  case $src in
2501c80d5b0Smrg    -* | [=\(\)!]) src=./$src;;
25111d341caSmrg  esac
25211d341caSmrg
25311d341caSmrg  if test -n "$dir_arg"; then
25411d341caSmrg    dst=$src
2554c61c93dSmrg    dstdir=$dst
2564c61c93dSmrg    test -d "$dstdir"
2574c61c93dSmrg    dstdir_status=$?
25811d341caSmrg  else
2594c61c93dSmrg
26011d341caSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
26111d341caSmrg    # might cause directories to be created, which would be especially bad
26211d341caSmrg    # if $src (and thus $dsttmp) contains '*'.
26311d341caSmrg    if test ! -f "$src" && test ! -d "$src"; then
26411d341caSmrg      echo "$0: $src does not exist." >&2
26511d341caSmrg      exit 1
26611d341caSmrg    fi
26711d341caSmrg
2684c61c93dSmrg    if test -z "$dst_arg"; then
26911d341caSmrg      echo "$0: no destination specified." >&2
27011d341caSmrg      exit 1
27111d341caSmrg    fi
2724c61c93dSmrg    dst=$dst_arg
27311d341caSmrg
27411d341caSmrg    # If destination is a directory, append the input filename; won't work
27511d341caSmrg    # if double slashes aren't ignored.
27611d341caSmrg    if test -d "$dst"; then
27741fe0c2aSmrg      if test "$is_target_a_directory" = never; then
27841fe0c2aSmrg        echo "$0: $dst_arg: Is a directory" >&2
27941fe0c2aSmrg        exit 1
28011d341caSmrg      fi
2814c61c93dSmrg      dstdir=$dst
2824c61c93dSmrg      dst=$dstdir/`basename "$src"`
2834c61c93dSmrg      dstdir_status=0
2844c61c93dSmrg    else
28541fe0c2aSmrg      dstdir=`dirname "$dst"`
2864c61c93dSmrg      test -d "$dstdir"
2874c61c93dSmrg      dstdir_status=$?
28811d341caSmrg    fi
28911d341caSmrg  fi
29011d341caSmrg
2914c61c93dSmrg  obsolete_mkdir_used=false
2924c61c93dSmrg
2934c61c93dSmrg  if test $dstdir_status != 0; then
2944c61c93dSmrg    case $posix_mkdir in
2954c61c93dSmrg      '')
29641fe0c2aSmrg        # Create intermediate dirs using mode 755 as modified by the umask.
29741fe0c2aSmrg        # This is like FreeBSD 'install' as of 1997-10-28.
29841fe0c2aSmrg        umask=`umask`
29941fe0c2aSmrg        case $stripcmd.$umask in
30041fe0c2aSmrg          # Optimize common cases.
30141fe0c2aSmrg          *[2367][2367]) mkdir_umask=$umask;;
30241fe0c2aSmrg          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
30341fe0c2aSmrg
30441fe0c2aSmrg          *[0-7])
30541fe0c2aSmrg            mkdir_umask=`expr $umask + 22 \
30641fe0c2aSmrg              - $umask % 100 % 40 + $umask % 20 \
30741fe0c2aSmrg              - $umask % 10 % 4 + $umask % 2
30841fe0c2aSmrg            `;;
30941fe0c2aSmrg          *) mkdir_umask=$umask,go-w;;
31041fe0c2aSmrg        esac
31141fe0c2aSmrg
31241fe0c2aSmrg        # With -d, create the new directory with the user-specified mode.
31341fe0c2aSmrg        # Otherwise, rely on $mkdir_umask.
31441fe0c2aSmrg        if test -n "$dir_arg"; then
31541fe0c2aSmrg          mkdir_mode=-m$mode
31641fe0c2aSmrg        else
31741fe0c2aSmrg          mkdir_mode=
31841fe0c2aSmrg        fi
31941fe0c2aSmrg
32041fe0c2aSmrg        posix_mkdir=false
32141fe0c2aSmrg        case $umask in
32241fe0c2aSmrg          *[123567][0-7][0-7])
32341fe0c2aSmrg            # POSIX mkdir -p sets u+wx bits regardless of umask, which
32441fe0c2aSmrg            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
32541fe0c2aSmrg            ;;
32641fe0c2aSmrg          *)
32741fe0c2aSmrg            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
32841fe0c2aSmrg            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
32941fe0c2aSmrg
33041fe0c2aSmrg            if (umask $mkdir_umask &&
33141fe0c2aSmrg                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
33241fe0c2aSmrg            then
33341fe0c2aSmrg              if test -z "$dir_arg" || {
33441fe0c2aSmrg                   # Check for POSIX incompatibilities with -m.
33541fe0c2aSmrg                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
33641fe0c2aSmrg                   # other-writable bit of parent directory when it shouldn't.
33741fe0c2aSmrg                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
33841fe0c2aSmrg                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
33941fe0c2aSmrg                   case $ls_ld_tmpdir in
34041fe0c2aSmrg                     d????-?r-*) different_mode=700;;
34141fe0c2aSmrg                     d????-?--*) different_mode=755;;
34241fe0c2aSmrg                     *) false;;
34341fe0c2aSmrg                   esac &&
34441fe0c2aSmrg                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
34541fe0c2aSmrg                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
34641fe0c2aSmrg                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
34741fe0c2aSmrg                   }
34841fe0c2aSmrg                 }
34941fe0c2aSmrg              then posix_mkdir=:
35041fe0c2aSmrg              fi
35141fe0c2aSmrg              rmdir "$tmpdir/d" "$tmpdir"
35241fe0c2aSmrg            else
35341fe0c2aSmrg              # Remove any dirs left behind by ancient mkdir implementations.
35441fe0c2aSmrg              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
35541fe0c2aSmrg            fi
35641fe0c2aSmrg            trap '' 0;;
35741fe0c2aSmrg        esac;;
3584c61c93dSmrg    esac
35911d341caSmrg
3604c61c93dSmrg    if
3614c61c93dSmrg      $posix_mkdir && (
36241fe0c2aSmrg        umask $mkdir_umask &&
36341fe0c2aSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3644c61c93dSmrg      )
3654c61c93dSmrg    then :
3664c61c93dSmrg    else
36711d341caSmrg
3684c61c93dSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3694c61c93dSmrg      # or it failed possibly due to a race condition.  Create the
3704c61c93dSmrg      # directory the slow way, step by step, checking for races as we go.
37111d341caSmrg
3724c61c93dSmrg      case $dstdir in
37341fe0c2aSmrg        /*) prefix='/';;
37441fe0c2aSmrg        [-=\(\)!]*) prefix='./';;
37541fe0c2aSmrg        *)  prefix='';;
3764c61c93dSmrg      esac
37711d341caSmrg
3784c61c93dSmrg      oIFS=$IFS
3794c61c93dSmrg      IFS=/
38041fe0c2aSmrg      set -f
3814c61c93dSmrg      set fnord $dstdir
38211d341caSmrg      shift
38341fe0c2aSmrg      set +f
3844c61c93dSmrg      IFS=$oIFS
3854c61c93dSmrg
3864c61c93dSmrg      prefixes=
3874c61c93dSmrg
3884c61c93dSmrg      for d
3894c61c93dSmrg      do
39041fe0c2aSmrg        test X"$d" = X && continue
39141fe0c2aSmrg
39241fe0c2aSmrg        prefix=$prefix$d
39341fe0c2aSmrg        if test -d "$prefix"; then
39441fe0c2aSmrg          prefixes=
39541fe0c2aSmrg        else
39641fe0c2aSmrg          if $posix_mkdir; then
39741fe0c2aSmrg            (umask=$mkdir_umask &&
39841fe0c2aSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
39941fe0c2aSmrg            # Don't fail if two instances are running concurrently.
40041fe0c2aSmrg            test -d "$prefix" || exit 1
40141fe0c2aSmrg          else
40241fe0c2aSmrg            case $prefix in
40341fe0c2aSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
40441fe0c2aSmrg              *) qprefix=$prefix;;
40541fe0c2aSmrg            esac
40641fe0c2aSmrg            prefixes="$prefixes '$qprefix'"
40741fe0c2aSmrg          fi
40841fe0c2aSmrg        fi
40941fe0c2aSmrg        prefix=$prefix/
4104c61c93dSmrg      done
4114c61c93dSmrg
4124c61c93dSmrg      if test -n "$prefixes"; then
41341fe0c2aSmrg        # Don't fail if two instances are running concurrently.
41441fe0c2aSmrg        (umask $mkdir_umask &&
41541fe0c2aSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
41641fe0c2aSmrg          test -d "$dstdir" || exit 1
41741fe0c2aSmrg        obsolete_mkdir_used=true
41811d341caSmrg      fi
4194c61c93dSmrg    fi
42011d341caSmrg  fi
42111d341caSmrg
42211d341caSmrg  if test -n "$dir_arg"; then
4234c61c93dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4244c61c93dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4254c61c93dSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4264c61c93dSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
42711d341caSmrg  else
42811d341caSmrg
42911d341caSmrg    # Make a couple of temp file names in the proper directory.
43011d341caSmrg    dsttmp=$dstdir/_inst.$$_
43111d341caSmrg    rmtmp=$dstdir/_rm.$$_
43211d341caSmrg
43311d341caSmrg    # Trap to clean up those temp files at exit.
43411d341caSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
43511d341caSmrg
43611d341caSmrg    # Copy the file name to the temp name.
4374c61c93dSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
43811d341caSmrg
43911d341caSmrg    # and set any options; do chmod last to preserve setuid bits.
44011d341caSmrg    #
44111d341caSmrg    # If any of these fail, we abort the whole thing.  If we want to
44211d341caSmrg    # ignore errors from any of these, just make sure not to ignore
44311d341caSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
44411d341caSmrg    #
4454c61c93dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4464c61c93dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4474c61c93dSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4484c61c93dSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4494c61c93dSmrg
4504c61c93dSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4514c61c93dSmrg    if $copy_on_change &&
45241fe0c2aSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
45341fe0c2aSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
45441fe0c2aSmrg       set -f &&
4554c61c93dSmrg       set X $old && old=:$2:$4:$5:$6 &&
4564c61c93dSmrg       set X $new && new=:$2:$4:$5:$6 &&
45741fe0c2aSmrg       set +f &&
4584c61c93dSmrg       test "$old" = "$new" &&
4594c61c93dSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4604c61c93dSmrg    then
4614c61c93dSmrg      rm -f "$dsttmp"
4624c61c93dSmrg    else
4634c61c93dSmrg      # Rename the file to the real destination.
4644c61c93dSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4654c61c93dSmrg
4664c61c93dSmrg      # The rename failed, perhaps because mv can't rename something else
4674c61c93dSmrg      # to itself, or perhaps because mv is so ancient that it does not
4684c61c93dSmrg      # support -f.
4694c61c93dSmrg      {
47041fe0c2aSmrg        # Now remove or move aside any old file at destination location.
47141fe0c2aSmrg        # We try this two ways since rm can't unlink itself on some
47241fe0c2aSmrg        # systems and the destination file might be busy for other
47341fe0c2aSmrg        # reasons.  In this case, the final cleanup might fail but the new
47441fe0c2aSmrg        # file should still install successfully.
47541fe0c2aSmrg        {
47641fe0c2aSmrg          test ! -f "$dst" ||
47741fe0c2aSmrg          $doit $rmcmd -f "$dst" 2>/dev/null ||
47841fe0c2aSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
47941fe0c2aSmrg            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
48041fe0c2aSmrg          } ||
48141fe0c2aSmrg          { echo "$0: cannot unlink or rename $dst" >&2
48241fe0c2aSmrg            (exit 1); exit 1
48341fe0c2aSmrg          }
48441fe0c2aSmrg        } &&
48541fe0c2aSmrg
48641fe0c2aSmrg        # Now rename the file to the real destination.
48741fe0c2aSmrg        $doit $mvcmd "$dsttmp" "$dst"
4884c61c93dSmrg      }
4894c61c93dSmrg    fi || exit 1
4904c61c93dSmrg
4914c61c93dSmrg    trap '' 0
4924c61c93dSmrg  fi
49311d341caSmrgdone
49411d341caSmrg
49511d341caSmrg# Local variables:
49611d341caSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
49711d341caSmrg# time-stamp-start: "scriptversion="
49811d341caSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
4994c61c93dSmrg# time-stamp-time-zone: "UTC"
5004c61c93dSmrg# time-stamp-end: "; # UTC"
50111d341caSmrg# End:
502