xref: /netbsd-src/external/bsd/flex/dist/build-aux/install-sh (revision 56bd85463476f90bb489799c99292bb30d6771c0)
130da1778Schristos#!/bin/sh
230da1778Schristos# install - install a program, script, or datafile
330da1778Schristos
4*56bd8546Schristosscriptversion=2014-09-12.12; # UTC
530da1778Schristos
630da1778Schristos# This originates from X11R5 (mit/util/scripts/install.sh), which was
730da1778Schristos# later released in X11R6 (xc/config/util/install.sh) with the
830da1778Schristos# following copyright and license.
930da1778Schristos#
1030da1778Schristos# Copyright (C) 1994 X Consortium
1130da1778Schristos#
1230da1778Schristos# Permission is hereby granted, free of charge, to any person obtaining a copy
1330da1778Schristos# of this software and associated documentation files (the "Software"), to
1430da1778Schristos# deal in the Software without restriction, including without limitation the
1530da1778Schristos# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1630da1778Schristos# sell copies of the Software, and to permit persons to whom the Software is
1730da1778Schristos# furnished to do so, subject to the following conditions:
1830da1778Schristos#
1930da1778Schristos# The above copyright notice and this permission notice shall be included in
2030da1778Schristos# all copies or substantial portions of the Software.
2130da1778Schristos#
2230da1778Schristos# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2330da1778Schristos# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2430da1778Schristos# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2530da1778Schristos# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2630da1778Schristos# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2730da1778Schristos# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2830da1778Schristos#
2930da1778Schristos# Except as contained in this notice, the name of the X Consortium shall not
3030da1778Schristos# be used in advertising or otherwise to promote the sale, use or other deal-
3130da1778Schristos# ings in this Software without prior written authorization from the X Consor-
3230da1778Schristos# tium.
3330da1778Schristos#
3430da1778Schristos#
3530da1778Schristos# FSF changes to this file are in the public domain.
3630da1778Schristos#
3730da1778Schristos# Calling this script install-sh is preferred over install.sh, to prevent
3830da1778Schristos# 'make' implicit rules from creating a file called install from it
3930da1778Schristos# when there is no Makefile.
4030da1778Schristos#
4130da1778Schristos# This script is compatible with the BSD install script, but was written
4230da1778Schristos# from scratch.
4330da1778Schristos
4430da1778Schristostab='	'
4530da1778Schristosnl='
4630da1778Schristos'
4730da1778SchristosIFS=" $tab$nl"
4830da1778Schristos
4930da1778Schristos# Set DOITPROG to "echo" to test this script.
5030da1778Schristos
5130da1778Schristosdoit=${DOITPROG-}
5230da1778Schristosdoit_exec=${doit:-exec}
5330da1778Schristos
5430da1778Schristos# Put in absolute file names if you don't have them in your path;
5530da1778Schristos# or use environment vars.
5630da1778Schristos
5730da1778Schristoschgrpprog=${CHGRPPROG-chgrp}
5830da1778Schristoschmodprog=${CHMODPROG-chmod}
5930da1778Schristoschownprog=${CHOWNPROG-chown}
6030da1778Schristoscmpprog=${CMPPROG-cmp}
6130da1778Schristoscpprog=${CPPROG-cp}
6230da1778Schristosmkdirprog=${MKDIRPROG-mkdir}
6330da1778Schristosmvprog=${MVPROG-mv}
6430da1778Schristosrmprog=${RMPROG-rm}
6530da1778Schristosstripprog=${STRIPPROG-strip}
6630da1778Schristos
6730da1778Schristosposix_mkdir=
6830da1778Schristos
6930da1778Schristos# Desired mode of installed file.
7030da1778Schristosmode=0755
7130da1778Schristos
7230da1778Schristoschgrpcmd=
7330da1778Schristoschmodcmd=$chmodprog
7430da1778Schristoschowncmd=
7530da1778Schristosmvcmd=$mvprog
7630da1778Schristosrmcmd="$rmprog -f"
7730da1778Schristosstripcmd=
7830da1778Schristos
7930da1778Schristossrc=
8030da1778Schristosdst=
8130da1778Schristosdir_arg=
8230da1778Schristosdst_arg=
8330da1778Schristos
8430da1778Schristoscopy_on_change=false
8530da1778Schristosis_target_a_directory=possibly
8630da1778Schristos
8730da1778Schristosusage="\
8830da1778SchristosUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
8930da1778Schristos   or: $0 [OPTION]... SRCFILES... DIRECTORY
9030da1778Schristos   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
9130da1778Schristos   or: $0 [OPTION]... -d DIRECTORIES...
9230da1778Schristos
9330da1778SchristosIn the 1st form, copy SRCFILE to DSTFILE.
9430da1778SchristosIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
9530da1778SchristosIn the 4th, create DIRECTORIES.
9630da1778Schristos
9730da1778SchristosOptions:
9830da1778Schristos     --help     display this help and exit.
9930da1778Schristos     --version  display version info and exit.
10030da1778Schristos
10130da1778Schristos  -c            (ignored)
10230da1778Schristos  -C            install only if different (preserve the last data modification time)
10330da1778Schristos  -d            create directories instead of installing files.
10430da1778Schristos  -g GROUP      $chgrpprog installed files to GROUP.
10530da1778Schristos  -m MODE       $chmodprog installed files to MODE.
10630da1778Schristos  -o USER       $chownprog installed files to USER.
10730da1778Schristos  -s            $stripprog installed files.
10830da1778Schristos  -t DIRECTORY  install into DIRECTORY.
10930da1778Schristos  -T            report an error if DSTFILE is a directory.
11030da1778Schristos
11130da1778SchristosEnvironment variables override the default commands:
11230da1778Schristos  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
11330da1778Schristos  RMPROG STRIPPROG
11430da1778Schristos"
11530da1778Schristos
11630da1778Schristoswhile test $# -ne 0; do
11730da1778Schristos  case $1 in
11830da1778Schristos    -c) ;;
11930da1778Schristos
12030da1778Schristos    -C) copy_on_change=true;;
12130da1778Schristos
12230da1778Schristos    -d) dir_arg=true;;
12330da1778Schristos
12430da1778Schristos    -g) chgrpcmd="$chgrpprog $2"
12530da1778Schristos        shift;;
12630da1778Schristos
12730da1778Schristos    --help) echo "$usage"; exit $?;;
12830da1778Schristos
12930da1778Schristos    -m) mode=$2
13030da1778Schristos        case $mode in
13130da1778Schristos          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
13230da1778Schristos            echo "$0: invalid mode: $mode" >&2
13330da1778Schristos            exit 1;;
13430da1778Schristos        esac
13530da1778Schristos        shift;;
13630da1778Schristos
13730da1778Schristos    -o) chowncmd="$chownprog $2"
13830da1778Schristos        shift;;
13930da1778Schristos
14030da1778Schristos    -s) stripcmd=$stripprog;;
14130da1778Schristos
14230da1778Schristos    -t)
14330da1778Schristos        is_target_a_directory=always
14430da1778Schristos        dst_arg=$2
14530da1778Schristos        # Protect names problematic for 'test' and other utilities.
14630da1778Schristos        case $dst_arg in
14730da1778Schristos          -* | [=\(\)!]) dst_arg=./$dst_arg;;
14830da1778Schristos        esac
14930da1778Schristos        shift;;
15030da1778Schristos
15130da1778Schristos    -T) is_target_a_directory=never;;
15230da1778Schristos
15330da1778Schristos    --version) echo "$0 $scriptversion"; exit $?;;
15430da1778Schristos
15530da1778Schristos    --) shift
15630da1778Schristos        break;;
15730da1778Schristos
15830da1778Schristos    -*) echo "$0: invalid option: $1" >&2
15930da1778Schristos        exit 1;;
16030da1778Schristos
16130da1778Schristos    *)  break;;
16230da1778Schristos  esac
16330da1778Schristos  shift
16430da1778Schristosdone
16530da1778Schristos
16630da1778Schristos# We allow the use of options -d and -T together, by making -d
16730da1778Schristos# take the precedence; this is for compatibility with GNU install.
16830da1778Schristos
16930da1778Schristosif test -n "$dir_arg"; then
17030da1778Schristos  if test -n "$dst_arg"; then
17130da1778Schristos    echo "$0: target directory not allowed when installing a directory." >&2
17230da1778Schristos    exit 1
17330da1778Schristos  fi
17430da1778Schristosfi
17530da1778Schristos
17630da1778Schristosif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
17730da1778Schristos  # When -d is used, all remaining arguments are directories to create.
17830da1778Schristos  # When -t is used, the destination is already specified.
17930da1778Schristos  # Otherwise, the last argument is the destination.  Remove it from $@.
18030da1778Schristos  for arg
18130da1778Schristos  do
18230da1778Schristos    if test -n "$dst_arg"; then
18330da1778Schristos      # $@ is not empty: it contains at least $arg.
18430da1778Schristos      set fnord "$@" "$dst_arg"
18530da1778Schristos      shift # fnord
18630da1778Schristos    fi
18730da1778Schristos    shift # arg
18830da1778Schristos    dst_arg=$arg
18930da1778Schristos    # Protect names problematic for 'test' and other utilities.
19030da1778Schristos    case $dst_arg in
19130da1778Schristos      -* | [=\(\)!]) dst_arg=./$dst_arg;;
19230da1778Schristos    esac
19330da1778Schristos  done
19430da1778Schristosfi
19530da1778Schristos
19630da1778Schristosif test $# -eq 0; then
19730da1778Schristos  if test -z "$dir_arg"; then
19830da1778Schristos    echo "$0: no input file specified." >&2
19930da1778Schristos    exit 1
20030da1778Schristos  fi
20130da1778Schristos  # It's OK to call 'install-sh -d' without argument.
20230da1778Schristos  # This can happen when creating conditional directories.
20330da1778Schristos  exit 0
20430da1778Schristosfi
20530da1778Schristos
20630da1778Schristosif test -z "$dir_arg"; then
20730da1778Schristos  if test $# -gt 1 || test "$is_target_a_directory" = always; then
20830da1778Schristos    if test ! -d "$dst_arg"; then
20930da1778Schristos      echo "$0: $dst_arg: Is not a directory." >&2
21030da1778Schristos      exit 1
21130da1778Schristos    fi
21230da1778Schristos  fi
21330da1778Schristosfi
21430da1778Schristos
21530da1778Schristosif test -z "$dir_arg"; then
21630da1778Schristos  do_exit='(exit $ret); exit $ret'
21730da1778Schristos  trap "ret=129; $do_exit" 1
21830da1778Schristos  trap "ret=130; $do_exit" 2
21930da1778Schristos  trap "ret=141; $do_exit" 13
22030da1778Schristos  trap "ret=143; $do_exit" 15
22130da1778Schristos
22230da1778Schristos  # Set umask so as not to create temps with too-generous modes.
22330da1778Schristos  # However, 'strip' requires both read and write access to temps.
22430da1778Schristos  case $mode in
22530da1778Schristos    # Optimize common cases.
22630da1778Schristos    *644) cp_umask=133;;
22730da1778Schristos    *755) cp_umask=22;;
22830da1778Schristos
22930da1778Schristos    *[0-7])
23030da1778Schristos      if test -z "$stripcmd"; then
23130da1778Schristos        u_plus_rw=
23230da1778Schristos      else
23330da1778Schristos        u_plus_rw='% 200'
23430da1778Schristos      fi
23530da1778Schristos      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
23630da1778Schristos    *)
23730da1778Schristos      if test -z "$stripcmd"; then
23830da1778Schristos        u_plus_rw=
23930da1778Schristos      else
24030da1778Schristos        u_plus_rw=,u+rw
24130da1778Schristos      fi
24230da1778Schristos      cp_umask=$mode$u_plus_rw;;
24330da1778Schristos  esac
24430da1778Schristosfi
24530da1778Schristos
24630da1778Schristosfor src
24730da1778Schristosdo
24830da1778Schristos  # Protect names problematic for 'test' and other utilities.
24930da1778Schristos  case $src in
25030da1778Schristos    -* | [=\(\)!]) src=./$src;;
25130da1778Schristos  esac
25230da1778Schristos
25330da1778Schristos  if test -n "$dir_arg"; then
25430da1778Schristos    dst=$src
25530da1778Schristos    dstdir=$dst
25630da1778Schristos    test -d "$dstdir"
25730da1778Schristos    dstdir_status=$?
25830da1778Schristos  else
25930da1778Schristos
26030da1778Schristos    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
26130da1778Schristos    # might cause directories to be created, which would be especially bad
26230da1778Schristos    # if $src (and thus $dsttmp) contains '*'.
26330da1778Schristos    if test ! -f "$src" && test ! -d "$src"; then
26430da1778Schristos      echo "$0: $src does not exist." >&2
26530da1778Schristos      exit 1
26630da1778Schristos    fi
26730da1778Schristos
26830da1778Schristos    if test -z "$dst_arg"; then
26930da1778Schristos      echo "$0: no destination specified." >&2
27030da1778Schristos      exit 1
27130da1778Schristos    fi
27230da1778Schristos    dst=$dst_arg
27330da1778Schristos
27430da1778Schristos    # If destination is a directory, append the input filename; won't work
27530da1778Schristos    # if double slashes aren't ignored.
27630da1778Schristos    if test -d "$dst"; then
27730da1778Schristos      if test "$is_target_a_directory" = never; then
27830da1778Schristos        echo "$0: $dst_arg: Is a directory" >&2
27930da1778Schristos        exit 1
28030da1778Schristos      fi
28130da1778Schristos      dstdir=$dst
28230da1778Schristos      dst=$dstdir/`basename "$src"`
28330da1778Schristos      dstdir_status=0
28430da1778Schristos    else
28530da1778Schristos      dstdir=`dirname "$dst"`
28630da1778Schristos      test -d "$dstdir"
28730da1778Schristos      dstdir_status=$?
28830da1778Schristos    fi
28930da1778Schristos  fi
29030da1778Schristos
29130da1778Schristos  obsolete_mkdir_used=false
29230da1778Schristos
29330da1778Schristos  if test $dstdir_status != 0; then
29430da1778Schristos    case $posix_mkdir in
29530da1778Schristos      '')
29630da1778Schristos        # Create intermediate dirs using mode 755 as modified by the umask.
29730da1778Schristos        # This is like FreeBSD 'install' as of 1997-10-28.
29830da1778Schristos        umask=`umask`
29930da1778Schristos        case $stripcmd.$umask in
30030da1778Schristos          # Optimize common cases.
30130da1778Schristos          *[2367][2367]) mkdir_umask=$umask;;
30230da1778Schristos          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
30330da1778Schristos
30430da1778Schristos          *[0-7])
30530da1778Schristos            mkdir_umask=`expr $umask + 22 \
30630da1778Schristos              - $umask % 100 % 40 + $umask % 20 \
30730da1778Schristos              - $umask % 10 % 4 + $umask % 2
30830da1778Schristos            `;;
30930da1778Schristos          *) mkdir_umask=$umask,go-w;;
31030da1778Schristos        esac
31130da1778Schristos
31230da1778Schristos        # With -d, create the new directory with the user-specified mode.
31330da1778Schristos        # Otherwise, rely on $mkdir_umask.
31430da1778Schristos        if test -n "$dir_arg"; then
31530da1778Schristos          mkdir_mode=-m$mode
31630da1778Schristos        else
31730da1778Schristos          mkdir_mode=
31830da1778Schristos        fi
31930da1778Schristos
32030da1778Schristos        posix_mkdir=false
32130da1778Schristos        case $umask in
32230da1778Schristos          *[123567][0-7][0-7])
32330da1778Schristos            # POSIX mkdir -p sets u+wx bits regardless of umask, which
32430da1778Schristos            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
32530da1778Schristos            ;;
32630da1778Schristos          *)
327*56bd8546Schristos            # $RANDOM is not portable (e.g. dash);  use it when possible to
328*56bd8546Schristos            # lower collision chance
32930da1778Schristos            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
330*56bd8546Schristos            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
33130da1778Schristos
332*56bd8546Schristos            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
333*56bd8546Schristos            # create the $tmpdir first (and fail if unsuccessful) to make sure
334*56bd8546Schristos            # that nobody tries to guess the $tmpdir name.
33530da1778Schristos            if (umask $mkdir_umask &&
336*56bd8546Schristos                $mkdirprog $mkdir_mode "$tmpdir" &&
337*56bd8546Schristos                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
33830da1778Schristos            then
33930da1778Schristos              if test -z "$dir_arg" || {
34030da1778Schristos                   # Check for POSIX incompatibilities with -m.
34130da1778Schristos                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
34230da1778Schristos                   # other-writable bit of parent directory when it shouldn't.
34330da1778Schristos                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
344*56bd8546Schristos                   test_tmpdir="$tmpdir/a"
345*56bd8546Schristos                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
34630da1778Schristos                   case $ls_ld_tmpdir in
34730da1778Schristos                     d????-?r-*) different_mode=700;;
34830da1778Schristos                     d????-?--*) different_mode=755;;
34930da1778Schristos                     *) false;;
35030da1778Schristos                   esac &&
351*56bd8546Schristos                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
352*56bd8546Schristos                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
35330da1778Schristos                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
35430da1778Schristos                   }
35530da1778Schristos                 }
35630da1778Schristos              then posix_mkdir=:
35730da1778Schristos              fi
358*56bd8546Schristos              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
35930da1778Schristos            else
36030da1778Schristos              # Remove any dirs left behind by ancient mkdir implementations.
361*56bd8546Schristos              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
36230da1778Schristos            fi
36330da1778Schristos            trap '' 0;;
36430da1778Schristos        esac;;
36530da1778Schristos    esac
36630da1778Schristos
36730da1778Schristos    if
36830da1778Schristos      $posix_mkdir && (
36930da1778Schristos        umask $mkdir_umask &&
37030da1778Schristos        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
37130da1778Schristos      )
37230da1778Schristos    then :
37330da1778Schristos    else
37430da1778Schristos
37530da1778Schristos      # The umask is ridiculous, or mkdir does not conform to POSIX,
37630da1778Schristos      # or it failed possibly due to a race condition.  Create the
37730da1778Schristos      # directory the slow way, step by step, checking for races as we go.
37830da1778Schristos
37930da1778Schristos      case $dstdir in
38030da1778Schristos        /*) prefix='/';;
38130da1778Schristos        [-=\(\)!]*) prefix='./';;
38230da1778Schristos        *)  prefix='';;
38330da1778Schristos      esac
38430da1778Schristos
38530da1778Schristos      oIFS=$IFS
38630da1778Schristos      IFS=/
38730da1778Schristos      set -f
38830da1778Schristos      set fnord $dstdir
38930da1778Schristos      shift
39030da1778Schristos      set +f
39130da1778Schristos      IFS=$oIFS
39230da1778Schristos
39330da1778Schristos      prefixes=
39430da1778Schristos
39530da1778Schristos      for d
39630da1778Schristos      do
39730da1778Schristos        test X"$d" = X && continue
39830da1778Schristos
39930da1778Schristos        prefix=$prefix$d
40030da1778Schristos        if test -d "$prefix"; then
40130da1778Schristos          prefixes=
40230da1778Schristos        else
40330da1778Schristos          if $posix_mkdir; then
40430da1778Schristos            (umask=$mkdir_umask &&
40530da1778Schristos             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
40630da1778Schristos            # Don't fail if two instances are running concurrently.
40730da1778Schristos            test -d "$prefix" || exit 1
40830da1778Schristos          else
40930da1778Schristos            case $prefix in
41030da1778Schristos              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
41130da1778Schristos              *) qprefix=$prefix;;
41230da1778Schristos            esac
41330da1778Schristos            prefixes="$prefixes '$qprefix'"
41430da1778Schristos          fi
41530da1778Schristos        fi
41630da1778Schristos        prefix=$prefix/
41730da1778Schristos      done
41830da1778Schristos
41930da1778Schristos      if test -n "$prefixes"; then
42030da1778Schristos        # Don't fail if two instances are running concurrently.
42130da1778Schristos        (umask $mkdir_umask &&
42230da1778Schristos         eval "\$doit_exec \$mkdirprog $prefixes") ||
42330da1778Schristos          test -d "$dstdir" || exit 1
42430da1778Schristos        obsolete_mkdir_used=true
42530da1778Schristos      fi
42630da1778Schristos    fi
42730da1778Schristos  fi
42830da1778Schristos
42930da1778Schristos  if test -n "$dir_arg"; then
43030da1778Schristos    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
43130da1778Schristos    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
43230da1778Schristos    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
43330da1778Schristos      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
43430da1778Schristos  else
43530da1778Schristos
43630da1778Schristos    # Make a couple of temp file names in the proper directory.
43730da1778Schristos    dsttmp=$dstdir/_inst.$$_
43830da1778Schristos    rmtmp=$dstdir/_rm.$$_
43930da1778Schristos
44030da1778Schristos    # Trap to clean up those temp files at exit.
44130da1778Schristos    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
44230da1778Schristos
44330da1778Schristos    # Copy the file name to the temp name.
44430da1778Schristos    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
44530da1778Schristos
44630da1778Schristos    # and set any options; do chmod last to preserve setuid bits.
44730da1778Schristos    #
44830da1778Schristos    # If any of these fail, we abort the whole thing.  If we want to
44930da1778Schristos    # ignore errors from any of these, just make sure not to ignore
45030da1778Schristos    # errors from the above "$doit $cpprog $src $dsttmp" command.
45130da1778Schristos    #
45230da1778Schristos    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
45330da1778Schristos    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
45430da1778Schristos    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
45530da1778Schristos    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
45630da1778Schristos
45730da1778Schristos    # If -C, don't bother to copy if it wouldn't change the file.
45830da1778Schristos    if $copy_on_change &&
45930da1778Schristos       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
46030da1778Schristos       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
46130da1778Schristos       set -f &&
46230da1778Schristos       set X $old && old=:$2:$4:$5:$6 &&
46330da1778Schristos       set X $new && new=:$2:$4:$5:$6 &&
46430da1778Schristos       set +f &&
46530da1778Schristos       test "$old" = "$new" &&
46630da1778Schristos       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
46730da1778Schristos    then
46830da1778Schristos      rm -f "$dsttmp"
46930da1778Schristos    else
47030da1778Schristos      # Rename the file to the real destination.
47130da1778Schristos      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
47230da1778Schristos
47330da1778Schristos      # The rename failed, perhaps because mv can't rename something else
47430da1778Schristos      # to itself, or perhaps because mv is so ancient that it does not
47530da1778Schristos      # support -f.
47630da1778Schristos      {
47730da1778Schristos        # Now remove or move aside any old file at destination location.
47830da1778Schristos        # We try this two ways since rm can't unlink itself on some
47930da1778Schristos        # systems and the destination file might be busy for other
48030da1778Schristos        # reasons.  In this case, the final cleanup might fail but the new
48130da1778Schristos        # file should still install successfully.
48230da1778Schristos        {
48330da1778Schristos          test ! -f "$dst" ||
48430da1778Schristos          $doit $rmcmd -f "$dst" 2>/dev/null ||
48530da1778Schristos          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
48630da1778Schristos            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
48730da1778Schristos          } ||
48830da1778Schristos          { echo "$0: cannot unlink or rename $dst" >&2
48930da1778Schristos            (exit 1); exit 1
49030da1778Schristos          }
49130da1778Schristos        } &&
49230da1778Schristos
49330da1778Schristos        # Now rename the file to the real destination.
49430da1778Schristos        $doit $mvcmd "$dsttmp" "$dst"
49530da1778Schristos      }
49630da1778Schristos    fi || exit 1
49730da1778Schristos
49830da1778Schristos    trap '' 0
49930da1778Schristos  fi
50030da1778Schristosdone
50130da1778Schristos
50230da1778Schristos# Local variables:
50330da1778Schristos# eval: (add-hook 'write-file-hooks 'time-stamp)
50430da1778Schristos# time-stamp-start: "scriptversion="
50530da1778Schristos# time-stamp-format: "%:y-%02m-%02d.%02H"
50630da1778Schristos# time-stamp-time-zone: "UTC"
50730da1778Schristos# time-stamp-end: "; # UTC"
50830da1778Schristos# End:
509