install-sh revision 9cd34f4b
13e747e6dSmrg#!/bin/sh
23e747e6dSmrg# install - install a program, script, or datafile
33e747e6dSmrg
49cd34f4bSmrgscriptversion=2013-12-25.23; # UTC
53e747e6dSmrg
63e747e6dSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
73e747e6dSmrg# later released in X11R6 (xc/config/util/install.sh) with the
83e747e6dSmrg# following copyright and license.
93e747e6dSmrg#
103e747e6dSmrg# Copyright (C) 1994 X Consortium
113e747e6dSmrg#
123e747e6dSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
133e747e6dSmrg# of this software and associated documentation files (the "Software"), to
143e747e6dSmrg# deal in the Software without restriction, including without limitation the
153e747e6dSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
163e747e6dSmrg# sell copies of the Software, and to permit persons to whom the Software is
173e747e6dSmrg# furnished to do so, subject to the following conditions:
183e747e6dSmrg#
193e747e6dSmrg# The above copyright notice and this permission notice shall be included in
203e747e6dSmrg# all copies or substantial portions of the Software.
213e747e6dSmrg#
223e747e6dSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233e747e6dSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
243e747e6dSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
253e747e6dSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
263e747e6dSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
273e747e6dSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
283e747e6dSmrg#
293e747e6dSmrg# Except as contained in this notice, the name of the X Consortium shall not
303e747e6dSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
313e747e6dSmrg# ings in this Software without prior written authorization from the X Consor-
323e747e6dSmrg# tium.
333e747e6dSmrg#
343e747e6dSmrg#
353e747e6dSmrg# FSF changes to this file are in the public domain.
363e747e6dSmrg#
373e747e6dSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38c2535118Smrg# 'make' implicit rules from creating a file called install from it
393e747e6dSmrg# when there is no Makefile.
403e747e6dSmrg#
413e747e6dSmrg# This script is compatible with the BSD install script, but was written
423e747e6dSmrg# from scratch.
433e747e6dSmrg
449cd34f4bSmrgtab='	'
453e747e6dSmrgnl='
463e747e6dSmrg'
479cd34f4bSmrgIFS=" $tab$nl"
483e747e6dSmrg
499cd34f4bSmrg# Set DOITPROG to "echo" to test this script.
503e747e6dSmrg
513e747e6dSmrgdoit=${DOITPROG-}
529cd34f4bSmrgdoit_exec=${doit:-exec}
533e747e6dSmrg
543e747e6dSmrg# Put in absolute file names if you don't have them in your path;
553e747e6dSmrg# or use environment vars.
563e747e6dSmrg
573e747e6dSmrgchgrpprog=${CHGRPPROG-chgrp}
583e747e6dSmrgchmodprog=${CHMODPROG-chmod}
593e747e6dSmrgchownprog=${CHOWNPROG-chown}
603e747e6dSmrgcmpprog=${CMPPROG-cmp}
613e747e6dSmrgcpprog=${CPPROG-cp}
623e747e6dSmrgmkdirprog=${MKDIRPROG-mkdir}
633e747e6dSmrgmvprog=${MVPROG-mv}
643e747e6dSmrgrmprog=${RMPROG-rm}
653e747e6dSmrgstripprog=${STRIPPROG-strip}
663e747e6dSmrg
673e747e6dSmrgposix_mkdir=
683e747e6dSmrg
693e747e6dSmrg# Desired mode of installed file.
703e747e6dSmrgmode=0755
713e747e6dSmrg
723e747e6dSmrgchgrpcmd=
733e747e6dSmrgchmodcmd=$chmodprog
743e747e6dSmrgchowncmd=
753e747e6dSmrgmvcmd=$mvprog
763e747e6dSmrgrmcmd="$rmprog -f"
773e747e6dSmrgstripcmd=
783e747e6dSmrg
793e747e6dSmrgsrc=
803e747e6dSmrgdst=
813e747e6dSmrgdir_arg=
823e747e6dSmrgdst_arg=
833e747e6dSmrg
843e747e6dSmrgcopy_on_change=false
859cd34f4bSmrgis_target_a_directory=possibly
863e747e6dSmrg
873e747e6dSmrgusage="\
883e747e6dSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
893e747e6dSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
903e747e6dSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
913e747e6dSmrg   or: $0 [OPTION]... -d DIRECTORIES...
923e747e6dSmrg
933e747e6dSmrgIn the 1st form, copy SRCFILE to DSTFILE.
943e747e6dSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
953e747e6dSmrgIn the 4th, create DIRECTORIES.
963e747e6dSmrg
973e747e6dSmrgOptions:
983e747e6dSmrg     --help     display this help and exit.
993e747e6dSmrg     --version  display version info and exit.
1003e747e6dSmrg
1013e747e6dSmrg  -c            (ignored)
1023e747e6dSmrg  -C            install only if different (preserve the last data modification time)
1033e747e6dSmrg  -d            create directories instead of installing files.
1043e747e6dSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1053e747e6dSmrg  -m MODE       $chmodprog installed files to MODE.
1063e747e6dSmrg  -o USER       $chownprog installed files to USER.
1073e747e6dSmrg  -s            $stripprog installed files.
1083e747e6dSmrg  -t DIRECTORY  install into DIRECTORY.
1093e747e6dSmrg  -T            report an error if DSTFILE is a directory.
1103e747e6dSmrg
1113e747e6dSmrgEnvironment variables override the default commands:
1123e747e6dSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1133e747e6dSmrg  RMPROG STRIPPROG
1143e747e6dSmrg"
1153e747e6dSmrg
1163e747e6dSmrgwhile test $# -ne 0; do
1173e747e6dSmrg  case $1 in
1183e747e6dSmrg    -c) ;;
1193e747e6dSmrg
1203e747e6dSmrg    -C) copy_on_change=true;;
1213e747e6dSmrg
1223e747e6dSmrg    -d) dir_arg=true;;
1233e747e6dSmrg
1243e747e6dSmrg    -g) chgrpcmd="$chgrpprog $2"
1259cd34f4bSmrg        shift;;
1263e747e6dSmrg
1273e747e6dSmrg    --help) echo "$usage"; exit $?;;
1283e747e6dSmrg
1293e747e6dSmrg    -m) mode=$2
1309cd34f4bSmrg        case $mode in
1319cd34f4bSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1329cd34f4bSmrg            echo "$0: invalid mode: $mode" >&2
1339cd34f4bSmrg            exit 1;;
1349cd34f4bSmrg        esac
1359cd34f4bSmrg        shift;;
1363e747e6dSmrg
1373e747e6dSmrg    -o) chowncmd="$chownprog $2"
1389cd34f4bSmrg        shift;;
1393e747e6dSmrg
1403e747e6dSmrg    -s) stripcmd=$stripprog;;
1413e747e6dSmrg
1429cd34f4bSmrg    -t)
1439cd34f4bSmrg        is_target_a_directory=always
1449cd34f4bSmrg        dst_arg=$2
1459cd34f4bSmrg        # Protect names problematic for 'test' and other utilities.
1469cd34f4bSmrg        case $dst_arg in
1479cd34f4bSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1489cd34f4bSmrg        esac
1499cd34f4bSmrg        shift;;
1503e747e6dSmrg
1519cd34f4bSmrg    -T) is_target_a_directory=never;;
1523e747e6dSmrg
1533e747e6dSmrg    --version) echo "$0 $scriptversion"; exit $?;;
1543e747e6dSmrg
1559cd34f4bSmrg    --) shift
1569cd34f4bSmrg        break;;
1573e747e6dSmrg
1589cd34f4bSmrg    -*) echo "$0: invalid option: $1" >&2
1599cd34f4bSmrg        exit 1;;
1603e747e6dSmrg
1613e747e6dSmrg    *)  break;;
1623e747e6dSmrg  esac
1633e747e6dSmrg  shift
1643e747e6dSmrgdone
1653e747e6dSmrg
1669cd34f4bSmrg# We allow the use of options -d and -T together, by making -d
1679cd34f4bSmrg# take the precedence; this is for compatibility with GNU install.
1689cd34f4bSmrg
1699cd34f4bSmrgif test -n "$dir_arg"; then
1709cd34f4bSmrg  if test -n "$dst_arg"; then
1719cd34f4bSmrg    echo "$0: target directory not allowed when installing a directory." >&2
1729cd34f4bSmrg    exit 1
1739cd34f4bSmrg  fi
1749cd34f4bSmrgfi
1759cd34f4bSmrg
1763e747e6dSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1773e747e6dSmrg  # When -d is used, all remaining arguments are directories to create.
1783e747e6dSmrg  # When -t is used, the destination is already specified.
1793e747e6dSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1803e747e6dSmrg  for arg
1813e747e6dSmrg  do
1823e747e6dSmrg    if test -n "$dst_arg"; then
1833e747e6dSmrg      # $@ is not empty: it contains at least $arg.
1843e747e6dSmrg      set fnord "$@" "$dst_arg"
1853e747e6dSmrg      shift # fnord
1863e747e6dSmrg    fi
1873e747e6dSmrg    shift # arg
1883e747e6dSmrg    dst_arg=$arg
189c2535118Smrg    # Protect names problematic for 'test' and other utilities.
190c2535118Smrg    case $dst_arg in
191c2535118Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
192c2535118Smrg    esac
1933e747e6dSmrg  done
1943e747e6dSmrgfi
1953e747e6dSmrg
1963e747e6dSmrgif test $# -eq 0; then
1973e747e6dSmrg  if test -z "$dir_arg"; then
1983e747e6dSmrg    echo "$0: no input file specified." >&2
1993e747e6dSmrg    exit 1
2003e747e6dSmrg  fi
201c2535118Smrg  # It's OK to call 'install-sh -d' without argument.
2023e747e6dSmrg  # This can happen when creating conditional directories.
2033e747e6dSmrg  exit 0
2043e747e6dSmrgfi
2053e747e6dSmrg
2069cd34f4bSmrgif test -z "$dir_arg"; then
2079cd34f4bSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
2089cd34f4bSmrg    if test ! -d "$dst_arg"; then
2099cd34f4bSmrg      echo "$0: $dst_arg: Is not a directory." >&2
2109cd34f4bSmrg      exit 1
2119cd34f4bSmrg    fi
2129cd34f4bSmrg  fi
2139cd34f4bSmrgfi
2149cd34f4bSmrg
2153e747e6dSmrgif test -z "$dir_arg"; then
216c2535118Smrg  do_exit='(exit $ret); exit $ret'
217c2535118Smrg  trap "ret=129; $do_exit" 1
218c2535118Smrg  trap "ret=130; $do_exit" 2
219c2535118Smrg  trap "ret=141; $do_exit" 13
220c2535118Smrg  trap "ret=143; $do_exit" 15
2213e747e6dSmrg
2223e747e6dSmrg  # Set umask so as not to create temps with too-generous modes.
2233e747e6dSmrg  # However, 'strip' requires both read and write access to temps.
2243e747e6dSmrg  case $mode in
2253e747e6dSmrg    # Optimize common cases.
2263e747e6dSmrg    *644) cp_umask=133;;
2273e747e6dSmrg    *755) cp_umask=22;;
2283e747e6dSmrg
2293e747e6dSmrg    *[0-7])
2303e747e6dSmrg      if test -z "$stripcmd"; then
2319cd34f4bSmrg        u_plus_rw=
2323e747e6dSmrg      else
2339cd34f4bSmrg        u_plus_rw='% 200'
2343e747e6dSmrg      fi
2353e747e6dSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2363e747e6dSmrg    *)
2373e747e6dSmrg      if test -z "$stripcmd"; then
2389cd34f4bSmrg        u_plus_rw=
2393e747e6dSmrg      else
2409cd34f4bSmrg        u_plus_rw=,u+rw
2413e747e6dSmrg      fi
2423e747e6dSmrg      cp_umask=$mode$u_plus_rw;;
2433e747e6dSmrg  esac
2443e747e6dSmrgfi
2453e747e6dSmrg
2463e747e6dSmrgfor src
2473e747e6dSmrgdo
248c2535118Smrg  # Protect names problematic for 'test' and other utilities.
2493e747e6dSmrg  case $src in
250c2535118Smrg    -* | [=\(\)!]) src=./$src;;
2513e747e6dSmrg  esac
2523e747e6dSmrg
2533e747e6dSmrg  if test -n "$dir_arg"; then
2543e747e6dSmrg    dst=$src
2553e747e6dSmrg    dstdir=$dst
2563e747e6dSmrg    test -d "$dstdir"
2573e747e6dSmrg    dstdir_status=$?
2583e747e6dSmrg  else
2593e747e6dSmrg
2603e747e6dSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2613e747e6dSmrg    # might cause directories to be created, which would be especially bad
2623e747e6dSmrg    # if $src (and thus $dsttmp) contains '*'.
2633e747e6dSmrg    if test ! -f "$src" && test ! -d "$src"; then
2643e747e6dSmrg      echo "$0: $src does not exist." >&2
2653e747e6dSmrg      exit 1
2663e747e6dSmrg    fi
2673e747e6dSmrg
2683e747e6dSmrg    if test -z "$dst_arg"; then
2693e747e6dSmrg      echo "$0: no destination specified." >&2
2703e747e6dSmrg      exit 1
2713e747e6dSmrg    fi
2723e747e6dSmrg    dst=$dst_arg
2733e747e6dSmrg
2743e747e6dSmrg    # If destination is a directory, append the input filename; won't work
2753e747e6dSmrg    # if double slashes aren't ignored.
2763e747e6dSmrg    if test -d "$dst"; then
2779cd34f4bSmrg      if test "$is_target_a_directory" = never; then
2789cd34f4bSmrg        echo "$0: $dst_arg: Is a directory" >&2
2799cd34f4bSmrg        exit 1
2803e747e6dSmrg      fi
2813e747e6dSmrg      dstdir=$dst
2823e747e6dSmrg      dst=$dstdir/`basename "$src"`
2833e747e6dSmrg      dstdir_status=0
2843e747e6dSmrg    else
2859cd34f4bSmrg      dstdir=`dirname "$dst"`
2863e747e6dSmrg      test -d "$dstdir"
2873e747e6dSmrg      dstdir_status=$?
2883e747e6dSmrg    fi
2893e747e6dSmrg  fi
2903e747e6dSmrg
2913e747e6dSmrg  obsolete_mkdir_used=false
2923e747e6dSmrg
2933e747e6dSmrg  if test $dstdir_status != 0; then
2943e747e6dSmrg    case $posix_mkdir in
2953e747e6dSmrg      '')
2969cd34f4bSmrg        # Create intermediate dirs using mode 755 as modified by the umask.
2979cd34f4bSmrg        # This is like FreeBSD 'install' as of 1997-10-28.
2989cd34f4bSmrg        umask=`umask`
2999cd34f4bSmrg        case $stripcmd.$umask in
3009cd34f4bSmrg          # Optimize common cases.
3019cd34f4bSmrg          *[2367][2367]) mkdir_umask=$umask;;
3029cd34f4bSmrg          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3039cd34f4bSmrg
3049cd34f4bSmrg          *[0-7])
3059cd34f4bSmrg            mkdir_umask=`expr $umask + 22 \
3069cd34f4bSmrg              - $umask % 100 % 40 + $umask % 20 \
3079cd34f4bSmrg              - $umask % 10 % 4 + $umask % 2
3089cd34f4bSmrg            `;;
3099cd34f4bSmrg          *) mkdir_umask=$umask,go-w;;
3109cd34f4bSmrg        esac
3119cd34f4bSmrg
3129cd34f4bSmrg        # With -d, create the new directory with the user-specified mode.
3139cd34f4bSmrg        # Otherwise, rely on $mkdir_umask.
3149cd34f4bSmrg        if test -n "$dir_arg"; then
3159cd34f4bSmrg          mkdir_mode=-m$mode
3169cd34f4bSmrg        else
3179cd34f4bSmrg          mkdir_mode=
3189cd34f4bSmrg        fi
3199cd34f4bSmrg
3209cd34f4bSmrg        posix_mkdir=false
3219cd34f4bSmrg        case $umask in
3229cd34f4bSmrg          *[123567][0-7][0-7])
3239cd34f4bSmrg            # POSIX mkdir -p sets u+wx bits regardless of umask, which
3249cd34f4bSmrg            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3259cd34f4bSmrg            ;;
3269cd34f4bSmrg          *)
3279cd34f4bSmrg            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3289cd34f4bSmrg            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3299cd34f4bSmrg
3309cd34f4bSmrg            if (umask $mkdir_umask &&
3319cd34f4bSmrg                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3329cd34f4bSmrg            then
3339cd34f4bSmrg              if test -z "$dir_arg" || {
3349cd34f4bSmrg                   # Check for POSIX incompatibilities with -m.
3359cd34f4bSmrg                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3369cd34f4bSmrg                   # other-writable bit of parent directory when it shouldn't.
3379cd34f4bSmrg                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3389cd34f4bSmrg                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3399cd34f4bSmrg                   case $ls_ld_tmpdir in
3409cd34f4bSmrg                     d????-?r-*) different_mode=700;;
3419cd34f4bSmrg                     d????-?--*) different_mode=755;;
3429cd34f4bSmrg                     *) false;;
3439cd34f4bSmrg                   esac &&
3449cd34f4bSmrg                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3459cd34f4bSmrg                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3469cd34f4bSmrg                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3479cd34f4bSmrg                   }
3489cd34f4bSmrg                 }
3499cd34f4bSmrg              then posix_mkdir=:
3509cd34f4bSmrg              fi
3519cd34f4bSmrg              rmdir "$tmpdir/d" "$tmpdir"
3529cd34f4bSmrg            else
3539cd34f4bSmrg              # Remove any dirs left behind by ancient mkdir implementations.
3549cd34f4bSmrg              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3559cd34f4bSmrg            fi
3569cd34f4bSmrg            trap '' 0;;
3579cd34f4bSmrg        esac;;
3583e747e6dSmrg    esac
3593e747e6dSmrg
3603e747e6dSmrg    if
3613e747e6dSmrg      $posix_mkdir && (
3629cd34f4bSmrg        umask $mkdir_umask &&
3639cd34f4bSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3643e747e6dSmrg      )
3653e747e6dSmrg    then :
3663e747e6dSmrg    else
3673e747e6dSmrg
3683e747e6dSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3693e747e6dSmrg      # or it failed possibly due to a race condition.  Create the
3703e747e6dSmrg      # directory the slow way, step by step, checking for races as we go.
3713e747e6dSmrg
3723e747e6dSmrg      case $dstdir in
3739cd34f4bSmrg        /*) prefix='/';;
3749cd34f4bSmrg        [-=\(\)!]*) prefix='./';;
3759cd34f4bSmrg        *)  prefix='';;
3763e747e6dSmrg      esac
3773e747e6dSmrg
3783e747e6dSmrg      oIFS=$IFS
3793e747e6dSmrg      IFS=/
3809cd34f4bSmrg      set -f
3813e747e6dSmrg      set fnord $dstdir
3823e747e6dSmrg      shift
3839cd34f4bSmrg      set +f
3843e747e6dSmrg      IFS=$oIFS
3853e747e6dSmrg
3863e747e6dSmrg      prefixes=
3873e747e6dSmrg
3883e747e6dSmrg      for d
3893e747e6dSmrg      do
3909cd34f4bSmrg        test X"$d" = X && continue
3919cd34f4bSmrg
3929cd34f4bSmrg        prefix=$prefix$d
3939cd34f4bSmrg        if test -d "$prefix"; then
3949cd34f4bSmrg          prefixes=
3959cd34f4bSmrg        else
3969cd34f4bSmrg          if $posix_mkdir; then
3979cd34f4bSmrg            (umask=$mkdir_umask &&
3989cd34f4bSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
3999cd34f4bSmrg            # Don't fail if two instances are running concurrently.
4009cd34f4bSmrg            test -d "$prefix" || exit 1
4019cd34f4bSmrg          else
4029cd34f4bSmrg            case $prefix in
4039cd34f4bSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4049cd34f4bSmrg              *) qprefix=$prefix;;
4059cd34f4bSmrg            esac
4069cd34f4bSmrg            prefixes="$prefixes '$qprefix'"
4079cd34f4bSmrg          fi
4089cd34f4bSmrg        fi
4099cd34f4bSmrg        prefix=$prefix/
4103e747e6dSmrg      done
4113e747e6dSmrg
4123e747e6dSmrg      if test -n "$prefixes"; then
4139cd34f4bSmrg        # Don't fail if two instances are running concurrently.
4149cd34f4bSmrg        (umask $mkdir_umask &&
4159cd34f4bSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
4169cd34f4bSmrg          test -d "$dstdir" || exit 1
4179cd34f4bSmrg        obsolete_mkdir_used=true
4183e747e6dSmrg      fi
4193e747e6dSmrg    fi
4203e747e6dSmrg  fi
4213e747e6dSmrg
4223e747e6dSmrg  if test -n "$dir_arg"; then
4233e747e6dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4243e747e6dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4253e747e6dSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4263e747e6dSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4273e747e6dSmrg  else
4283e747e6dSmrg
4293e747e6dSmrg    # Make a couple of temp file names in the proper directory.
4303e747e6dSmrg    dsttmp=$dstdir/_inst.$$_
4313e747e6dSmrg    rmtmp=$dstdir/_rm.$$_
4323e747e6dSmrg
4333e747e6dSmrg    # Trap to clean up those temp files at exit.
4343e747e6dSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4353e747e6dSmrg
4363e747e6dSmrg    # Copy the file name to the temp name.
4373e747e6dSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4383e747e6dSmrg
4393e747e6dSmrg    # and set any options; do chmod last to preserve setuid bits.
4403e747e6dSmrg    #
4413e747e6dSmrg    # If any of these fail, we abort the whole thing.  If we want to
4423e747e6dSmrg    # ignore errors from any of these, just make sure not to ignore
4433e747e6dSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4443e747e6dSmrg    #
4453e747e6dSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4463e747e6dSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4473e747e6dSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4483e747e6dSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4493e747e6dSmrg
4503e747e6dSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4513e747e6dSmrg    if $copy_on_change &&
4529cd34f4bSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4539cd34f4bSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
4549cd34f4bSmrg       set -f &&
4553e747e6dSmrg       set X $old && old=:$2:$4:$5:$6 &&
4563e747e6dSmrg       set X $new && new=:$2:$4:$5:$6 &&
4579cd34f4bSmrg       set +f &&
4583e747e6dSmrg       test "$old" = "$new" &&
4593e747e6dSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4603e747e6dSmrg    then
4613e747e6dSmrg      rm -f "$dsttmp"
4623e747e6dSmrg    else
4633e747e6dSmrg      # Rename the file to the real destination.
4643e747e6dSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4653e747e6dSmrg
4663e747e6dSmrg      # The rename failed, perhaps because mv can't rename something else
4673e747e6dSmrg      # to itself, or perhaps because mv is so ancient that it does not
4683e747e6dSmrg      # support -f.
4693e747e6dSmrg      {
4709cd34f4bSmrg        # Now remove or move aside any old file at destination location.
4719cd34f4bSmrg        # We try this two ways since rm can't unlink itself on some
4729cd34f4bSmrg        # systems and the destination file might be busy for other
4739cd34f4bSmrg        # reasons.  In this case, the final cleanup might fail but the new
4749cd34f4bSmrg        # file should still install successfully.
4759cd34f4bSmrg        {
4769cd34f4bSmrg          test ! -f "$dst" ||
4779cd34f4bSmrg          $doit $rmcmd -f "$dst" 2>/dev/null ||
4789cd34f4bSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4799cd34f4bSmrg            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4809cd34f4bSmrg          } ||
4819cd34f4bSmrg          { echo "$0: cannot unlink or rename $dst" >&2
4829cd34f4bSmrg            (exit 1); exit 1
4839cd34f4bSmrg          }
4849cd34f4bSmrg        } &&
4859cd34f4bSmrg
4869cd34f4bSmrg        # Now rename the file to the real destination.
4879cd34f4bSmrg        $doit $mvcmd "$dsttmp" "$dst"
4883e747e6dSmrg      }
4893e747e6dSmrg    fi || exit 1
4903e747e6dSmrg
4913e747e6dSmrg    trap '' 0
4923e747e6dSmrg  fi
4933e747e6dSmrgdone
4943e747e6dSmrg
4953e747e6dSmrg# Local variables:
4963e747e6dSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
4973e747e6dSmrg# time-stamp-start: "scriptversion="
4983e747e6dSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
4997a2631fcSmrg# time-stamp-time-zone: "UTC"
5007a2631fcSmrg# time-stamp-end: "; # UTC"
5013e747e6dSmrg# End:
502