xref: /netbsd-src/external/lgpl3/mpc/dist/install-sh (revision 062d2d48d34d3e4901797f81befe658ca0cf6792)
18fa80f29Smrg#!/bin/sh
28fa80f29Smrg# install - install a program, script, or datafile
38fa80f29Smrg
4*062d2d48Smrgscriptversion=2013-12-25.23; # UTC
58fa80f29Smrg
68fa80f29Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
78fa80f29Smrg# later released in X11R6 (xc/config/util/install.sh) with the
88fa80f29Smrg# following copyright and license.
98fa80f29Smrg#
108fa80f29Smrg# Copyright (C) 1994 X Consortium
118fa80f29Smrg#
128fa80f29Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
138fa80f29Smrg# of this software and associated documentation files (the "Software"), to
148fa80f29Smrg# deal in the Software without restriction, including without limitation the
158fa80f29Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
168fa80f29Smrg# sell copies of the Software, and to permit persons to whom the Software is
178fa80f29Smrg# furnished to do so, subject to the following conditions:
188fa80f29Smrg#
198fa80f29Smrg# The above copyright notice and this permission notice shall be included in
208fa80f29Smrg# all copies or substantial portions of the Software.
218fa80f29Smrg#
228fa80f29Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
238fa80f29Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
248fa80f29Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
258fa80f29Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
268fa80f29Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
278fa80f29Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
288fa80f29Smrg#
298fa80f29Smrg# Except as contained in this notice, the name of the X Consortium shall not
308fa80f29Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
318fa80f29Smrg# ings in this Software without prior written authorization from the X Consor-
328fa80f29Smrg# tium.
338fa80f29Smrg#
348fa80f29Smrg#
358fa80f29Smrg# FSF changes to this file are in the public domain.
368fa80f29Smrg#
378fa80f29Smrg# Calling this script install-sh is preferred over install.sh, to prevent
38*062d2d48Smrg# 'make' implicit rules from creating a file called install from it
398fa80f29Smrg# when there is no Makefile.
408fa80f29Smrg#
418fa80f29Smrg# This script is compatible with the BSD install script, but was written
428fa80f29Smrg# from scratch.
438fa80f29Smrg
44*062d2d48Smrgtab='	'
458fa80f29Smrgnl='
468fa80f29Smrg'
47*062d2d48SmrgIFS=" $tab$nl"
488fa80f29Smrg
49*062d2d48Smrg# Set DOITPROG to "echo" to test this script.
508fa80f29Smrg
518fa80f29Smrgdoit=${DOITPROG-}
52*062d2d48Smrgdoit_exec=${doit:-exec}
538fa80f29Smrg
548fa80f29Smrg# Put in absolute file names if you don't have them in your path;
558fa80f29Smrg# or use environment vars.
568fa80f29Smrg
578fa80f29Smrgchgrpprog=${CHGRPPROG-chgrp}
588fa80f29Smrgchmodprog=${CHMODPROG-chmod}
598fa80f29Smrgchownprog=${CHOWNPROG-chown}
608fa80f29Smrgcmpprog=${CMPPROG-cmp}
618fa80f29Smrgcpprog=${CPPROG-cp}
628fa80f29Smrgmkdirprog=${MKDIRPROG-mkdir}
638fa80f29Smrgmvprog=${MVPROG-mv}
648fa80f29Smrgrmprog=${RMPROG-rm}
658fa80f29Smrgstripprog=${STRIPPROG-strip}
668fa80f29Smrg
678fa80f29Smrgposix_mkdir=
688fa80f29Smrg
698fa80f29Smrg# Desired mode of installed file.
708fa80f29Smrgmode=0755
718fa80f29Smrg
728fa80f29Smrgchgrpcmd=
738fa80f29Smrgchmodcmd=$chmodprog
748fa80f29Smrgchowncmd=
758fa80f29Smrgmvcmd=$mvprog
768fa80f29Smrgrmcmd="$rmprog -f"
778fa80f29Smrgstripcmd=
788fa80f29Smrg
798fa80f29Smrgsrc=
808fa80f29Smrgdst=
818fa80f29Smrgdir_arg=
828fa80f29Smrgdst_arg=
838fa80f29Smrg
848fa80f29Smrgcopy_on_change=false
85*062d2d48Smrgis_target_a_directory=possibly
868fa80f29Smrg
878fa80f29Smrgusage="\
888fa80f29SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
898fa80f29Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
908fa80f29Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
918fa80f29Smrg   or: $0 [OPTION]... -d DIRECTORIES...
928fa80f29Smrg
938fa80f29SmrgIn the 1st form, copy SRCFILE to DSTFILE.
948fa80f29SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
958fa80f29SmrgIn the 4th, create DIRECTORIES.
968fa80f29Smrg
978fa80f29SmrgOptions:
988fa80f29Smrg     --help     display this help and exit.
998fa80f29Smrg     --version  display version info and exit.
1008fa80f29Smrg
1018fa80f29Smrg  -c            (ignored)
1028fa80f29Smrg  -C            install only if different (preserve the last data modification time)
1038fa80f29Smrg  -d            create directories instead of installing files.
1048fa80f29Smrg  -g GROUP      $chgrpprog installed files to GROUP.
1058fa80f29Smrg  -m MODE       $chmodprog installed files to MODE.
1068fa80f29Smrg  -o USER       $chownprog installed files to USER.
1078fa80f29Smrg  -s            $stripprog installed files.
1088fa80f29Smrg  -t DIRECTORY  install into DIRECTORY.
1098fa80f29Smrg  -T            report an error if DSTFILE is a directory.
1108fa80f29Smrg
1118fa80f29SmrgEnvironment variables override the default commands:
1128fa80f29Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1138fa80f29Smrg  RMPROG STRIPPROG
1148fa80f29Smrg"
1158fa80f29Smrg
1168fa80f29Smrgwhile test $# -ne 0; do
1178fa80f29Smrg  case $1 in
1188fa80f29Smrg    -c) ;;
1198fa80f29Smrg
1208fa80f29Smrg    -C) copy_on_change=true;;
1218fa80f29Smrg
1228fa80f29Smrg    -d) dir_arg=true;;
1238fa80f29Smrg
1248fa80f29Smrg    -g) chgrpcmd="$chgrpprog $2"
1258fa80f29Smrg        shift;;
1268fa80f29Smrg
1278fa80f29Smrg    --help) echo "$usage"; exit $?;;
1288fa80f29Smrg
1298fa80f29Smrg    -m) mode=$2
1308fa80f29Smrg        case $mode in
131*062d2d48Smrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1328fa80f29Smrg            echo "$0: invalid mode: $mode" >&2
1338fa80f29Smrg            exit 1;;
1348fa80f29Smrg        esac
1358fa80f29Smrg        shift;;
1368fa80f29Smrg
1378fa80f29Smrg    -o) chowncmd="$chownprog $2"
1388fa80f29Smrg        shift;;
1398fa80f29Smrg
1408fa80f29Smrg    -s) stripcmd=$stripprog;;
1418fa80f29Smrg
142*062d2d48Smrg    -t)
143*062d2d48Smrg        is_target_a_directory=always
144*062d2d48Smrg        dst_arg=$2
145*062d2d48Smrg        # Protect names problematic for 'test' and other utilities.
1468fa80f29Smrg        case $dst_arg in
1478fa80f29Smrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1488fa80f29Smrg        esac
1498fa80f29Smrg        shift;;
1508fa80f29Smrg
151*062d2d48Smrg    -T) is_target_a_directory=never;;
1528fa80f29Smrg
1538fa80f29Smrg    --version) echo "$0 $scriptversion"; exit $?;;
1548fa80f29Smrg
1558fa80f29Smrg    --) shift
1568fa80f29Smrg        break;;
1578fa80f29Smrg
1588fa80f29Smrg    -*) echo "$0: invalid option: $1" >&2
1598fa80f29Smrg        exit 1;;
1608fa80f29Smrg
1618fa80f29Smrg    *)  break;;
1628fa80f29Smrg  esac
1638fa80f29Smrg  shift
1648fa80f29Smrgdone
1658fa80f29Smrg
166*062d2d48Smrg# We allow the use of options -d and -T together, by making -d
167*062d2d48Smrg# take the precedence; this is for compatibility with GNU install.
168*062d2d48Smrg
169*062d2d48Smrgif test -n "$dir_arg"; then
170*062d2d48Smrg  if test -n "$dst_arg"; then
171*062d2d48Smrg    echo "$0: target directory not allowed when installing a directory." >&2
172*062d2d48Smrg    exit 1
173*062d2d48Smrg  fi
174*062d2d48Smrgfi
175*062d2d48Smrg
1768fa80f29Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1778fa80f29Smrg  # When -d is used, all remaining arguments are directories to create.
1788fa80f29Smrg  # When -t is used, the destination is already specified.
1798fa80f29Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1808fa80f29Smrg  for arg
1818fa80f29Smrg  do
1828fa80f29Smrg    if test -n "$dst_arg"; then
1838fa80f29Smrg      # $@ is not empty: it contains at least $arg.
1848fa80f29Smrg      set fnord "$@" "$dst_arg"
1858fa80f29Smrg      shift # fnord
1868fa80f29Smrg    fi
1878fa80f29Smrg    shift # arg
1888fa80f29Smrg    dst_arg=$arg
189*062d2d48Smrg    # Protect names problematic for 'test' and other utilities.
1908fa80f29Smrg    case $dst_arg in
1918fa80f29Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1928fa80f29Smrg    esac
1938fa80f29Smrg  done
1948fa80f29Smrgfi
1958fa80f29Smrg
1968fa80f29Smrgif test $# -eq 0; then
1978fa80f29Smrg  if test -z "$dir_arg"; then
1988fa80f29Smrg    echo "$0: no input file specified." >&2
1998fa80f29Smrg    exit 1
2008fa80f29Smrg  fi
201*062d2d48Smrg  # It's OK to call 'install-sh -d' without argument.
2028fa80f29Smrg  # This can happen when creating conditional directories.
2038fa80f29Smrg  exit 0
2048fa80f29Smrgfi
2058fa80f29Smrg
2068fa80f29Smrgif test -z "$dir_arg"; then
207*062d2d48Smrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
208*062d2d48Smrg    if test ! -d "$dst_arg"; then
209*062d2d48Smrg      echo "$0: $dst_arg: Is not a directory." >&2
210*062d2d48Smrg      exit 1
211*062d2d48Smrg    fi
212*062d2d48Smrg  fi
213*062d2d48Smrgfi
214*062d2d48Smrg
215*062d2d48Smrgif test -z "$dir_arg"; then
2168fa80f29Smrg  do_exit='(exit $ret); exit $ret'
2178fa80f29Smrg  trap "ret=129; $do_exit" 1
2188fa80f29Smrg  trap "ret=130; $do_exit" 2
2198fa80f29Smrg  trap "ret=141; $do_exit" 13
2208fa80f29Smrg  trap "ret=143; $do_exit" 15
2218fa80f29Smrg
2228fa80f29Smrg  # Set umask so as not to create temps with too-generous modes.
2238fa80f29Smrg  # However, 'strip' requires both read and write access to temps.
2248fa80f29Smrg  case $mode in
2258fa80f29Smrg    # Optimize common cases.
2268fa80f29Smrg    *644) cp_umask=133;;
2278fa80f29Smrg    *755) cp_umask=22;;
2288fa80f29Smrg
2298fa80f29Smrg    *[0-7])
2308fa80f29Smrg      if test -z "$stripcmd"; then
2318fa80f29Smrg        u_plus_rw=
2328fa80f29Smrg      else
2338fa80f29Smrg        u_plus_rw='% 200'
2348fa80f29Smrg      fi
2358fa80f29Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2368fa80f29Smrg    *)
2378fa80f29Smrg      if test -z "$stripcmd"; then
2388fa80f29Smrg        u_plus_rw=
2398fa80f29Smrg      else
2408fa80f29Smrg        u_plus_rw=,u+rw
2418fa80f29Smrg      fi
2428fa80f29Smrg      cp_umask=$mode$u_plus_rw;;
2438fa80f29Smrg  esac
2448fa80f29Smrgfi
2458fa80f29Smrg
2468fa80f29Smrgfor src
2478fa80f29Smrgdo
248*062d2d48Smrg  # Protect names problematic for 'test' and other utilities.
2498fa80f29Smrg  case $src in
2508fa80f29Smrg    -* | [=\(\)!]) src=./$src;;
2518fa80f29Smrg  esac
2528fa80f29Smrg
2538fa80f29Smrg  if test -n "$dir_arg"; then
2548fa80f29Smrg    dst=$src
2558fa80f29Smrg    dstdir=$dst
2568fa80f29Smrg    test -d "$dstdir"
2578fa80f29Smrg    dstdir_status=$?
2588fa80f29Smrg  else
2598fa80f29Smrg
2608fa80f29Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2618fa80f29Smrg    # might cause directories to be created, which would be especially bad
2628fa80f29Smrg    # if $src (and thus $dsttmp) contains '*'.
2638fa80f29Smrg    if test ! -f "$src" && test ! -d "$src"; then
2648fa80f29Smrg      echo "$0: $src does not exist." >&2
2658fa80f29Smrg      exit 1
2668fa80f29Smrg    fi
2678fa80f29Smrg
2688fa80f29Smrg    if test -z "$dst_arg"; then
2698fa80f29Smrg      echo "$0: no destination specified." >&2
2708fa80f29Smrg      exit 1
2718fa80f29Smrg    fi
2728fa80f29Smrg    dst=$dst_arg
2738fa80f29Smrg
2748fa80f29Smrg    # If destination is a directory, append the input filename; won't work
2758fa80f29Smrg    # if double slashes aren't ignored.
2768fa80f29Smrg    if test -d "$dst"; then
277*062d2d48Smrg      if test "$is_target_a_directory" = never; then
2788fa80f29Smrg        echo "$0: $dst_arg: Is a directory" >&2
2798fa80f29Smrg        exit 1
2808fa80f29Smrg      fi
2818fa80f29Smrg      dstdir=$dst
2828fa80f29Smrg      dst=$dstdir/`basename "$src"`
2838fa80f29Smrg      dstdir_status=0
2848fa80f29Smrg    else
285*062d2d48Smrg      dstdir=`dirname "$dst"`
2868fa80f29Smrg      test -d "$dstdir"
2878fa80f29Smrg      dstdir_status=$?
2888fa80f29Smrg    fi
2898fa80f29Smrg  fi
2908fa80f29Smrg
2918fa80f29Smrg  obsolete_mkdir_used=false
2928fa80f29Smrg
2938fa80f29Smrg  if test $dstdir_status != 0; then
2948fa80f29Smrg    case $posix_mkdir in
2958fa80f29Smrg      '')
2968fa80f29Smrg        # Create intermediate dirs using mode 755 as modified by the umask.
2978fa80f29Smrg        # This is like FreeBSD 'install' as of 1997-10-28.
2988fa80f29Smrg        umask=`umask`
2998fa80f29Smrg        case $stripcmd.$umask in
3008fa80f29Smrg          # Optimize common cases.
3018fa80f29Smrg          *[2367][2367]) mkdir_umask=$umask;;
3028fa80f29Smrg          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3038fa80f29Smrg
3048fa80f29Smrg          *[0-7])
3058fa80f29Smrg            mkdir_umask=`expr $umask + 22 \
3068fa80f29Smrg              - $umask % 100 % 40 + $umask % 20 \
3078fa80f29Smrg              - $umask % 10 % 4 + $umask % 2
3088fa80f29Smrg            `;;
3098fa80f29Smrg          *) mkdir_umask=$umask,go-w;;
3108fa80f29Smrg        esac
3118fa80f29Smrg
3128fa80f29Smrg        # With -d, create the new directory with the user-specified mode.
3138fa80f29Smrg        # Otherwise, rely on $mkdir_umask.
3148fa80f29Smrg        if test -n "$dir_arg"; then
3158fa80f29Smrg          mkdir_mode=-m$mode
3168fa80f29Smrg        else
3178fa80f29Smrg          mkdir_mode=
3188fa80f29Smrg        fi
3198fa80f29Smrg
3208fa80f29Smrg        posix_mkdir=false
3218fa80f29Smrg        case $umask in
3228fa80f29Smrg          *[123567][0-7][0-7])
3238fa80f29Smrg            # POSIX mkdir -p sets u+wx bits regardless of umask, which
3248fa80f29Smrg            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3258fa80f29Smrg            ;;
3268fa80f29Smrg          *)
3278fa80f29Smrg            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3288fa80f29Smrg            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3298fa80f29Smrg
3308fa80f29Smrg            if (umask $mkdir_umask &&
3318fa80f29Smrg                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3328fa80f29Smrg            then
3338fa80f29Smrg              if test -z "$dir_arg" || {
3348fa80f29Smrg                   # Check for POSIX incompatibilities with -m.
3358fa80f29Smrg                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
336*062d2d48Smrg                   # other-writable bit of parent directory when it shouldn't.
3378fa80f29Smrg                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3388fa80f29Smrg                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3398fa80f29Smrg                   case $ls_ld_tmpdir in
3408fa80f29Smrg                     d????-?r-*) different_mode=700;;
3418fa80f29Smrg                     d????-?--*) different_mode=755;;
3428fa80f29Smrg                     *) false;;
3438fa80f29Smrg                   esac &&
3448fa80f29Smrg                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3458fa80f29Smrg                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3468fa80f29Smrg                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3478fa80f29Smrg                   }
3488fa80f29Smrg                 }
3498fa80f29Smrg              then posix_mkdir=:
3508fa80f29Smrg              fi
3518fa80f29Smrg              rmdir "$tmpdir/d" "$tmpdir"
3528fa80f29Smrg            else
3538fa80f29Smrg              # Remove any dirs left behind by ancient mkdir implementations.
3548fa80f29Smrg              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3558fa80f29Smrg            fi
3568fa80f29Smrg            trap '' 0;;
3578fa80f29Smrg        esac;;
3588fa80f29Smrg    esac
3598fa80f29Smrg
3608fa80f29Smrg    if
3618fa80f29Smrg      $posix_mkdir && (
3628fa80f29Smrg        umask $mkdir_umask &&
3638fa80f29Smrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3648fa80f29Smrg      )
3658fa80f29Smrg    then :
3668fa80f29Smrg    else
3678fa80f29Smrg
3688fa80f29Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3698fa80f29Smrg      # or it failed possibly due to a race condition.  Create the
3708fa80f29Smrg      # directory the slow way, step by step, checking for races as we go.
3718fa80f29Smrg
3728fa80f29Smrg      case $dstdir in
3738fa80f29Smrg        /*) prefix='/';;
3748fa80f29Smrg        [-=\(\)!]*) prefix='./';;
3758fa80f29Smrg        *)  prefix='';;
3768fa80f29Smrg      esac
3778fa80f29Smrg
3788fa80f29Smrg      oIFS=$IFS
3798fa80f29Smrg      IFS=/
380*062d2d48Smrg      set -f
3818fa80f29Smrg      set fnord $dstdir
3828fa80f29Smrg      shift
383*062d2d48Smrg      set +f
3848fa80f29Smrg      IFS=$oIFS
3858fa80f29Smrg
3868fa80f29Smrg      prefixes=
3878fa80f29Smrg
3888fa80f29Smrg      for d
3898fa80f29Smrg      do
3908fa80f29Smrg        test X"$d" = X && continue
3918fa80f29Smrg
3928fa80f29Smrg        prefix=$prefix$d
3938fa80f29Smrg        if test -d "$prefix"; then
3948fa80f29Smrg          prefixes=
3958fa80f29Smrg        else
3968fa80f29Smrg          if $posix_mkdir; then
3978fa80f29Smrg            (umask=$mkdir_umask &&
3988fa80f29Smrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
3998fa80f29Smrg            # Don't fail if two instances are running concurrently.
4008fa80f29Smrg            test -d "$prefix" || exit 1
4018fa80f29Smrg          else
4028fa80f29Smrg            case $prefix in
4038fa80f29Smrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4048fa80f29Smrg              *) qprefix=$prefix;;
4058fa80f29Smrg            esac
4068fa80f29Smrg            prefixes="$prefixes '$qprefix'"
4078fa80f29Smrg          fi
4088fa80f29Smrg        fi
4098fa80f29Smrg        prefix=$prefix/
4108fa80f29Smrg      done
4118fa80f29Smrg
4128fa80f29Smrg      if test -n "$prefixes"; then
4138fa80f29Smrg        # Don't fail if two instances are running concurrently.
4148fa80f29Smrg        (umask $mkdir_umask &&
4158fa80f29Smrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
4168fa80f29Smrg          test -d "$dstdir" || exit 1
4178fa80f29Smrg        obsolete_mkdir_used=true
4188fa80f29Smrg      fi
4198fa80f29Smrg    fi
4208fa80f29Smrg  fi
4218fa80f29Smrg
4228fa80f29Smrg  if test -n "$dir_arg"; then
4238fa80f29Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4248fa80f29Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4258fa80f29Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4268fa80f29Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4278fa80f29Smrg  else
4288fa80f29Smrg
4298fa80f29Smrg    # Make a couple of temp file names in the proper directory.
4308fa80f29Smrg    dsttmp=$dstdir/_inst.$$_
4318fa80f29Smrg    rmtmp=$dstdir/_rm.$$_
4328fa80f29Smrg
4338fa80f29Smrg    # Trap to clean up those temp files at exit.
4348fa80f29Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4358fa80f29Smrg
4368fa80f29Smrg    # Copy the file name to the temp name.
4378fa80f29Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4388fa80f29Smrg
4398fa80f29Smrg    # and set any options; do chmod last to preserve setuid bits.
4408fa80f29Smrg    #
4418fa80f29Smrg    # If any of these fail, we abort the whole thing.  If we want to
4428fa80f29Smrg    # ignore errors from any of these, just make sure not to ignore
4438fa80f29Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4448fa80f29Smrg    #
4458fa80f29Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4468fa80f29Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4478fa80f29Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4488fa80f29Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4498fa80f29Smrg
4508fa80f29Smrg    # If -C, don't bother to copy if it wouldn't change the file.
4518fa80f29Smrg    if $copy_on_change &&
4528fa80f29Smrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4538fa80f29Smrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
454*062d2d48Smrg       set -f &&
4558fa80f29Smrg       set X $old && old=:$2:$4:$5:$6 &&
4568fa80f29Smrg       set X $new && new=:$2:$4:$5:$6 &&
457*062d2d48Smrg       set +f &&
4588fa80f29Smrg       test "$old" = "$new" &&
4598fa80f29Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4608fa80f29Smrg    then
4618fa80f29Smrg      rm -f "$dsttmp"
4628fa80f29Smrg    else
4638fa80f29Smrg      # Rename the file to the real destination.
4648fa80f29Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4658fa80f29Smrg
4668fa80f29Smrg      # The rename failed, perhaps because mv can't rename something else
4678fa80f29Smrg      # to itself, or perhaps because mv is so ancient that it does not
4688fa80f29Smrg      # support -f.
4698fa80f29Smrg      {
4708fa80f29Smrg        # Now remove or move aside any old file at destination location.
4718fa80f29Smrg        # We try this two ways since rm can't unlink itself on some
4728fa80f29Smrg        # systems and the destination file might be busy for other
4738fa80f29Smrg        # reasons.  In this case, the final cleanup might fail but the new
4748fa80f29Smrg        # file should still install successfully.
4758fa80f29Smrg        {
4768fa80f29Smrg          test ! -f "$dst" ||
4778fa80f29Smrg          $doit $rmcmd -f "$dst" 2>/dev/null ||
4788fa80f29Smrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4798fa80f29Smrg            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4808fa80f29Smrg          } ||
4818fa80f29Smrg          { echo "$0: cannot unlink or rename $dst" >&2
4828fa80f29Smrg            (exit 1); exit 1
4838fa80f29Smrg          }
4848fa80f29Smrg        } &&
4858fa80f29Smrg
4868fa80f29Smrg        # Now rename the file to the real destination.
4878fa80f29Smrg        $doit $mvcmd "$dsttmp" "$dst"
4888fa80f29Smrg      }
4898fa80f29Smrg    fi || exit 1
4908fa80f29Smrg
4918fa80f29Smrg    trap '' 0
4928fa80f29Smrg  fi
4938fa80f29Smrgdone
4948fa80f29Smrg
4958fa80f29Smrg# Local variables:
4968fa80f29Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
4978fa80f29Smrg# time-stamp-start: "scriptversion="
4988fa80f29Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
4998fa80f29Smrg# time-stamp-time-zone: "UTC"
5008fa80f29Smrg# time-stamp-end: "; # UTC"
5018fa80f29Smrg# End:
502