install-sh revision 35c4bbdf
105b261ecSmrg#!/bin/sh
205b261ecSmrg# install - install a program, script, or datafile
305b261ecSmrg
435c4bbdfSmrgscriptversion=2013-12-25.23; # UTC
505b261ecSmrg
605b261ecSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
705b261ecSmrg# later released in X11R6 (xc/config/util/install.sh) with the
805b261ecSmrg# following copyright and license.
905b261ecSmrg#
1005b261ecSmrg# Copyright (C) 1994 X Consortium
1105b261ecSmrg#
1205b261ecSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1305b261ecSmrg# of this software and associated documentation files (the "Software"), to
1405b261ecSmrg# deal in the Software without restriction, including without limitation the
1505b261ecSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1605b261ecSmrg# sell copies of the Software, and to permit persons to whom the Software is
1705b261ecSmrg# furnished to do so, subject to the following conditions:
1805b261ecSmrg#
1905b261ecSmrg# The above copyright notice and this permission notice shall be included in
2005b261ecSmrg# all copies or substantial portions of the Software.
2105b261ecSmrg#
2205b261ecSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2305b261ecSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2405b261ecSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2505b261ecSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2605b261ecSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2705b261ecSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2805b261ecSmrg#
2905b261ecSmrg# Except as contained in this notice, the name of the X Consortium shall not
3005b261ecSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
3105b261ecSmrg# ings in this Software without prior written authorization from the X Consor-
3205b261ecSmrg# tium.
3305b261ecSmrg#
3405b261ecSmrg#
3505b261ecSmrg# FSF changes to this file are in the public domain.
3605b261ecSmrg#
3705b261ecSmrg# Calling this script install-sh is preferred over install.sh, to prevent
3835c4bbdfSmrg# 'make' implicit rules from creating a file called install from it
3905b261ecSmrg# when there is no Makefile.
4005b261ecSmrg#
4105b261ecSmrg# This script is compatible with the BSD install script, but was written
4205b261ecSmrg# from scratch.
4305b261ecSmrg
4435c4bbdfSmrgtab='	'
4505b261ecSmrgnl='
4605b261ecSmrg'
4735c4bbdfSmrgIFS=" $tab$nl"
4805b261ecSmrg
4935c4bbdfSmrg# Set DOITPROG to "echo" to test this script.
5005b261ecSmrg
5135c4bbdfSmrgdoit=${DOITPROG-}
5235c4bbdfSmrgdoit_exec=${doit:-exec}
5305b261ecSmrg
5405b261ecSmrg# Put in absolute file names if you don't have them in your path;
5505b261ecSmrg# or use environment vars.
5605b261ecSmrg
5735c4bbdfSmrgchgrpprog=${CHGRPPROG-chgrp}
5835c4bbdfSmrgchmodprog=${CHMODPROG-chmod}
5935c4bbdfSmrgchownprog=${CHOWNPROG-chown}
6035c4bbdfSmrgcmpprog=${CMPPROG-cmp}
6135c4bbdfSmrgcpprog=${CPPROG-cp}
6235c4bbdfSmrgmkdirprog=${MKDIRPROG-mkdir}
6335c4bbdfSmrgmvprog=${MVPROG-mv}
6435c4bbdfSmrgrmprog=${RMPROG-rm}
6535c4bbdfSmrgstripprog=${STRIPPROG-strip}
6605b261ecSmrg
6705b261ecSmrgposix_mkdir=
6805b261ecSmrg
6905b261ecSmrg# Desired mode of installed file.
7005b261ecSmrgmode=0755
7105b261ecSmrg
7235c4bbdfSmrgchgrpcmd=
7305b261ecSmrgchmodcmd=$chmodprog
7405b261ecSmrgchowncmd=
7535c4bbdfSmrgmvcmd=$mvprog
76475c125cSmrgrmcmd="$rmprog -f"
7735c4bbdfSmrgstripcmd=
7835c4bbdfSmrg
7905b261ecSmrgsrc=
8005b261ecSmrgdst=
8105b261ecSmrgdir_arg=
8235c4bbdfSmrgdst_arg=
8335c4bbdfSmrg
8435c4bbdfSmrgcopy_on_change=false
8535c4bbdfSmrgis_target_a_directory=possibly
8605b261ecSmrg
8735c4bbdfSmrgusage="\
8835c4bbdfSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
8905b261ecSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
9005b261ecSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9105b261ecSmrg   or: $0 [OPTION]... -d DIRECTORIES...
9205b261ecSmrg
9305b261ecSmrgIn the 1st form, copy SRCFILE to DSTFILE.
9405b261ecSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
9505b261ecSmrgIn the 4th, create DIRECTORIES.
9605b261ecSmrg
9705b261ecSmrgOptions:
9835c4bbdfSmrg     --help     display this help and exit.
9935c4bbdfSmrg     --version  display version info and exit.
10035c4bbdfSmrg
10135c4bbdfSmrg  -c            (ignored)
10235c4bbdfSmrg  -C            install only if different (preserve the last data modification time)
10335c4bbdfSmrg  -d            create directories instead of installing files.
10435c4bbdfSmrg  -g GROUP      $chgrpprog installed files to GROUP.
10535c4bbdfSmrg  -m MODE       $chmodprog installed files to MODE.
10635c4bbdfSmrg  -o USER       $chownprog installed files to USER.
10735c4bbdfSmrg  -s            $stripprog installed files.
10835c4bbdfSmrg  -t DIRECTORY  install into DIRECTORY.
10935c4bbdfSmrg  -T            report an error if DSTFILE is a directory.
11005b261ecSmrg
11105b261ecSmrgEnvironment variables override the default commands:
11235c4bbdfSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
11335c4bbdfSmrg  RMPROG STRIPPROG
11405b261ecSmrg"
11505b261ecSmrg
11605b261ecSmrgwhile test $# -ne 0; do
11705b261ecSmrg  case $1 in
11835c4bbdfSmrg    -c) ;;
11905b261ecSmrg
12035c4bbdfSmrg    -C) copy_on_change=true;;
12135c4bbdfSmrg
12235c4bbdfSmrg    -d) dir_arg=true;;
12305b261ecSmrg
12405b261ecSmrg    -g) chgrpcmd="$chgrpprog $2"
12535c4bbdfSmrg        shift;;
12605b261ecSmrg
12705b261ecSmrg    --help) echo "$usage"; exit $?;;
12805b261ecSmrg
12905b261ecSmrg    -m) mode=$2
13035c4bbdfSmrg        case $mode in
13135c4bbdfSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
13235c4bbdfSmrg            echo "$0: invalid mode: $mode" >&2
13335c4bbdfSmrg            exit 1;;
13435c4bbdfSmrg        esac
13535c4bbdfSmrg        shift;;
13605b261ecSmrg
13705b261ecSmrg    -o) chowncmd="$chownprog $2"
13835c4bbdfSmrg        shift;;
13905b261ecSmrg
14035c4bbdfSmrg    -s) stripcmd=$stripprog;;
14105b261ecSmrg
14235c4bbdfSmrg    -t)
14335c4bbdfSmrg        is_target_a_directory=always
14435c4bbdfSmrg        dst_arg=$2
14535c4bbdfSmrg        # Protect names problematic for 'test' and other utilities.
14635c4bbdfSmrg        case $dst_arg in
14735c4bbdfSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
14835c4bbdfSmrg        esac
14935c4bbdfSmrg        shift;;
15005b261ecSmrg
15135c4bbdfSmrg    -T) is_target_a_directory=never;;
15205b261ecSmrg
15305b261ecSmrg    --version) echo "$0 $scriptversion"; exit $?;;
15405b261ecSmrg
15535c4bbdfSmrg    --) shift
15635c4bbdfSmrg        break;;
15705b261ecSmrg
15835c4bbdfSmrg    -*) echo "$0: invalid option: $1" >&2
15935c4bbdfSmrg        exit 1;;
16005b261ecSmrg
16105b261ecSmrg    *)  break;;
16205b261ecSmrg  esac
16335c4bbdfSmrg  shift
16405b261ecSmrgdone
16505b261ecSmrg
16635c4bbdfSmrg# We allow the use of options -d and -T together, by making -d
16735c4bbdfSmrg# take the precedence; this is for compatibility with GNU install.
16835c4bbdfSmrg
16935c4bbdfSmrgif test -n "$dir_arg"; then
17035c4bbdfSmrg  if test -n "$dst_arg"; then
17135c4bbdfSmrg    echo "$0: target directory not allowed when installing a directory." >&2
17235c4bbdfSmrg    exit 1
17335c4bbdfSmrg  fi
17435c4bbdfSmrgfi
17535c4bbdfSmrg
17635c4bbdfSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
17705b261ecSmrg  # When -d is used, all remaining arguments are directories to create.
17805b261ecSmrg  # When -t is used, the destination is already specified.
17905b261ecSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
18005b261ecSmrg  for arg
18105b261ecSmrg  do
18235c4bbdfSmrg    if test -n "$dst_arg"; then
18305b261ecSmrg      # $@ is not empty: it contains at least $arg.
18435c4bbdfSmrg      set fnord "$@" "$dst_arg"
18505b261ecSmrg      shift # fnord
18605b261ecSmrg    fi
18705b261ecSmrg    shift # arg
18835c4bbdfSmrg    dst_arg=$arg
18935c4bbdfSmrg    # Protect names problematic for 'test' and other utilities.
19035c4bbdfSmrg    case $dst_arg in
19135c4bbdfSmrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
19235c4bbdfSmrg    esac
19305b261ecSmrg  done
19405b261ecSmrgfi
19505b261ecSmrg
19605b261ecSmrgif test $# -eq 0; then
19705b261ecSmrg  if test -z "$dir_arg"; then
19805b261ecSmrg    echo "$0: no input file specified." >&2
19905b261ecSmrg    exit 1
20005b261ecSmrg  fi
20135c4bbdfSmrg  # It's OK to call 'install-sh -d' without argument.
20205b261ecSmrg  # This can happen when creating conditional directories.
20305b261ecSmrg  exit 0
20405b261ecSmrgfi
20505b261ecSmrg
20605b261ecSmrgif test -z "$dir_arg"; then
20735c4bbdfSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
20835c4bbdfSmrg    if test ! -d "$dst_arg"; then
20935c4bbdfSmrg      echo "$0: $dst_arg: Is not a directory." >&2
21035c4bbdfSmrg      exit 1
21135c4bbdfSmrg    fi
21235c4bbdfSmrg  fi
21335c4bbdfSmrgfi
21435c4bbdfSmrg
21535c4bbdfSmrgif test -z "$dir_arg"; then
21635c4bbdfSmrg  do_exit='(exit $ret); exit $ret'
21735c4bbdfSmrg  trap "ret=129; $do_exit" 1
21835c4bbdfSmrg  trap "ret=130; $do_exit" 2
21935c4bbdfSmrg  trap "ret=141; $do_exit" 13
22035c4bbdfSmrg  trap "ret=143; $do_exit" 15
22105b261ecSmrg
22205b261ecSmrg  # Set umask so as not to create temps with too-generous modes.
22305b261ecSmrg  # However, 'strip' requires both read and write access to temps.
22405b261ecSmrg  case $mode in
22505b261ecSmrg    # Optimize common cases.
22605b261ecSmrg    *644) cp_umask=133;;
22705b261ecSmrg    *755) cp_umask=22;;
22805b261ecSmrg
22905b261ecSmrg    *[0-7])
23005b261ecSmrg      if test -z "$stripcmd"; then
23135c4bbdfSmrg        u_plus_rw=
23205b261ecSmrg      else
23335c4bbdfSmrg        u_plus_rw='% 200'
23405b261ecSmrg      fi
23505b261ecSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
23605b261ecSmrg    *)
23705b261ecSmrg      if test -z "$stripcmd"; then
23835c4bbdfSmrg        u_plus_rw=
23905b261ecSmrg      else
24035c4bbdfSmrg        u_plus_rw=,u+rw
24105b261ecSmrg      fi
24205b261ecSmrg      cp_umask=$mode$u_plus_rw;;
24305b261ecSmrg  esac
24405b261ecSmrgfi
24505b261ecSmrg
24605b261ecSmrgfor src
24705b261ecSmrgdo
24835c4bbdfSmrg  # Protect names problematic for 'test' and other utilities.
24905b261ecSmrg  case $src in
25035c4bbdfSmrg    -* | [=\(\)!]) src=./$src;;
25105b261ecSmrg  esac
25205b261ecSmrg
25305b261ecSmrg  if test -n "$dir_arg"; then
25405b261ecSmrg    dst=$src
25505b261ecSmrg    dstdir=$dst
25605b261ecSmrg    test -d "$dstdir"
25705b261ecSmrg    dstdir_status=$?
25805b261ecSmrg  else
25905b261ecSmrg
26005b261ecSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
26105b261ecSmrg    # might cause directories to be created, which would be especially bad
26205b261ecSmrg    # if $src (and thus $dsttmp) contains '*'.
26305b261ecSmrg    if test ! -f "$src" && test ! -d "$src"; then
26405b261ecSmrg      echo "$0: $src does not exist." >&2
26505b261ecSmrg      exit 1
26605b261ecSmrg    fi
26705b261ecSmrg
26835c4bbdfSmrg    if test -z "$dst_arg"; then
26905b261ecSmrg      echo "$0: no destination specified." >&2
27005b261ecSmrg      exit 1
27105b261ecSmrg    fi
27235c4bbdfSmrg    dst=$dst_arg
27305b261ecSmrg
27405b261ecSmrg    # If destination is a directory, append the input filename; won't work
27505b261ecSmrg    # if double slashes aren't ignored.
27605b261ecSmrg    if test -d "$dst"; then
27735c4bbdfSmrg      if test "$is_target_a_directory" = never; then
27835c4bbdfSmrg        echo "$0: $dst_arg: Is a directory" >&2
27935c4bbdfSmrg        exit 1
28005b261ecSmrg      fi
28105b261ecSmrg      dstdir=$dst
28205b261ecSmrg      dst=$dstdir/`basename "$src"`
28305b261ecSmrg      dstdir_status=0
28405b261ecSmrg    else
28535c4bbdfSmrg      dstdir=`dirname "$dst"`
28605b261ecSmrg      test -d "$dstdir"
28705b261ecSmrg      dstdir_status=$?
28805b261ecSmrg    fi
28905b261ecSmrg  fi
29005b261ecSmrg
29105b261ecSmrg  obsolete_mkdir_used=false
29205b261ecSmrg
29305b261ecSmrg  if test $dstdir_status != 0; then
29405b261ecSmrg    case $posix_mkdir in
29505b261ecSmrg      '')
29635c4bbdfSmrg        # Create intermediate dirs using mode 755 as modified by the umask.
29735c4bbdfSmrg        # This is like FreeBSD 'install' as of 1997-10-28.
29835c4bbdfSmrg        umask=`umask`
29935c4bbdfSmrg        case $stripcmd.$umask in
30035c4bbdfSmrg          # Optimize common cases.
30135c4bbdfSmrg          *[2367][2367]) mkdir_umask=$umask;;
30235c4bbdfSmrg          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
30335c4bbdfSmrg
30435c4bbdfSmrg          *[0-7])
30535c4bbdfSmrg            mkdir_umask=`expr $umask + 22 \
30635c4bbdfSmrg              - $umask % 100 % 40 + $umask % 20 \
30735c4bbdfSmrg              - $umask % 10 % 4 + $umask % 2
30835c4bbdfSmrg            `;;
30935c4bbdfSmrg          *) mkdir_umask=$umask,go-w;;
31035c4bbdfSmrg        esac
31135c4bbdfSmrg
31235c4bbdfSmrg        # With -d, create the new directory with the user-specified mode.
31335c4bbdfSmrg        # Otherwise, rely on $mkdir_umask.
31435c4bbdfSmrg        if test -n "$dir_arg"; then
31535c4bbdfSmrg          mkdir_mode=-m$mode
31635c4bbdfSmrg        else
31735c4bbdfSmrg          mkdir_mode=
31835c4bbdfSmrg        fi
31935c4bbdfSmrg
32035c4bbdfSmrg        posix_mkdir=false
32135c4bbdfSmrg        case $umask in
32235c4bbdfSmrg          *[123567][0-7][0-7])
32335c4bbdfSmrg            # POSIX mkdir -p sets u+wx bits regardless of umask, which
32435c4bbdfSmrg            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
32535c4bbdfSmrg            ;;
32635c4bbdfSmrg          *)
32735c4bbdfSmrg            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
32835c4bbdfSmrg            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
32935c4bbdfSmrg
33035c4bbdfSmrg            if (umask $mkdir_umask &&
33135c4bbdfSmrg                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
33235c4bbdfSmrg            then
33335c4bbdfSmrg              if test -z "$dir_arg" || {
33435c4bbdfSmrg                   # Check for POSIX incompatibilities with -m.
33535c4bbdfSmrg                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
33635c4bbdfSmrg                   # other-writable bit of parent directory when it shouldn't.
33735c4bbdfSmrg                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
33835c4bbdfSmrg                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
33935c4bbdfSmrg                   case $ls_ld_tmpdir in
34035c4bbdfSmrg                     d????-?r-*) different_mode=700;;
34135c4bbdfSmrg                     d????-?--*) different_mode=755;;
34235c4bbdfSmrg                     *) false;;
34335c4bbdfSmrg                   esac &&
34435c4bbdfSmrg                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
34535c4bbdfSmrg                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
34635c4bbdfSmrg                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
34735c4bbdfSmrg                   }
34835c4bbdfSmrg                 }
34935c4bbdfSmrg              then posix_mkdir=:
35035c4bbdfSmrg              fi
35135c4bbdfSmrg              rmdir "$tmpdir/d" "$tmpdir"
35235c4bbdfSmrg            else
35335c4bbdfSmrg              # Remove any dirs left behind by ancient mkdir implementations.
35435c4bbdfSmrg              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
35535c4bbdfSmrg            fi
35635c4bbdfSmrg            trap '' 0;;
35735c4bbdfSmrg        esac;;
35805b261ecSmrg    esac
35905b261ecSmrg
36005b261ecSmrg    if
36105b261ecSmrg      $posix_mkdir && (
36235c4bbdfSmrg        umask $mkdir_umask &&
36335c4bbdfSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
36405b261ecSmrg      )
36505b261ecSmrg    then :
36605b261ecSmrg    else
36705b261ecSmrg
36805b261ecSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
36905b261ecSmrg      # or it failed possibly due to a race condition.  Create the
37005b261ecSmrg      # directory the slow way, step by step, checking for races as we go.
37105b261ecSmrg
37205b261ecSmrg      case $dstdir in
37335c4bbdfSmrg        /*) prefix='/';;
37435c4bbdfSmrg        [-=\(\)!]*) prefix='./';;
37535c4bbdfSmrg        *)  prefix='';;
376475c125cSmrg      esac
37705b261ecSmrg
37805b261ecSmrg      oIFS=$IFS
37905b261ecSmrg      IFS=/
38035c4bbdfSmrg      set -f
38105b261ecSmrg      set fnord $dstdir
38205b261ecSmrg      shift
38335c4bbdfSmrg      set +f
38405b261ecSmrg      IFS=$oIFS
38505b261ecSmrg
38605b261ecSmrg      prefixes=
38705b261ecSmrg
38805b261ecSmrg      for d
38905b261ecSmrg      do
39035c4bbdfSmrg        test X"$d" = X && continue
39135c4bbdfSmrg
39235c4bbdfSmrg        prefix=$prefix$d
39335c4bbdfSmrg        if test -d "$prefix"; then
39435c4bbdfSmrg          prefixes=
39535c4bbdfSmrg        else
39635c4bbdfSmrg          if $posix_mkdir; then
39735c4bbdfSmrg            (umask=$mkdir_umask &&
39835c4bbdfSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
39935c4bbdfSmrg            # Don't fail if two instances are running concurrently.
40035c4bbdfSmrg            test -d "$prefix" || exit 1
40135c4bbdfSmrg          else
40235c4bbdfSmrg            case $prefix in
40335c4bbdfSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
40435c4bbdfSmrg              *) qprefix=$prefix;;
40535c4bbdfSmrg            esac
40635c4bbdfSmrg            prefixes="$prefixes '$qprefix'"
40735c4bbdfSmrg          fi
40835c4bbdfSmrg        fi
40935c4bbdfSmrg        prefix=$prefix/
41005b261ecSmrg      done
41105b261ecSmrg
41205b261ecSmrg      if test -n "$prefixes"; then
41335c4bbdfSmrg        # Don't fail if two instances are running concurrently.
41435c4bbdfSmrg        (umask $mkdir_umask &&
41535c4bbdfSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
41635c4bbdfSmrg          test -d "$dstdir" || exit 1
41735c4bbdfSmrg        obsolete_mkdir_used=true
41805b261ecSmrg      fi
41905b261ecSmrg    fi
42005b261ecSmrg  fi
42105b261ecSmrg
42205b261ecSmrg  if test -n "$dir_arg"; then
42305b261ecSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
42405b261ecSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
42505b261ecSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
42605b261ecSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
42705b261ecSmrg  else
42805b261ecSmrg
42905b261ecSmrg    # Make a couple of temp file names in the proper directory.
43005b261ecSmrg    dsttmp=$dstdir/_inst.$$_
43105b261ecSmrg    rmtmp=$dstdir/_rm.$$_
43205b261ecSmrg
43305b261ecSmrg    # Trap to clean up those temp files at exit.
43405b261ecSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
43505b261ecSmrg
43605b261ecSmrg    # Copy the file name to the temp name.
43705b261ecSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
43805b261ecSmrg
43905b261ecSmrg    # and set any options; do chmod last to preserve setuid bits.
44005b261ecSmrg    #
44105b261ecSmrg    # If any of these fail, we abort the whole thing.  If we want to
44205b261ecSmrg    # ignore errors from any of these, just make sure not to ignore
44305b261ecSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
44405b261ecSmrg    #
44535c4bbdfSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
44635c4bbdfSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
44735c4bbdfSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
44835c4bbdfSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
44935c4bbdfSmrg
45035c4bbdfSmrg    # If -C, don't bother to copy if it wouldn't change the file.
45135c4bbdfSmrg    if $copy_on_change &&
45235c4bbdfSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
45335c4bbdfSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
45435c4bbdfSmrg       set -f &&
45535c4bbdfSmrg       set X $old && old=:$2:$4:$5:$6 &&
45635c4bbdfSmrg       set X $new && new=:$2:$4:$5:$6 &&
45735c4bbdfSmrg       set +f &&
45835c4bbdfSmrg       test "$old" = "$new" &&
45935c4bbdfSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
46035c4bbdfSmrg    then
46135c4bbdfSmrg      rm -f "$dsttmp"
46235c4bbdfSmrg    else
46335c4bbdfSmrg      # Rename the file to the real destination.
46435c4bbdfSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
46535c4bbdfSmrg
46635c4bbdfSmrg      # The rename failed, perhaps because mv can't rename something else
46735c4bbdfSmrg      # to itself, or perhaps because mv is so ancient that it does not
46835c4bbdfSmrg      # support -f.
46935c4bbdfSmrg      {
47035c4bbdfSmrg        # Now remove or move aside any old file at destination location.
47135c4bbdfSmrg        # We try this two ways since rm can't unlink itself on some
47235c4bbdfSmrg        # systems and the destination file might be busy for other
47335c4bbdfSmrg        # reasons.  In this case, the final cleanup might fail but the new
47435c4bbdfSmrg        # file should still install successfully.
47535c4bbdfSmrg        {
47635c4bbdfSmrg          test ! -f "$dst" ||
47735c4bbdfSmrg          $doit $rmcmd -f "$dst" 2>/dev/null ||
47835c4bbdfSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
47935c4bbdfSmrg            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
48035c4bbdfSmrg          } ||
48135c4bbdfSmrg          { echo "$0: cannot unlink or rename $dst" >&2
48235c4bbdfSmrg            (exit 1); exit 1
48335c4bbdfSmrg          }
48435c4bbdfSmrg        } &&
48535c4bbdfSmrg
48635c4bbdfSmrg        # Now rename the file to the real destination.
48735c4bbdfSmrg        $doit $mvcmd "$dsttmp" "$dst"
48835c4bbdfSmrg      }
48935c4bbdfSmrg    fi || exit 1
49005b261ecSmrg
49105b261ecSmrg    trap '' 0
49205b261ecSmrg  fi
49305b261ecSmrgdone
49405b261ecSmrg
49505b261ecSmrg# Local variables:
49605b261ecSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
49705b261ecSmrg# time-stamp-start: "scriptversion="
49805b261ecSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
49935c4bbdfSmrg# time-stamp-time-zone: "UTC"
50035c4bbdfSmrg# time-stamp-end: "; # UTC"
50105b261ecSmrg# End:
502