install-sh revision 76c9c3ba
116910e25Smrg#!/bin/sh
216910e25Smrg# install - install a program, script, or datafile
39c125d91Smrg
476c9c3baSmrgscriptversion=2013-12-25.23; # UTC
59c125d91Smrg
616910e25Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
716910e25Smrg# later released in X11R6 (xc/config/util/install.sh) with the
816910e25Smrg# following copyright and license.
916910e25Smrg#
1016910e25Smrg# Copyright (C) 1994 X Consortium
1116910e25Smrg#
1216910e25Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1316910e25Smrg# of this software and associated documentation files (the "Software"), to
1416910e25Smrg# deal in the Software without restriction, including without limitation the
1516910e25Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1616910e25Smrg# sell copies of the Software, and to permit persons to whom the Software is
1716910e25Smrg# furnished to do so, subject to the following conditions:
1816910e25Smrg#
1916910e25Smrg# The above copyright notice and this permission notice shall be included in
2016910e25Smrg# all copies or substantial portions of the Software.
2116910e25Smrg#
2216910e25Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2316910e25Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2416910e25Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2516910e25Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2616910e25Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2716910e25Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2816910e25Smrg#
2916910e25Smrg# Except as contained in this notice, the name of the X Consortium shall not
3016910e25Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3116910e25Smrg# ings in this Software without prior written authorization from the X Consor-
3216910e25Smrg# tium.
3316910e25Smrg#
3416910e25Smrg#
3516910e25Smrg# FSF changes to this file are in the public domain.
3616910e25Smrg#
3716910e25Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3876c9c3baSmrg# 'make' implicit rules from creating a file called install from it
3916910e25Smrg# when there is no Makefile.
4016910e25Smrg#
4116910e25Smrg# This script is compatible with the BSD install script, but was written
429c125d91Smrg# from scratch.
4316910e25Smrg
4476c9c3baSmrgtab='	'
459c125d91Smrgnl='
469c125d91Smrg'
4776c9c3baSmrgIFS=" $tab$nl"
4816910e25Smrg
4976c9c3baSmrg# Set DOITPROG to "echo" to test this script.
5016910e25Smrg
519c125d91Smrgdoit=${DOITPROG-}
5276c9c3baSmrgdoit_exec=${doit:-exec}
5316910e25Smrg
549c125d91Smrg# Put in absolute file names if you don't have them in your path;
559c125d91Smrg# or use environment vars.
569c125d91Smrg
579c125d91Smrgchgrpprog=${CHGRPPROG-chgrp}
589c125d91Smrgchmodprog=${CHMODPROG-chmod}
599c125d91Smrgchownprog=${CHOWNPROG-chown}
609c125d91Smrgcmpprog=${CMPPROG-cmp}
619c125d91Smrgcpprog=${CPPROG-cp}
629c125d91Smrgmkdirprog=${MKDIRPROG-mkdir}
639c125d91Smrgmvprog=${MVPROG-mv}
649c125d91Smrgrmprog=${RMPROG-rm}
659c125d91Smrgstripprog=${STRIPPROG-strip}
669c125d91Smrg
679c125d91Smrgposix_mkdir=
689c125d91Smrg
699c125d91Smrg# Desired mode of installed file.
709c125d91Smrgmode=0755
719c125d91Smrg
729c125d91Smrgchgrpcmd=
739c125d91Smrgchmodcmd=$chmodprog
749c125d91Smrgchowncmd=
759c125d91Smrgmvcmd=$mvprog
769c125d91Smrgrmcmd="$rmprog -f"
779c125d91Smrgstripcmd=
7816910e25Smrg
799c125d91Smrgsrc=
809c125d91Smrgdst=
819c125d91Smrgdir_arg=
829c125d91Smrgdst_arg=
8316910e25Smrg
849c125d91Smrgcopy_on_change=false
8576c9c3baSmrgis_target_a_directory=possibly
8616910e25Smrg
879c125d91Smrgusage="\
889c125d91SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
899c125d91Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
909c125d91Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
919c125d91Smrg   or: $0 [OPTION]... -d DIRECTORIES...
9216910e25Smrg
939c125d91SmrgIn the 1st form, copy SRCFILE to DSTFILE.
949c125d91SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
959c125d91SmrgIn the 4th, create DIRECTORIES.
9616910e25Smrg
979c125d91SmrgOptions:
989c125d91Smrg     --help     display this help and exit.
999c125d91Smrg     --version  display version info and exit.
10016910e25Smrg
1019c125d91Smrg  -c            (ignored)
1029c125d91Smrg  -C            install only if different (preserve the last data modification time)
1039c125d91Smrg  -d            create directories instead of installing files.
1049c125d91Smrg  -g GROUP      $chgrpprog installed files to GROUP.
1059c125d91Smrg  -m MODE       $chmodprog installed files to MODE.
1069c125d91Smrg  -o USER       $chownprog installed files to USER.
1079c125d91Smrg  -s            $stripprog installed files.
1089c125d91Smrg  -t DIRECTORY  install into DIRECTORY.
1099c125d91Smrg  -T            report an error if DSTFILE is a directory.
11016910e25Smrg
1119c125d91SmrgEnvironment variables override the default commands:
1129c125d91Smrg  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
1139c125d91Smrg  RMPROG STRIPPROG
1149c125d91Smrg"
11516910e25Smrg
1169c125d91Smrgwhile test $# -ne 0; do
1179c125d91Smrg  case $1 in
1189c125d91Smrg    -c) ;;
11916910e25Smrg
1209c125d91Smrg    -C) copy_on_change=true;;
12116910e25Smrg
1229c125d91Smrg    -d) dir_arg=true;;
12316910e25Smrg
1249c125d91Smrg    -g) chgrpcmd="$chgrpprog $2"
12576c9c3baSmrg        shift;;
12616910e25Smrg
1279c125d91Smrg    --help) echo "$usage"; exit $?;;
12816910e25Smrg
1299c125d91Smrg    -m) mode=$2
13076c9c3baSmrg        case $mode in
13176c9c3baSmrg          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
13276c9c3baSmrg            echo "$0: invalid mode: $mode" >&2
13376c9c3baSmrg            exit 1;;
13476c9c3baSmrg        esac
13576c9c3baSmrg        shift;;
13616910e25Smrg
1379c125d91Smrg    -o) chowncmd="$chownprog $2"
13876c9c3baSmrg        shift;;
13916910e25Smrg
1409c125d91Smrg    -s) stripcmd=$stripprog;;
14116910e25Smrg
14276c9c3baSmrg    -t)
14376c9c3baSmrg        is_target_a_directory=always
14476c9c3baSmrg        dst_arg=$2
14576c9c3baSmrg        # Protect names problematic for 'test' and other utilities.
14676c9c3baSmrg        case $dst_arg in
14776c9c3baSmrg          -* | [=\(\)!]) dst_arg=./$dst_arg;;
14876c9c3baSmrg        esac
14976c9c3baSmrg        shift;;
15016910e25Smrg
15176c9c3baSmrg    -T) is_target_a_directory=never;;
15216910e25Smrg
1539c125d91Smrg    --version) echo "$0 $scriptversion"; exit $?;;
15416910e25Smrg
15576c9c3baSmrg    --) shift
15676c9c3baSmrg        break;;
15716910e25Smrg
15876c9c3baSmrg    -*) echo "$0: invalid option: $1" >&2
15976c9c3baSmrg        exit 1;;
16016910e25Smrg
1619c125d91Smrg    *)  break;;
1629c125d91Smrg  esac
1639c125d91Smrg  shift
1649c125d91Smrgdone
16516910e25Smrg
16676c9c3baSmrg# We allow the use of options -d and -T together, by making -d
16776c9c3baSmrg# take the precedence; this is for compatibility with GNU install.
16876c9c3baSmrg
16976c9c3baSmrgif test -n "$dir_arg"; then
17076c9c3baSmrg  if test -n "$dst_arg"; then
17176c9c3baSmrg    echo "$0: target directory not allowed when installing a directory." >&2
17276c9c3baSmrg    exit 1
17376c9c3baSmrg  fi
17476c9c3baSmrgfi
17576c9c3baSmrg
1769c125d91Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
1779c125d91Smrg  # When -d is used, all remaining arguments are directories to create.
1789c125d91Smrg  # When -t is used, the destination is already specified.
1799c125d91Smrg  # Otherwise, the last argument is the destination.  Remove it from $@.
1809c125d91Smrg  for arg
1819c125d91Smrg  do
1829c125d91Smrg    if test -n "$dst_arg"; then
1839c125d91Smrg      # $@ is not empty: it contains at least $arg.
1849c125d91Smrg      set fnord "$@" "$dst_arg"
1859c125d91Smrg      shift # fnord
1869c125d91Smrg    fi
1879c125d91Smrg    shift # arg
1889c125d91Smrg    dst_arg=$arg
18976c9c3baSmrg    # Protect names problematic for 'test' and other utilities.
19076c9c3baSmrg    case $dst_arg in
19176c9c3baSmrg      -* | [=\(\)!]) dst_arg=./$dst_arg;;
19276c9c3baSmrg    esac
1939c125d91Smrg  done
1949c125d91Smrgfi
19516910e25Smrg
1969c125d91Smrgif test $# -eq 0; then
1979c125d91Smrg  if test -z "$dir_arg"; then
1989c125d91Smrg    echo "$0: no input file specified." >&2
1999c125d91Smrg    exit 1
2009c125d91Smrg  fi
20176c9c3baSmrg  # It's OK to call 'install-sh -d' without argument.
2029c125d91Smrg  # This can happen when creating conditional directories.
2039c125d91Smrg  exit 0
2049c125d91Smrgfi
20516910e25Smrg
2069c125d91Smrgif test -z "$dir_arg"; then
20776c9c3baSmrg  if test $# -gt 1 || test "$is_target_a_directory" = always; then
20876c9c3baSmrg    if test ! -d "$dst_arg"; then
20976c9c3baSmrg      echo "$0: $dst_arg: Is not a directory." >&2
21076c9c3baSmrg      exit 1
21176c9c3baSmrg    fi
21276c9c3baSmrg  fi
21376c9c3baSmrgfi
21476c9c3baSmrg
21576c9c3baSmrgif test -z "$dir_arg"; then
21676c9c3baSmrg  do_exit='(exit $ret); exit $ret'
21776c9c3baSmrg  trap "ret=129; $do_exit" 1
21876c9c3baSmrg  trap "ret=130; $do_exit" 2
21976c9c3baSmrg  trap "ret=141; $do_exit" 13
22076c9c3baSmrg  trap "ret=143; $do_exit" 15
2219c125d91Smrg
2229c125d91Smrg  # Set umask so as not to create temps with too-generous modes.
2239c125d91Smrg  # However, 'strip' requires both read and write access to temps.
2249c125d91Smrg  case $mode in
2259c125d91Smrg    # Optimize common cases.
2269c125d91Smrg    *644) cp_umask=133;;
2279c125d91Smrg    *755) cp_umask=22;;
2289c125d91Smrg
2299c125d91Smrg    *[0-7])
2309c125d91Smrg      if test -z "$stripcmd"; then
23176c9c3baSmrg        u_plus_rw=
2329c125d91Smrg      else
23376c9c3baSmrg        u_plus_rw='% 200'
2349c125d91Smrg      fi
2359c125d91Smrg      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
2369c125d91Smrg    *)
2379c125d91Smrg      if test -z "$stripcmd"; then
23876c9c3baSmrg        u_plus_rw=
2399c125d91Smrg      else
24076c9c3baSmrg        u_plus_rw=,u+rw
2419c125d91Smrg      fi
2429c125d91Smrg      cp_umask=$mode$u_plus_rw;;
2439c125d91Smrg  esac
2449c125d91Smrgfi
24516910e25Smrg
2469c125d91Smrgfor src
2479c125d91Smrgdo
24876c9c3baSmrg  # Protect names problematic for 'test' and other utilities.
2499c125d91Smrg  case $src in
25076c9c3baSmrg    -* | [=\(\)!]) src=./$src;;
2519c125d91Smrg  esac
2529c125d91Smrg
2539c125d91Smrg  if test -n "$dir_arg"; then
2549c125d91Smrg    dst=$src
2559c125d91Smrg    dstdir=$dst
2569c125d91Smrg    test -d "$dstdir"
2579c125d91Smrg    dstdir_status=$?
2589c125d91Smrg  else
2599c125d91Smrg
2609c125d91Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
2619c125d91Smrg    # might cause directories to be created, which would be especially bad
2629c125d91Smrg    # if $src (and thus $dsttmp) contains '*'.
2639c125d91Smrg    if test ! -f "$src" && test ! -d "$src"; then
2649c125d91Smrg      echo "$0: $src does not exist." >&2
2659c125d91Smrg      exit 1
2669c125d91Smrg    fi
2679c125d91Smrg
2689c125d91Smrg    if test -z "$dst_arg"; then
2699c125d91Smrg      echo "$0: no destination specified." >&2
2709c125d91Smrg      exit 1
2719c125d91Smrg    fi
2729c125d91Smrg    dst=$dst_arg
27316910e25Smrg
2749c125d91Smrg    # If destination is a directory, append the input filename; won't work
2759c125d91Smrg    # if double slashes aren't ignored.
2769c125d91Smrg    if test -d "$dst"; then
27776c9c3baSmrg      if test "$is_target_a_directory" = never; then
27876c9c3baSmrg        echo "$0: $dst_arg: Is a directory" >&2
27976c9c3baSmrg        exit 1
2809c125d91Smrg      fi
2819c125d91Smrg      dstdir=$dst
2829c125d91Smrg      dst=$dstdir/`basename "$src"`
2839c125d91Smrg      dstdir_status=0
2849c125d91Smrg    else
28576c9c3baSmrg      dstdir=`dirname "$dst"`
2869c125d91Smrg      test -d "$dstdir"
2879c125d91Smrg      dstdir_status=$?
2889c125d91Smrg    fi
2899c125d91Smrg  fi
2909c125d91Smrg
2919c125d91Smrg  obsolete_mkdir_used=false
2929c125d91Smrg
2939c125d91Smrg  if test $dstdir_status != 0; then
2949c125d91Smrg    case $posix_mkdir in
2959c125d91Smrg      '')
29676c9c3baSmrg        # Create intermediate dirs using mode 755 as modified by the umask.
29776c9c3baSmrg        # This is like FreeBSD 'install' as of 1997-10-28.
29876c9c3baSmrg        umask=`umask`
29976c9c3baSmrg        case $stripcmd.$umask in
30076c9c3baSmrg          # Optimize common cases.
30176c9c3baSmrg          *[2367][2367]) mkdir_umask=$umask;;
30276c9c3baSmrg          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
30376c9c3baSmrg
30476c9c3baSmrg          *[0-7])
30576c9c3baSmrg            mkdir_umask=`expr $umask + 22 \
30676c9c3baSmrg              - $umask % 100 % 40 + $umask % 20 \
30776c9c3baSmrg              - $umask % 10 % 4 + $umask % 2
30876c9c3baSmrg            `;;
30976c9c3baSmrg          *) mkdir_umask=$umask,go-w;;
31076c9c3baSmrg        esac
31176c9c3baSmrg
31276c9c3baSmrg        # With -d, create the new directory with the user-specified mode.
31376c9c3baSmrg        # Otherwise, rely on $mkdir_umask.
31476c9c3baSmrg        if test -n "$dir_arg"; then
31576c9c3baSmrg          mkdir_mode=-m$mode
31676c9c3baSmrg        else
31776c9c3baSmrg          mkdir_mode=
31876c9c3baSmrg        fi
31976c9c3baSmrg
32076c9c3baSmrg        posix_mkdir=false
32176c9c3baSmrg        case $umask in
32276c9c3baSmrg          *[123567][0-7][0-7])
32376c9c3baSmrg            # POSIX mkdir -p sets u+wx bits regardless of umask, which
32476c9c3baSmrg            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
32576c9c3baSmrg            ;;
32676c9c3baSmrg          *)
32776c9c3baSmrg            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
32876c9c3baSmrg            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
32976c9c3baSmrg
33076c9c3baSmrg            if (umask $mkdir_umask &&
33176c9c3baSmrg                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
33276c9c3baSmrg            then
33376c9c3baSmrg              if test -z "$dir_arg" || {
33476c9c3baSmrg                   # Check for POSIX incompatibilities with -m.
33576c9c3baSmrg                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
33676c9c3baSmrg                   # other-writable bit of parent directory when it shouldn't.
33776c9c3baSmrg                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
33876c9c3baSmrg                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
33976c9c3baSmrg                   case $ls_ld_tmpdir in
34076c9c3baSmrg                     d????-?r-*) different_mode=700;;
34176c9c3baSmrg                     d????-?--*) different_mode=755;;
34276c9c3baSmrg                     *) false;;
34376c9c3baSmrg                   esac &&
34476c9c3baSmrg                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
34576c9c3baSmrg                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
34676c9c3baSmrg                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
34776c9c3baSmrg                   }
34876c9c3baSmrg                 }
34976c9c3baSmrg              then posix_mkdir=:
35076c9c3baSmrg              fi
35176c9c3baSmrg              rmdir "$tmpdir/d" "$tmpdir"
35276c9c3baSmrg            else
35376c9c3baSmrg              # Remove any dirs left behind by ancient mkdir implementations.
35476c9c3baSmrg              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
35576c9c3baSmrg            fi
35676c9c3baSmrg            trap '' 0;;
35776c9c3baSmrg        esac;;
3589c125d91Smrg    esac
35916910e25Smrg
3609c125d91Smrg    if
3619c125d91Smrg      $posix_mkdir && (
36276c9c3baSmrg        umask $mkdir_umask &&
36376c9c3baSmrg        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
3649c125d91Smrg      )
3659c125d91Smrg    then :
3669c125d91Smrg    else
3679c125d91Smrg
3689c125d91Smrg      # The umask is ridiculous, or mkdir does not conform to POSIX,
3699c125d91Smrg      # or it failed possibly due to a race condition.  Create the
3709c125d91Smrg      # directory the slow way, step by step, checking for races as we go.
3719c125d91Smrg
3729c125d91Smrg      case $dstdir in
37376c9c3baSmrg        /*) prefix='/';;
37476c9c3baSmrg        [-=\(\)!]*) prefix='./';;
37576c9c3baSmrg        *)  prefix='';;
3769c125d91Smrg      esac
3779c125d91Smrg
3789c125d91Smrg      oIFS=$IFS
3799c125d91Smrg      IFS=/
38076c9c3baSmrg      set -f
3819c125d91Smrg      set fnord $dstdir
3829c125d91Smrg      shift
38376c9c3baSmrg      set +f
3849c125d91Smrg      IFS=$oIFS
3859c125d91Smrg
3869c125d91Smrg      prefixes=
3879c125d91Smrg
3889c125d91Smrg      for d
3899c125d91Smrg      do
39076c9c3baSmrg        test X"$d" = X && continue
39176c9c3baSmrg
39276c9c3baSmrg        prefix=$prefix$d
39376c9c3baSmrg        if test -d "$prefix"; then
39476c9c3baSmrg          prefixes=
39576c9c3baSmrg        else
39676c9c3baSmrg          if $posix_mkdir; then
39776c9c3baSmrg            (umask=$mkdir_umask &&
39876c9c3baSmrg             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
39976c9c3baSmrg            # Don't fail if two instances are running concurrently.
40076c9c3baSmrg            test -d "$prefix" || exit 1
40176c9c3baSmrg          else
40276c9c3baSmrg            case $prefix in
40376c9c3baSmrg              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
40476c9c3baSmrg              *) qprefix=$prefix;;
40576c9c3baSmrg            esac
40676c9c3baSmrg            prefixes="$prefixes '$qprefix'"
40776c9c3baSmrg          fi
40876c9c3baSmrg        fi
40976c9c3baSmrg        prefix=$prefix/
4109c125d91Smrg      done
4119c125d91Smrg
4129c125d91Smrg      if test -n "$prefixes"; then
41376c9c3baSmrg        # Don't fail if two instances are running concurrently.
41476c9c3baSmrg        (umask $mkdir_umask &&
41576c9c3baSmrg         eval "\$doit_exec \$mkdirprog $prefixes") ||
41676c9c3baSmrg          test -d "$dstdir" || exit 1
41776c9c3baSmrg        obsolete_mkdir_used=true
4189c125d91Smrg      fi
4199c125d91Smrg    fi
4209c125d91Smrg  fi
4219c125d91Smrg
4229c125d91Smrg  if test -n "$dir_arg"; then
4239c125d91Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
4249c125d91Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
4259c125d91Smrg    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
4269c125d91Smrg      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
4279c125d91Smrg  else
4289c125d91Smrg
4299c125d91Smrg    # Make a couple of temp file names in the proper directory.
4309c125d91Smrg    dsttmp=$dstdir/_inst.$$_
4319c125d91Smrg    rmtmp=$dstdir/_rm.$$_
4329c125d91Smrg
4339c125d91Smrg    # Trap to clean up those temp files at exit.
4349c125d91Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
4359c125d91Smrg
4369c125d91Smrg    # Copy the file name to the temp name.
4379c125d91Smrg    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
4389c125d91Smrg
4399c125d91Smrg    # and set any options; do chmod last to preserve setuid bits.
4409c125d91Smrg    #
4419c125d91Smrg    # If any of these fail, we abort the whole thing.  If we want to
4429c125d91Smrg    # ignore errors from any of these, just make sure not to ignore
4439c125d91Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
4449c125d91Smrg    #
4459c125d91Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
4469c125d91Smrg    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
4479c125d91Smrg    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
4489c125d91Smrg    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
4499c125d91Smrg
4509c125d91Smrg    # If -C, don't bother to copy if it wouldn't change the file.
4519c125d91Smrg    if $copy_on_change &&
45276c9c3baSmrg       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
45376c9c3baSmrg       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
45476c9c3baSmrg       set -f &&
4559c125d91Smrg       set X $old && old=:$2:$4:$5:$6 &&
4569c125d91Smrg       set X $new && new=:$2:$4:$5:$6 &&
45776c9c3baSmrg       set +f &&
4589c125d91Smrg       test "$old" = "$new" &&
4599c125d91Smrg       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
4609c125d91Smrg    then
4619c125d91Smrg      rm -f "$dsttmp"
4629c125d91Smrg    else
4639c125d91Smrg      # Rename the file to the real destination.
4649c125d91Smrg      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
4659c125d91Smrg
4669c125d91Smrg      # The rename failed, perhaps because mv can't rename something else
4679c125d91Smrg      # to itself, or perhaps because mv is so ancient that it does not
4689c125d91Smrg      # support -f.
4699c125d91Smrg      {
47076c9c3baSmrg        # Now remove or move aside any old file at destination location.
47176c9c3baSmrg        # We try this two ways since rm can't unlink itself on some
47276c9c3baSmrg        # systems and the destination file might be busy for other
47376c9c3baSmrg        # reasons.  In this case, the final cleanup might fail but the new
47476c9c3baSmrg        # file should still install successfully.
47576c9c3baSmrg        {
47676c9c3baSmrg          test ! -f "$dst" ||
47776c9c3baSmrg          $doit $rmcmd -f "$dst" 2>/dev/null ||
47876c9c3baSmrg          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
47976c9c3baSmrg            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
48076c9c3baSmrg          } ||
48176c9c3baSmrg          { echo "$0: cannot unlink or rename $dst" >&2
48276c9c3baSmrg            (exit 1); exit 1
48376c9c3baSmrg          }
48476c9c3baSmrg        } &&
48576c9c3baSmrg
48676c9c3baSmrg        # Now rename the file to the real destination.
48776c9c3baSmrg        $doit $mvcmd "$dsttmp" "$dst"
4889c125d91Smrg      }
4899c125d91Smrg    fi || exit 1
4909c125d91Smrg
4919c125d91Smrg    trap '' 0
4929c125d91Smrg  fi
4939c125d91Smrgdone
49416910e25Smrg
4959c125d91Smrg# Local variables:
4969c125d91Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
4979c125d91Smrg# time-stamp-start: "scriptversion="
4989c125d91Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
4999c125d91Smrg# time-stamp-time-zone: "UTC"
5009c125d91Smrg# time-stamp-end: "; # UTC"
5019c125d91Smrg# End:
502