1b8f75c19Smrg#!/bin/sh
2b8f75c19Smrg# install - install a program, script, or datafile
37e4fd55aSmrg
48832ea4aSmrgscriptversion=2013-12-25.23; # UTC
57e4fd55aSmrg
6b8f75c19Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7b8f75c19Smrg# later released in X11R6 (xc/config/util/install.sh) with the
8b8f75c19Smrg# following copyright and license.
9b8f75c19Smrg#
10b8f75c19Smrg# Copyright (C) 1994 X Consortium
11b8f75c19Smrg#
12b8f75c19Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13b8f75c19Smrg# of this software and associated documentation files (the "Software"), to
14b8f75c19Smrg# deal in the Software without restriction, including without limitation the
15b8f75c19Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16b8f75c19Smrg# sell copies of the Software, and to permit persons to whom the Software is
17b8f75c19Smrg# furnished to do so, subject to the following conditions:
18b8f75c19Smrg#
19b8f75c19Smrg# The above copyright notice and this permission notice shall be included in
20b8f75c19Smrg# all copies or substantial portions of the Software.
21b8f75c19Smrg#
22b8f75c19Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23b8f75c19Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24b8f75c19Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25b8f75c19Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26b8f75c19Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27b8f75c19Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28b8f75c19Smrg#
29b8f75c19Smrg# Except as contained in this notice, the name of the X Consortium shall not
30b8f75c19Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
31b8f75c19Smrg# ings in this Software without prior written authorization from the X Consor-
32b8f75c19Smrg# tium.
33b8f75c19Smrg#
34b8f75c19Smrg#
35b8f75c19Smrg# FSF changes to this file are in the public domain.
36b8f75c19Smrg#
37b8f75c19Smrg# Calling this script install-sh is preferred over install.sh, to prevent
388e4923e5Smrg# 'make' implicit rules from creating a file called install from it
39b8f75c19Smrg# when there is no Makefile.
40b8f75c19Smrg#
41b8f75c19Smrg# This script is compatible with the BSD install script, but was written
427e4fd55aSmrg# from scratch.
43b8f75c19Smrg
448832ea4aSmrgtab='	'
457e4fd55aSmrgnl='
467e4fd55aSmrg'
478832ea4aSmrgIFS=" $tab$nl"
48b8f75c19Smrg
498832ea4aSmrg# Set DOITPROG to "echo" to test this script.
50b8f75c19Smrg
517e4fd55aSmrgdoit=${DOITPROG-}
528832ea4aSmrgdoit_exec=${doit:-exec}
53b8f75c19Smrg
547e4fd55aSmrg# Put in absolute file names if you don't have them in your path;
557e4fd55aSmrg# or use environment vars.
567e4fd55aSmrg
577e4fd55aSmrgchgrpprog=${CHGRPPROG-chgrp}
587e4fd55aSmrgchmodprog=${CHMODPROG-chmod}
597e4fd55aSmrgchownprog=${CHOWNPROG-chown}
607e4fd55aSmrgcmpprog=${CMPPROG-cmp}
617e4fd55aSmrgcpprog=${CPPROG-cp}
627e4fd55aSmrgmkdirprog=${MKDIRPROG-mkdir}
637e4fd55aSmrgmvprog=${MVPROG-mv}
647e4fd55aSmrgrmprog=${RMPROG-rm}
657e4fd55aSmrgstripprog=${STRIPPROG-strip}
667e4fd55aSmrg
677e4fd55aSmrgposix_mkdir=
687e4fd55aSmrg
697e4fd55aSmrg# Desired mode of installed file.
707e4fd55aSmrgmode=0755
717e4fd55aSmrg
727e4fd55aSmrgchgrpcmd=
737e4fd55aSmrgchmodcmd=$chmodprog
747e4fd55aSmrgchowncmd=
757e4fd55aSmrgmvcmd=$mvprog
767e4fd55aSmrgrmcmd="$rmprog -f"
777e4fd55aSmrgstripcmd=
78b8f75c19Smrg
797e4fd55aSmrgsrc=
807e4fd55aSmrgdst=
817e4fd55aSmrgdir_arg=
827e4fd55aSmrgdst_arg=
83b8f75c19Smrg
847e4fd55aSmrgcopy_on_change=false
858832ea4aSmrgis_target_a_directory=possibly
86b8f75c19Smrg
877e4fd55aSmrgusage="\
887e4fd55aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
897e4fd55aSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
907e4fd55aSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
917e4fd55aSmrg   or: $0 [OPTION]... -d DIRECTORIES...
92b8f75c19Smrg
937e4fd55aSmrgIn the 1st form, copy SRCFILE to DSTFILE.
947e4fd55aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
957e4fd55aSmrgIn the 4th, create DIRECTORIES.
96b8f75c19Smrg
977e4fd55aSmrgOptions:
987e4fd55aSmrg     --help     display this help and exit.
997e4fd55aSmrg     --version  display version info and exit.
100b8f75c19Smrg
1017e4fd55aSmrg  -c            (ignored)
1027e4fd55aSmrg  -C            install only if different (preserve the last data modification time)
1037e4fd55aSmrg  -d            create directories instead of installing files.
1047e4fd55aSmrg  -g GROUP      $chgrpprog installed files to GROUP.
1057e4fd55aSmrg  -m MODE       $chmodprog installed files to MODE.
1067e4fd55aSmrg  -o USER       $chownprog installed files to USER.
1077e4fd55aSmrg  -s            $stripprog installed files.
1087e4fd55aSmrg  -t DIRECTORY  install into DIRECTORY.
1097e4fd55aSmrg  -T            report an error if DSTFILE is a directory.
110b8f75c19Smrg
1117e4fd55aSmrgEnvironment variables override the default commands:
1127e4fd55aSmrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1137e4fd55aSmrg  RMPROG STRIPPROG
1147e4fd55aSmrg"
115b8f75c19Smrg
1167e4fd55aSmrgwhile test $# -ne 0; do
1177e4fd55aSmrg  case $1 in
1187e4fd55aSmrg    -c) ;;
119b8f75c19Smrg
1207e4fd55aSmrg    -C) copy_on_change=true;;
121b8f75c19Smrg
1227e4fd55aSmrg    -d) dir_arg=true;;
123b8f75c19Smrg
1247e4fd55aSmrg    -g) chgrpcmd="$chgrpprog $2"
1258832ea4aSmrg        shift;;
126b8f75c19Smrg
1277e4fd55aSmrg    --help) echo "$usage"; exit $?;;
128b8f75c19Smrg
1297e4fd55aSmrg    -m) mode=$2
1308832ea4aSmrg        case $mode in
1318832ea4aSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
1328832ea4aSmrg            echo "$0: invalid mode: $mode" >&2
1338832ea4aSmrg            exit 1;;
1348832ea4aSmrg        esac
1358832ea4aSmrg        shift;;
136b8f75c19Smrg
1377e4fd55aSmrg    -o) chowncmd="$chownprog $2"
1388832ea4aSmrg        shift;;
139b8f75c19Smrg
1407e4fd55aSmrg    -s) stripcmd=$stripprog;;
141b8f75c19Smrg
1428832ea4aSmrg    -t)
1438832ea4aSmrg        is_target_a_directory=always
1448832ea4aSmrg        dst_arg=$2
1458832ea4aSmrg        # Protect names problematic for 'test' and other utilities.
1468832ea4aSmrg        case $dst_arg in
1478832ea4aSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1488832ea4aSmrg        esac
1498832ea4aSmrg        shift;;
150b8f75c19Smrg
1518832ea4aSmrg    -T) is_target_a_directory=never;;
152b8f75c19Smrg
1537e4fd55aSmrg    --version) echo "$0 $scriptversion"; exit $?;;
154b8f75c19Smrg
1558832ea4aSmrg    --) shift
1568832ea4aSmrg        break;;
157b8f75c19Smrg
1588832ea4aSmrg    -*) echo "$0: invalid option: $1" >&2
1598832ea4aSmrg        exit 1;;
160b8f75c19Smrg
1617e4fd55aSmrg    *)  break;;
1627e4fd55aSmrg  esac
1637e4fd55aSmrg  shift
1647e4fd55aSmrgdone
165b8f75c19Smrg
1668832ea4aSmrg# We allow the use of options -d and -T together, by making -d
1678832ea4aSmrg# take the precedence; this is for compatibility with GNU install.
1688832ea4aSmrg
1698832ea4aSmrgif test -n "$dir_arg"; then
1708832ea4aSmrg  if test -n "$dst_arg"; then
1718832ea4aSmrg    echo "$0: target directory not allowed when installing a directory." >&2
1728832ea4aSmrg    exit 1
1738832ea4aSmrg  fi
1748832ea4aSmrgfi
1758832ea4aSmrg
1767e4fd55aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1777e4fd55aSmrg  # When -d is used, all remaining arguments are directories to create.
1787e4fd55aSmrg  # When -t is used, the destination is already specified.
1797e4fd55aSmrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1807e4fd55aSmrg  for arg
1817e4fd55aSmrg  do
1827e4fd55aSmrg    if test -n "$dst_arg"; then
1837e4fd55aSmrg      # $@ is not empty: it contains at least $arg.
1847e4fd55aSmrg      set fnord "$@" "$dst_arg"
1857e4fd55aSmrg      shift # fnord
1867e4fd55aSmrg    fi
1877e4fd55aSmrg    shift # arg
1887e4fd55aSmrg    dst_arg=$arg
1898e4923e5Smrg    # Protect names problematic for 'test' and other utilities.
1908e4923e5Smrg    case $dst_arg in
1918e4923e5Smrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1928e4923e5Smrg    esac
1937e4fd55aSmrg  done
1947e4fd55aSmrgfi
195b8f75c19Smrg
1967e4fd55aSmrgif test $# -eq 0; then
1977e4fd55aSmrg  if test -z "$dir_arg"; then
1987e4fd55aSmrg    echo "$0: no input file specified." >&2
1997e4fd55aSmrg    exit 1
2007e4fd55aSmrg  fi
2018e4923e5Smrg  # It's OK to call 'install-sh -d' without argument.
2027e4fd55aSmrg  # This can happen when creating conditional directories.
2037e4fd55aSmrg  exit 0
2047e4fd55aSmrgfi
205b8f75c19Smrg
2068832ea4aSmrgif test -z "$dir_arg"; then
2078832ea4aSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
2088832ea4aSmrg    if test ! -d "$dst_arg"; then
2098832ea4aSmrg      echo "$0: $dst_arg: Is not a directory." >&2
2108832ea4aSmrg      exit 1
2118832ea4aSmrg    fi
2128832ea4aSmrg  fi
2138832ea4aSmrgfi
2148832ea4aSmrg
2157e4fd55aSmrgif test -z "$dir_arg"; then
2168e4923e5Smrg  do_exit='(exit $ret); exit $ret'
2178e4923e5Smrg  trap "ret=129; $do_exit" 1
2188e4923e5Smrg  trap "ret=130; $do_exit" 2
2198e4923e5Smrg  trap "ret=141; $do_exit" 13
2208e4923e5Smrg  trap "ret=143; $do_exit" 15
2217e4fd55aSmrg
2227e4fd55aSmrg  # Set umask so as not to create temps with too-generous modes.
2237e4fd55aSmrg  # However, 'strip' requires both read and write access to temps.
2247e4fd55aSmrg  case $mode in
2257e4fd55aSmrg    # Optimize common cases.
2267e4fd55aSmrg    *644) cp_umask=133;;
2277e4fd55aSmrg    *755) cp_umask=22;;
2287e4fd55aSmrg
2297e4fd55aSmrg    *[0-7])
2307e4fd55aSmrg      if test -z "$stripcmd"; then
2318832ea4aSmrg        u_plus_rw=
2327e4fd55aSmrg      else
2338832ea4aSmrg        u_plus_rw='% 200'
2347e4fd55aSmrg      fi
2357e4fd55aSmrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2367e4fd55aSmrg    *)
2377e4fd55aSmrg      if test -z "$stripcmd"; then
2388832ea4aSmrg        u_plus_rw=
2397e4fd55aSmrg      else
2408832ea4aSmrg        u_plus_rw=,u+rw
2417e4fd55aSmrg      fi
2427e4fd55aSmrg      cp_umask=$mode$u_plus_rw;;
2437e4fd55aSmrg  esac
2447e4fd55aSmrgfi
245b8f75c19Smrg
2467e4fd55aSmrgfor src
2477e4fd55aSmrgdo
2488e4923e5Smrg  # Protect names problematic for 'test' and other utilities.
2497e4fd55aSmrg  case $src in
2508e4923e5Smrg    -* | [=\(\)!]) src=./$src;;
2517e4fd55aSmrg  esac
2527e4fd55aSmrg
2537e4fd55aSmrg  if test -n "$dir_arg"; then
2547e4fd55aSmrg    dst=$src
2557e4fd55aSmrg    dstdir=$dst
2567e4fd55aSmrg    test -d "$dstdir"
2577e4fd55aSmrg    dstdir_status=$?
2587e4fd55aSmrg  else
2597e4fd55aSmrg
2607e4fd55aSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2617e4fd55aSmrg    # might cause directories to be created, which would be especially bad
2627e4fd55aSmrg    # if $src (and thus $dsttmp) contains '*'.
2637e4fd55aSmrg    if test ! -f "$src" && test ! -d "$src"; then
2647e4fd55aSmrg      echo "$0: $src does not exist." >&2
2657e4fd55aSmrg      exit 1
2667e4fd55aSmrg    fi
2677e4fd55aSmrg
2687e4fd55aSmrg    if test -z "$dst_arg"; then
2697e4fd55aSmrg      echo "$0: no destination specified." >&2
2707e4fd55aSmrg      exit 1
2717e4fd55aSmrg    fi
2727e4fd55aSmrg    dst=$dst_arg
273b8f75c19Smrg
2747e4fd55aSmrg    # If destination is a directory, append the input filename; won't work
2757e4fd55aSmrg    # if double slashes aren't ignored.
2767e4fd55aSmrg    if test -d "$dst"; then
2778832ea4aSmrg      if test "$is_target_a_directory" = never; then
2788832ea4aSmrg        echo "$0: $dst_arg: Is a directory" >&2
2798832ea4aSmrg        exit 1
2807e4fd55aSmrg      fi
2817e4fd55aSmrg      dstdir=$dst
2827e4fd55aSmrg      dst=$dstdir/`basename "$src"`
2837e4fd55aSmrg      dstdir_status=0
2847e4fd55aSmrg    else
2858832ea4aSmrg      dstdir=`dirname "$dst"`
2867e4fd55aSmrg      test -d "$dstdir"
2877e4fd55aSmrg      dstdir_status=$?
2887e4fd55aSmrg    fi
2897e4fd55aSmrg  fi
2907e4fd55aSmrg
2917e4fd55aSmrg  obsolete_mkdir_used=false
2927e4fd55aSmrg
2937e4fd55aSmrg  if test $dstdir_status != 0; then
2947e4fd55aSmrg    case $posix_mkdir in
2957e4fd55aSmrg      '')
2968832ea4aSmrg        # Create intermediate dirs using mode 755 as modified by the umask.
2978832ea4aSmrg        # This is like FreeBSD 'install' as of 1997-10-28.
2988832ea4aSmrg        umask=`umask`
2998832ea4aSmrg        case $stripcmd.$umask in
3008832ea4aSmrg          # Optimize common cases.
3018832ea4aSmrg          *[2367][2367]) mkdir_umask=$umask;;
3028832ea4aSmrg          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
3038832ea4aSmrg
3048832ea4aSmrg          *[0-7])
3058832ea4aSmrg            mkdir_umask=`expr $umask + 22 \
3068832ea4aSmrg              - $umask % 100 % 40 + $umask % 20 \
3078832ea4aSmrg              - $umask % 10 % 4 + $umask % 2
3088832ea4aSmrg            `;;
3098832ea4aSmrg          *) mkdir_umask=$umask,go-w;;
3108832ea4aSmrg        esac
3118832ea4aSmrg
3128832ea4aSmrg        # With -d, create the new directory with the user-specified mode.
3138832ea4aSmrg        # Otherwise, rely on $mkdir_umask.
3148832ea4aSmrg        if test -n "$dir_arg"; then
3158832ea4aSmrg          mkdir_mode=-m$mode
3168832ea4aSmrg        else
3178832ea4aSmrg          mkdir_mode=
3188832ea4aSmrg        fi
3198832ea4aSmrg
3208832ea4aSmrg        posix_mkdir=false
3218832ea4aSmrg        case $umask in
3228832ea4aSmrg          *[123567][0-7][0-7])
3238832ea4aSmrg            # POSIX mkdir -p sets u+wx bits regardless of umask, which
3248832ea4aSmrg            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
3258832ea4aSmrg            ;;
3268832ea4aSmrg          *)
3278832ea4aSmrg            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
3288832ea4aSmrg            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
3298832ea4aSmrg
3308832ea4aSmrg            if (umask $mkdir_umask &&
3318832ea4aSmrg                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
3328832ea4aSmrg            then
3338832ea4aSmrg              if test -z "$dir_arg" || {
3348832ea4aSmrg                   # Check for POSIX incompatibilities with -m.
3358832ea4aSmrg                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3368832ea4aSmrg                   # other-writable bit of parent directory when it shouldn't.
3378832ea4aSmrg                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
3388832ea4aSmrg                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
3398832ea4aSmrg                   case $ls_ld_tmpdir in
3408832ea4aSmrg                     d????-?r-*) different_mode=700;;
3418832ea4aSmrg                     d????-?--*) different_mode=755;;
3428832ea4aSmrg                     *) false;;
3438832ea4aSmrg                   esac &&
3448832ea4aSmrg                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
3458832ea4aSmrg                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
3468832ea4aSmrg                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
3478832ea4aSmrg                   }
3488832ea4aSmrg                 }
3498832ea4aSmrg              then posix_mkdir=:
3508832ea4aSmrg              fi
3518832ea4aSmrg              rmdir "$tmpdir/d" "$tmpdir"
3528832ea4aSmrg            else
3538832ea4aSmrg              # Remove any dirs left behind by ancient mkdir implementations.
3548832ea4aSmrg              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
3558832ea4aSmrg            fi
3568832ea4aSmrg            trap '' 0;;
3578832ea4aSmrg        esac;;
3587e4fd55aSmrg    esac
359b8f75c19Smrg
3607e4fd55aSmrg    if
3617e4fd55aSmrg      $posix_mkdir && (
3628832ea4aSmrg        umask $mkdir_umask &&
3638832ea4aSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3647e4fd55aSmrg      )
3657e4fd55aSmrg    then :
3667e4fd55aSmrg    else
3677e4fd55aSmrg
3687e4fd55aSmrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3697e4fd55aSmrg      # or it failed possibly due to a race condition.  Create the
3707e4fd55aSmrg      # directory the slow way, step by step, checking for races as we go.
3717e4fd55aSmrg
3727e4fd55aSmrg      case $dstdir in
3738832ea4aSmrg        /*) prefix='/';;
3748832ea4aSmrg        [-=\(\)!]*) prefix='./';;
3758832ea4aSmrg        *)  prefix='';;
3767e4fd55aSmrg      esac
3777e4fd55aSmrg
3787e4fd55aSmrg      oIFS=$IFS
3797e4fd55aSmrg      IFS=/
3808832ea4aSmrg      set -f
3817e4fd55aSmrg      set fnord $dstdir
3827e4fd55aSmrg      shift
3838832ea4aSmrg      set +f
3847e4fd55aSmrg      IFS=$oIFS
3857e4fd55aSmrg
3867e4fd55aSmrg      prefixes=
3877e4fd55aSmrg
3887e4fd55aSmrg      for d
3897e4fd55aSmrg      do
3908832ea4aSmrg        test X"$d" = X && continue
3918832ea4aSmrg
3928832ea4aSmrg        prefix=$prefix$d
3938832ea4aSmrg        if test -d "$prefix"; then
3948832ea4aSmrg          prefixes=
3958832ea4aSmrg        else
3968832ea4aSmrg          if $posix_mkdir; then
3978832ea4aSmrg            (umask=$mkdir_umask &&
3988832ea4aSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
3998832ea4aSmrg            # Don't fail if two instances are running concurrently.
4008832ea4aSmrg            test -d "$prefix" || exit 1
4018832ea4aSmrg          else
4028832ea4aSmrg            case $prefix in
4038832ea4aSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
4048832ea4aSmrg              *) qprefix=$prefix;;
4058832ea4aSmrg            esac
4068832ea4aSmrg            prefixes="$prefixes '$qprefix'"
4078832ea4aSmrg          fi
4088832ea4aSmrg        fi
4098832ea4aSmrg        prefix=$prefix/
4107e4fd55aSmrg      done
4117e4fd55aSmrg
4127e4fd55aSmrg      if test -n "$prefixes"; then
4138832ea4aSmrg        # Don't fail if two instances are running concurrently.
4148832ea4aSmrg        (umask $mkdir_umask &&
4158832ea4aSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
4168832ea4aSmrg          test -d "$dstdir" || exit 1
4178832ea4aSmrg        obsolete_mkdir_used=true
4187e4fd55aSmrg      fi
4197e4fd55aSmrg    fi
4207e4fd55aSmrg  fi
4217e4fd55aSmrg
4227e4fd55aSmrg  if test -n "$dir_arg"; then
4237e4fd55aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4247e4fd55aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4257e4fd55aSmrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4267e4fd55aSmrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4277e4fd55aSmrg  else
4287e4fd55aSmrg
4297e4fd55aSmrg    # Make a couple of temp file names in the proper directory.
4307e4fd55aSmrg    dsttmp=$dstdir/_inst.$$_
4317e4fd55aSmrg    rmtmp=$dstdir/_rm.$$_
4327e4fd55aSmrg
4337e4fd55aSmrg    # Trap to clean up those temp files at exit.
4347e4fd55aSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4357e4fd55aSmrg
4367e4fd55aSmrg    # Copy the file name to the temp name.
4377e4fd55aSmrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4387e4fd55aSmrg
4397e4fd55aSmrg    # and set any options; do chmod last to preserve setuid bits.
4407e4fd55aSmrg    #
4417e4fd55aSmrg    # If any of these fail, we abort the whole thing.  If we want to
4427e4fd55aSmrg    # ignore errors from any of these, just make sure not to ignore
4437e4fd55aSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4447e4fd55aSmrg    #
4457e4fd55aSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4467e4fd55aSmrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4477e4fd55aSmrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4487e4fd55aSmrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4497e4fd55aSmrg
4507e4fd55aSmrg    # If -C, don't bother to copy if it wouldn't change the file.
4517e4fd55aSmrg    if $copy_on_change &&
4528832ea4aSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
4538832ea4aSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
4548832ea4aSmrg       set -f &&
4557e4fd55aSmrg       set X $old && old=:$2:$4:$5:$6 &&
4567e4fd55aSmrg       set X $new && new=:$2:$4:$5:$6 &&
4578832ea4aSmrg       set +f &&
4587e4fd55aSmrg       test "$old" = "$new" &&
4597e4fd55aSmrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4607e4fd55aSmrg    then
4617e4fd55aSmrg      rm -f "$dsttmp"
4627e4fd55aSmrg    else
4637e4fd55aSmrg      # Rename the file to the real destination.
4647e4fd55aSmrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4657e4fd55aSmrg
4667e4fd55aSmrg      # The rename failed, perhaps because mv can't rename something else
4677e4fd55aSmrg      # to itself, or perhaps because mv is so ancient that it does not
4687e4fd55aSmrg      # support -f.
4697e4fd55aSmrg      {
4708832ea4aSmrg        # Now remove or move aside any old file at destination location.
4718832ea4aSmrg        # We try this two ways since rm can't unlink itself on some
4728832ea4aSmrg        # systems and the destination file might be busy for other
4738832ea4aSmrg        # reasons.  In this case, the final cleanup might fail but the new
4748832ea4aSmrg        # file should still install successfully.
4758832ea4aSmrg        {
4768832ea4aSmrg          test ! -f "$dst" ||
4778832ea4aSmrg          $doit $rmcmd -f "$dst" 2>/dev/null ||
4788832ea4aSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
4798832ea4aSmrg            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
4808832ea4aSmrg          } ||
4818832ea4aSmrg          { echo "$0: cannot unlink or rename $dst" >&2
4828832ea4aSmrg            (exit 1); exit 1
4838832ea4aSmrg          }
4848832ea4aSmrg        } &&
4858832ea4aSmrg
4868832ea4aSmrg        # Now rename the file to the real destination.
4878832ea4aSmrg        $doit $mvcmd "$dsttmp" "$dst"
4887e4fd55aSmrg      }
4897e4fd55aSmrg    fi || exit 1
4907e4fd55aSmrg
4917e4fd55aSmrg    trap '' 0
4927e4fd55aSmrg  fi
4937e4fd55aSmrgdone
494b8f75c19Smrg
4957e4fd55aSmrg# Local variables:
4967e4fd55aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
4977e4fd55aSmrg# time-stamp-start: "scriptversion="
4987e4fd55aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
4997e4fd55aSmrg# time-stamp-time-zone: "UTC"
5007e4fd55aSmrg# time-stamp-end: "; # UTC"
5017e4fd55aSmrg# End:
502