xref: /netbsd-src/external/bsd/unbound/dist/install-sh (revision d0eba39ba71d0ccd0f91ae4c5ff83442e84710bf)
1*d0eba39bSchristos#!/usr/bin/sh
23b6c3722Schristos# install - install a program, script, or datafile
33b6c3722Schristos
4*d0eba39bSchristosscriptversion=2013-12-25.23; # UTC
53b6c3722Schristos
63b6c3722Schristos# This originates from X11R5 (mit/util/scripts/install.sh), which was
73b6c3722Schristos# later released in X11R6 (xc/config/util/install.sh) with the
83b6c3722Schristos# following copyright and license.
93b6c3722Schristos#
103b6c3722Schristos# Copyright (C) 1994 X Consortium
113b6c3722Schristos#
123b6c3722Schristos# Permission is hereby granted, free of charge, to any person obtaining a copy
133b6c3722Schristos# of this software and associated documentation files (the "Software"), to
143b6c3722Schristos# deal in the Software without restriction, including without limitation the
153b6c3722Schristos# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
163b6c3722Schristos# sell copies of the Software, and to permit persons to whom the Software is
173b6c3722Schristos# furnished to do so, subject to the following conditions:
183b6c3722Schristos#
193b6c3722Schristos# The above copyright notice and this permission notice shall be included in
203b6c3722Schristos# all copies or substantial portions of the Software.
213b6c3722Schristos#
223b6c3722Schristos# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233b6c3722Schristos# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
243b6c3722Schristos# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
253b6c3722Schristos# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
263b6c3722Schristos# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
273b6c3722Schristos# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
283b6c3722Schristos#
293b6c3722Schristos# Except as contained in this notice, the name of the X Consortium shall not
303b6c3722Schristos# be used in advertising or otherwise to promote the sale, use or other deal-
313b6c3722Schristos# ings in this Software without prior written authorization from the X Consor-
323b6c3722Schristos# tium.
333b6c3722Schristos#
343b6c3722Schristos#
353b6c3722Schristos# FSF changes to this file are in the public domain.
363b6c3722Schristos#
373b6c3722Schristos# Calling this script install-sh is preferred over install.sh, to prevent
383b6c3722Schristos# 'make' implicit rules from creating a file called install from it
393b6c3722Schristos# when there is no Makefile.
403b6c3722Schristos#
413b6c3722Schristos# This script is compatible with the BSD install script, but was written
423b6c3722Schristos# from scratch.
433b6c3722Schristos
443b6c3722Schristostab='	'
453b6c3722Schristosnl='
463b6c3722Schristos'
473b6c3722SchristosIFS=" $tab$nl"
483b6c3722Schristos
493b6c3722Schristos# Set DOITPROG to "echo" to test this script.
503b6c3722Schristos
513b6c3722Schristosdoit=${DOITPROG-}
523b6c3722Schristosdoit_exec=${doit:-exec}
533b6c3722Schristos
543b6c3722Schristos# Put in absolute file names if you don't have them in your path;
553b6c3722Schristos# or use environment vars.
563b6c3722Schristos
573b6c3722Schristoschgrpprog=${CHGRPPROG-chgrp}
583b6c3722Schristoschmodprog=${CHMODPROG-chmod}
593b6c3722Schristoschownprog=${CHOWNPROG-chown}
603b6c3722Schristoscmpprog=${CMPPROG-cmp}
613b6c3722Schristoscpprog=${CPPROG-cp}
623b6c3722Schristosmkdirprog=${MKDIRPROG-mkdir}
633b6c3722Schristosmvprog=${MVPROG-mv}
643b6c3722Schristosrmprog=${RMPROG-rm}
653b6c3722Schristosstripprog=${STRIPPROG-strip}
663b6c3722Schristos
673b6c3722Schristosposix_mkdir=
683b6c3722Schristos
693b6c3722Schristos# Desired mode of installed file.
703b6c3722Schristosmode=0755
713b6c3722Schristos
723b6c3722Schristoschgrpcmd=
733b6c3722Schristoschmodcmd=$chmodprog
743b6c3722Schristoschowncmd=
753b6c3722Schristosmvcmd=$mvprog
763b6c3722Schristosrmcmd="$rmprog -f"
773b6c3722Schristosstripcmd=
783b6c3722Schristos
793b6c3722Schristossrc=
803b6c3722Schristosdst=
813b6c3722Schristosdir_arg=
823b6c3722Schristosdst_arg=
833b6c3722Schristos
843b6c3722Schristoscopy_on_change=false
853b6c3722Schristosis_target_a_directory=possibly
863b6c3722Schristos
873b6c3722Schristosusage="\
883b6c3722SchristosUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
893b6c3722Schristos   or: $0 [OPTION]... SRCFILES... DIRECTORY
903b6c3722Schristos   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
913b6c3722Schristos   or: $0 [OPTION]... -d DIRECTORIES...
923b6c3722Schristos
933b6c3722SchristosIn the 1st form, copy SRCFILE to DSTFILE.
943b6c3722SchristosIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
953b6c3722SchristosIn the 4th, create DIRECTORIES.
963b6c3722Schristos
973b6c3722SchristosOptions:
983b6c3722Schristos     --help     display this help and exit.
993b6c3722Schristos     --version  display version info and exit.
1003b6c3722Schristos
1013b6c3722Schristos  -c            (ignored)
1023b6c3722Schristos  -C            install only if different (preserve the last data modification time)
1033b6c3722Schristos  -d            create directories instead of installing files.
1043b6c3722Schristos  -g GROUP      $chgrpprog installed files to GROUP.
1053b6c3722Schristos  -m MODE       $chmodprog installed files to MODE.
1063b6c3722Schristos  -o USER       $chownprog installed files to USER.
1073b6c3722Schristos  -s            $stripprog installed files.
1083b6c3722Schristos  -t DIRECTORY  install into DIRECTORY.
1093b6c3722Schristos  -T            report an error if DSTFILE is a directory.
1103b6c3722Schristos
1113b6c3722SchristosEnvironment variables override the default commands:
1123b6c3722Schristos  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1133b6c3722Schristos  RMPROG STRIPPROG
1143b6c3722Schristos"
1153b6c3722Schristos
1163b6c3722Schristoswhile test $# -ne 0; do
1173b6c3722Schristos  case $1 in
1183b6c3722Schristos    -c) ;;
1193b6c3722Schristos
1203b6c3722Schristos    -C) copy_on_change=true;;
1213b6c3722Schristos
1223b6c3722Schristos    -d) dir_arg=true;;
1233b6c3722Schristos
1243b6c3722Schristos    -g) chgrpcmd="$chgrpprog $2"
1253b6c3722Schristos        shift;;
1263b6c3722Schristos
1273b6c3722Schristos    --help) echo "$usage"; exit $?;;
1283b6c3722Schristos
1293b6c3722Schristos    -m) mode=$2
1303b6c3722Schristos        case $mode in
1313b6c3722Schristos          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1323b6c3722Schristos            echo "$0: invalid mode: $mode" >&2
1333b6c3722Schristos            exit 1;;
1343b6c3722Schristos        esac
1353b6c3722Schristos        shift;;
1363b6c3722Schristos
1373b6c3722Schristos    -o) chowncmd="$chownprog $2"
1383b6c3722Schristos        shift;;
1393b6c3722Schristos
1403b6c3722Schristos    -s) stripcmd=$stripprog;;
1413b6c3722Schristos
1423b6c3722Schristos    -t)
1433b6c3722Schristos        is_target_a_directory=always
1443b6c3722Schristos        dst_arg=$2
1453b6c3722Schristos        # Protect names problematic for 'test' and other utilities.
1463b6c3722Schristos        case $dst_arg in
1473b6c3722Schristos          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1483b6c3722Schristos        esac
1493b6c3722Schristos        shift;;
1503b6c3722Schristos
1513b6c3722Schristos    -T) is_target_a_directory=never;;
1523b6c3722Schristos
1533b6c3722Schristos    --version) echo "$0 $scriptversion"; exit $?;;
1543b6c3722Schristos
1553b6c3722Schristos    --) shift
1563b6c3722Schristos        break;;
1573b6c3722Schristos
1583b6c3722Schristos    -*) echo "$0: invalid option: $1" >&2
1593b6c3722Schristos        exit 1;;
1603b6c3722Schristos
1613b6c3722Schristos    *)  break;;
1623b6c3722Schristos  esac
1633b6c3722Schristos  shift
1643b6c3722Schristosdone
1653b6c3722Schristos
1663b6c3722Schristos# We allow the use of options -d and -T together, by making -d
1673b6c3722Schristos# take the precedence; this is for compatibility with GNU install.
1683b6c3722Schristos
1693b6c3722Schristosif test -n "$dir_arg"; then
1703b6c3722Schristos  if test -n "$dst_arg"; then
1713b6c3722Schristos    echo "$0: target directory not allowed when installing a directory." >&2
1723b6c3722Schristos    exit 1
1733b6c3722Schristos  fi
1743b6c3722Schristosfi
1753b6c3722Schristos
1763b6c3722Schristosif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1773b6c3722Schristos  # When -d is used, all remaining arguments are directories to create.
1783b6c3722Schristos  # When -t is used, the destination is already specified.
1793b6c3722Schristos  # Otherwise, the last argument is the destination.  Remove it from $@.
1803b6c3722Schristos  for arg
1813b6c3722Schristos  do
1823b6c3722Schristos    if test -n "$dst_arg"; then
1833b6c3722Schristos      # $@ is not empty: it contains at least $arg.
1843b6c3722Schristos      set fnord "$@" "$dst_arg"
1853b6c3722Schristos      shift # fnord
1863b6c3722Schristos    fi
1873b6c3722Schristos    shift # arg
1883b6c3722Schristos    dst_arg=$arg
1893b6c3722Schristos    # Protect names problematic for 'test' and other utilities.
1903b6c3722Schristos    case $dst_arg in
1913b6c3722Schristos      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1923b6c3722Schristos    esac
1933b6c3722Schristos  done
1943b6c3722Schristosfi
1953b6c3722Schristos
1963b6c3722Schristosif test $# -eq 0; then
1973b6c3722Schristos  if test -z "$dir_arg"; then
1983b6c3722Schristos    echo "$0: no input file specified." >&2
1993b6c3722Schristos    exit 1
2003b6c3722Schristos  fi
2013b6c3722Schristos  # It's OK to call 'install-sh -d' without argument.
2023b6c3722Schristos  # This can happen when creating conditional directories.
2033b6c3722Schristos  exit 0
2043b6c3722Schristosfi
2053b6c3722Schristos
2063b6c3722Schristosif test -z "$dir_arg"; then
2073b6c3722Schristos  if test $# -gt 1 || test "$is_target_a_directory" = always; then
2083b6c3722Schristos    if test ! -d "$dst_arg"; then
2093b6c3722Schristos      echo "$0: $dst_arg: Is not a directory." >&2
2103b6c3722Schristos      exit 1
2113b6c3722Schristos    fi
2123b6c3722Schristos  fi
2133b6c3722Schristosfi
2143b6c3722Schristos
2153b6c3722Schristosif test -z "$dir_arg"; then
2163b6c3722Schristos  do_exit='(exit $ret); exit $ret'
2173b6c3722Schristos  trap "ret=129; $do_exit" 1
2183b6c3722Schristos  trap "ret=130; $do_exit" 2
2193b6c3722Schristos  trap "ret=141; $do_exit" 13
2203b6c3722Schristos  trap "ret=143; $do_exit" 15
2213b6c3722Schristos
2223b6c3722Schristos  # Set umask so as not to create temps with too-generous modes.
2233b6c3722Schristos  # However, 'strip' requires both read and write access to temps.
2243b6c3722Schristos  case $mode in
2253b6c3722Schristos    # Optimize common cases.
2263b6c3722Schristos    *644) cp_umask=133;;
2273b6c3722Schristos    *755) cp_umask=22;;
2283b6c3722Schristos
2293b6c3722Schristos    *[0-7])
2303b6c3722Schristos      if test -z "$stripcmd"; then
2313b6c3722Schristos        u_plus_rw=
2323b6c3722Schristos      else
2333b6c3722Schristos        u_plus_rw='% 200'
2343b6c3722Schristos      fi
2353b6c3722Schristos      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2363b6c3722Schristos    *)
2373b6c3722Schristos      if test -z "$stripcmd"; then
2383b6c3722Schristos        u_plus_rw=
2393b6c3722Schristos      else
2403b6c3722Schristos        u_plus_rw=,u+rw
2413b6c3722Schristos      fi
2423b6c3722Schristos      cp_umask=$mode$u_plus_rw;;
2433b6c3722Schristos  esac
2443b6c3722Schristosfi
2453b6c3722Schristos
2463b6c3722Schristosfor src
2473b6c3722Schristosdo
2483b6c3722Schristos  # Protect names problematic for 'test' and other utilities.
2493b6c3722Schristos  case $src in
2503b6c3722Schristos    -* | [=\(\)!]) src=./$src;;
2513b6c3722Schristos  esac
2523b6c3722Schristos
2533b6c3722Schristos  if test -n "$dir_arg"; then
2543b6c3722Schristos    dst=$src
2553b6c3722Schristos    dstdir=$dst
2563b6c3722Schristos    test -d "$dstdir"
2573b6c3722Schristos    dstdir_status=$?
2583b6c3722Schristos  else
2593b6c3722Schristos
2603b6c3722Schristos    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2613b6c3722Schristos    # might cause directories to be created, which would be especially bad
2623b6c3722Schristos    # if $src (and thus $dsttmp) contains '*'.
2633b6c3722Schristos    if test ! -f "$src" && test ! -d "$src"; then
2643b6c3722Schristos      echo "$0: $src does not exist." >&2
2653b6c3722Schristos      exit 1
2663b6c3722Schristos    fi
2673b6c3722Schristos
2683b6c3722Schristos    if test -z "$dst_arg"; then
2693b6c3722Schristos      echo "$0: no destination specified." >&2
2703b6c3722Schristos      exit 1
2713b6c3722Schristos    fi
2723b6c3722Schristos    dst=$dst_arg
2733b6c3722Schristos
2743b6c3722Schristos    # If destination is a directory, append the input filename; won't work
2753b6c3722Schristos    # if double slashes aren't ignored.
2763b6c3722Schristos    if test -d "$dst"; then
2773b6c3722Schristos      if test "$is_target_a_directory" = never; then
2783b6c3722Schristos        echo "$0: $dst_arg: Is a directory" >&2
2793b6c3722Schristos        exit 1
2803b6c3722Schristos      fi
2813b6c3722Schristos      dstdir=$dst
2823b6c3722Schristos      dst=$dstdir/`basename "$src"`
2833b6c3722Schristos      dstdir_status=0
2843b6c3722Schristos    else
2853b6c3722Schristos      dstdir=`dirname "$dst"`
2863b6c3722Schristos      test -d "$dstdir"
2873b6c3722Schristos      dstdir_status=$?
2883b6c3722Schristos    fi
2893b6c3722Schristos  fi
2903b6c3722Schristos
2913b6c3722Schristos  obsolete_mkdir_used=false
2923b6c3722Schristos
2933b6c3722Schristos  if test $dstdir_status != 0; then
2943b6c3722Schristos    case $posix_mkdir in
2953b6c3722Schristos      '')
2963b6c3722Schristos        # Create intermediate dirs using mode 755 as modified by the umask.
2973b6c3722Schristos        # This is like FreeBSD 'install' as of 1997-10-28.
2983b6c3722Schristos        umask=`umask`
2993b6c3722Schristos        case $stripcmd.$umask in
3003b6c3722Schristos          # Optimize common cases.
3013b6c3722Schristos          *[2367][2367]) mkdir_umask=$umask;;
3023b6c3722Schristos          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3033b6c3722Schristos
3043b6c3722Schristos          *[0-7])
3053b6c3722Schristos            mkdir_umask=`expr $umask + 22 \
3063b6c3722Schristos              - $umask % 100 % 40 + $umask % 20 \
3073b6c3722Schristos              - $umask % 10 % 4 + $umask % 2
3083b6c3722Schristos            `;;
3093b6c3722Schristos          *) mkdir_umask=$umask,go-w;;
3103b6c3722Schristos        esac
3113b6c3722Schristos
3123b6c3722Schristos        # With -d, create the new directory with the user-specified mode.
3133b6c3722Schristos        # Otherwise, rely on $mkdir_umask.
3143b6c3722Schristos        if test -n "$dir_arg"; then
3153b6c3722Schristos          mkdir_mode=-m$mode
3163b6c3722Schristos        else
3173b6c3722Schristos          mkdir_mode=
3183b6c3722Schristos        fi
3193b6c3722Schristos
3203b6c3722Schristos        posix_mkdir=false
3213b6c3722Schristos        case $umask in
3223b6c3722Schristos          *[123567][0-7][0-7])
3233b6c3722Schristos            # POSIX mkdir -p sets u+wx bits regardless of umask, which
3243b6c3722Schristos            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3253b6c3722Schristos            ;;
3263b6c3722Schristos          *)
3273b6c3722Schristos            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
328*d0eba39bSchristos            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3293b6c3722Schristos
3303b6c3722Schristos            if (umask $mkdir_umask &&
331*d0eba39bSchristos                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3323b6c3722Schristos            then
3333b6c3722Schristos              if test -z "$dir_arg" || {
3343b6c3722Schristos                   # Check for POSIX incompatibilities with -m.
3353b6c3722Schristos                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3363b6c3722Schristos                   # other-writable bit of parent directory when it shouldn't.
3373b6c3722Schristos                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
338*d0eba39bSchristos                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3393b6c3722Schristos                   case $ls_ld_tmpdir in
3403b6c3722Schristos                     d????-?r-*) different_mode=700;;
3413b6c3722Schristos                     d????-?--*) different_mode=755;;
3423b6c3722Schristos                     *) false;;
3433b6c3722Schristos                   esac &&
344*d0eba39bSchristos                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
345*d0eba39bSchristos                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3463b6c3722Schristos                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3473b6c3722Schristos                   }
3483b6c3722Schristos                 }
3493b6c3722Schristos              then posix_mkdir=:
3503b6c3722Schristos              fi
351*d0eba39bSchristos              rmdir "$tmpdir/d" "$tmpdir"
3523b6c3722Schristos            else
3533b6c3722Schristos              # Remove any dirs left behind by ancient mkdir implementations.
354*d0eba39bSchristos              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3553b6c3722Schristos            fi
3563b6c3722Schristos            trap '' 0;;
3573b6c3722Schristos        esac;;
3583b6c3722Schristos    esac
3593b6c3722Schristos
3603b6c3722Schristos    if
3613b6c3722Schristos      $posix_mkdir && (
3623b6c3722Schristos        umask $mkdir_umask &&
3633b6c3722Schristos        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3643b6c3722Schristos      )
3653b6c3722Schristos    then :
3663b6c3722Schristos    else
3673b6c3722Schristos
3683b6c3722Schristos      # The umask is ridiculous, or mkdir does not conform to POSIX,
3693b6c3722Schristos      # or it failed possibly due to a race condition.  Create the
3703b6c3722Schristos      # directory the slow way, step by step, checking for races as we go.
3713b6c3722Schristos
3723b6c3722Schristos      case $dstdir in
3733b6c3722Schristos        /*) prefix='/';;
3743b6c3722Schristos        [-=\(\)!]*) prefix='./';;
3753b6c3722Schristos        *)  prefix='';;
3763b6c3722Schristos      esac
3773b6c3722Schristos
3783b6c3722Schristos      oIFS=$IFS
3793b6c3722Schristos      IFS=/
3803b6c3722Schristos      set -f
3813b6c3722Schristos      set fnord $dstdir
3823b6c3722Schristos      shift
3833b6c3722Schristos      set +f
3843b6c3722Schristos      IFS=$oIFS
3853b6c3722Schristos
3863b6c3722Schristos      prefixes=
3873b6c3722Schristos
3883b6c3722Schristos      for d
3893b6c3722Schristos      do
3903b6c3722Schristos        test X"$d" = X && continue
3913b6c3722Schristos
3923b6c3722Schristos        prefix=$prefix$d
3933b6c3722Schristos        if test -d "$prefix"; then
3943b6c3722Schristos          prefixes=
3953b6c3722Schristos        else
3963b6c3722Schristos          if $posix_mkdir; then
3973b6c3722Schristos            (umask=$mkdir_umask &&
3983b6c3722Schristos             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
3993b6c3722Schristos            # Don't fail if two instances are running concurrently.
4003b6c3722Schristos            test -d "$prefix" || exit 1
4013b6c3722Schristos          else
4023b6c3722Schristos            case $prefix in
4033b6c3722Schristos              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4043b6c3722Schristos              *) qprefix=$prefix;;
4053b6c3722Schristos            esac
4063b6c3722Schristos            prefixes="$prefixes '$qprefix'"
4073b6c3722Schristos          fi
4083b6c3722Schristos        fi
4093b6c3722Schristos        prefix=$prefix/
4103b6c3722Schristos      done
4113b6c3722Schristos
4123b6c3722Schristos      if test -n "$prefixes"; then
4133b6c3722Schristos        # Don't fail if two instances are running concurrently.
4143b6c3722Schristos        (umask $mkdir_umask &&
4153b6c3722Schristos         eval "\$doit_exec \$mkdirprog $prefixes") ||
4163b6c3722Schristos          test -d "$dstdir" || exit 1
4173b6c3722Schristos        obsolete_mkdir_used=true
4183b6c3722Schristos      fi
4193b6c3722Schristos    fi
4203b6c3722Schristos  fi
4213b6c3722Schristos
4223b6c3722Schristos  if test -n "$dir_arg"; then
4233b6c3722Schristos    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4243b6c3722Schristos    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4253b6c3722Schristos    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4263b6c3722Schristos      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4273b6c3722Schristos  else
4283b6c3722Schristos
4293b6c3722Schristos    # Make a couple of temp file names in the proper directory.
4303b6c3722Schristos    dsttmp=$dstdir/_inst.$$_
4313b6c3722Schristos    rmtmp=$dstdir/_rm.$$_
4323b6c3722Schristos
4333b6c3722Schristos    # Trap to clean up those temp files at exit.
4343b6c3722Schristos    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4353b6c3722Schristos
4363b6c3722Schristos    # Copy the file name to the temp name.
4373b6c3722Schristos    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4383b6c3722Schristos
4393b6c3722Schristos    # and set any options; do chmod last to preserve setuid bits.
4403b6c3722Schristos    #
4413b6c3722Schristos    # If any of these fail, we abort the whole thing.  If we want to
4423b6c3722Schristos    # ignore errors from any of these, just make sure not to ignore
4433b6c3722Schristos    # errors from the above "$doit $cpprog $src $dsttmp" command.
4443b6c3722Schristos    #
4453b6c3722Schristos    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4463b6c3722Schristos    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4473b6c3722Schristos    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4483b6c3722Schristos    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4493b6c3722Schristos
4503b6c3722Schristos    # If -C, don't bother to copy if it wouldn't change the file.
4513b6c3722Schristos    if $copy_on_change &&
4523b6c3722Schristos       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4533b6c3722Schristos       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
4543b6c3722Schristos       set -f &&
4553b6c3722Schristos       set X $old && old=:$2:$4:$5:$6 &&
4563b6c3722Schristos       set X $new && new=:$2:$4:$5:$6 &&
4573b6c3722Schristos       set +f &&
4583b6c3722Schristos       test "$old" = "$new" &&
4593b6c3722Schristos       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4603b6c3722Schristos    then
4613b6c3722Schristos      rm -f "$dsttmp"
4623b6c3722Schristos    else
4633b6c3722Schristos      # Rename the file to the real destination.
4643b6c3722Schristos      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4653b6c3722Schristos
4663b6c3722Schristos      # The rename failed, perhaps because mv can't rename something else
4673b6c3722Schristos      # to itself, or perhaps because mv is so ancient that it does not
4683b6c3722Schristos      # support -f.
4693b6c3722Schristos      {
4703b6c3722Schristos        # Now remove or move aside any old file at destination location.
4713b6c3722Schristos        # We try this two ways since rm can't unlink itself on some
4723b6c3722Schristos        # systems and the destination file might be busy for other
4733b6c3722Schristos        # reasons.  In this case, the final cleanup might fail but the new
4743b6c3722Schristos        # file should still install successfully.
4753b6c3722Schristos        {
4763b6c3722Schristos          test ! -f "$dst" ||
4773b6c3722Schristos          $doit $rmcmd -f "$dst" 2>/dev/null ||
4783b6c3722Schristos          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4793b6c3722Schristos            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4803b6c3722Schristos          } ||
4813b6c3722Schristos          { echo "$0: cannot unlink or rename $dst" >&2
4823b6c3722Schristos            (exit 1); exit 1
4833b6c3722Schristos          }
4843b6c3722Schristos        } &&
4853b6c3722Schristos
4863b6c3722Schristos        # Now rename the file to the real destination.
4873b6c3722Schristos        $doit $mvcmd "$dsttmp" "$dst"
4883b6c3722Schristos      }
4893b6c3722Schristos    fi || exit 1
4903b6c3722Schristos
4913b6c3722Schristos    trap '' 0
4923b6c3722Schristos  fi
4933b6c3722Schristosdone
4943b6c3722Schristos
4953b6c3722Schristos# Local variables:
4963b6c3722Schristos# eval: (add-hook 'write-file-hooks 'time-stamp)
4973b6c3722Schristos# time-stamp-start: "scriptversion="
4983b6c3722Schristos# time-stamp-format: "%:y-%02m-%02d.%02H"
4993b6c3722Schristos# time-stamp-time-zone: "UTC"
5003b6c3722Schristos# time-stamp-end: "; # UTC"
5013b6c3722Schristos# End:
502