Blame install-sh

Packit e4b6da
#!/bin/sh
Packit e4b6da
# install - install a program, script, or datafile
Packit e4b6da
Packit e4b6da
scriptversion=2005-05-14.22
Packit e4b6da
Packit e4b6da
# This originates from X11R5 (mit/util/scripts/install.sh), which was
Packit e4b6da
# later released in X11R6 (xc/config/util/install.sh) with the
Packit e4b6da
# following copyright and license.
Packit e4b6da
#
Packit e4b6da
# Copyright (C) 1994 X Consortium
Packit e4b6da
#
Packit e4b6da
# Permission is hereby granted, free of charge, to any person obtaining a copy
Packit e4b6da
# of this software and associated documentation files (the "Software"), to
Packit e4b6da
# deal in the Software without restriction, including without limitation the
Packit e4b6da
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
Packit e4b6da
# sell copies of the Software, and to permit persons to whom the Software is
Packit e4b6da
# furnished to do so, subject to the following conditions:
Packit e4b6da
#
Packit e4b6da
# The above copyright notice and this permission notice shall be included in
Packit e4b6da
# all copies or substantial portions of the Software.
Packit e4b6da
#
Packit e4b6da
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit e4b6da
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit e4b6da
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit e4b6da
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit e4b6da
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
Packit e4b6da
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit e4b6da
#
Packit e4b6da
# Except as contained in this notice, the name of the X Consortium shall not
Packit e4b6da
# be used in advertising or otherwise to promote the sale, use or other deal-
Packit e4b6da
# ings in this Software without prior written authorization from the X Consor-
Packit e4b6da
# tium.
Packit e4b6da
#
Packit e4b6da
#
Packit e4b6da
# FSF changes to this file are in the public domain.
Packit e4b6da
#
Packit e4b6da
# Calling this script install-sh is preferred over install.sh, to prevent
Packit e4b6da
# `make' implicit rules from creating a file called install from it
Packit e4b6da
# when there is no Makefile.
Packit e4b6da
#
Packit e4b6da
# This script is compatible with the BSD install script, but was written
Packit e4b6da
# from scratch.  It can only install one file at a time, a restriction
Packit e4b6da
# shared with many OS's install programs.
Packit e4b6da
Packit e4b6da
# set DOITPROG to echo to test this script
Packit e4b6da
Packit e4b6da
# Don't use :- since 4.3BSD and earlier shells don't like it.
Packit e4b6da
doit="${DOITPROG-}"
Packit e4b6da
Packit e4b6da
# put in absolute paths if you don't have them in your path; or use env. vars.
Packit e4b6da
Packit e4b6da
mvprog="${MVPROG-mv}"
Packit e4b6da
cpprog="${CPPROG-cp}"
Packit e4b6da
chmodprog="${CHMODPROG-chmod}"
Packit e4b6da
chownprog="${CHOWNPROG-chown}"
Packit e4b6da
chgrpprog="${CHGRPPROG-chgrp}"
Packit e4b6da
stripprog="${STRIPPROG-strip}"
Packit e4b6da
rmprog="${RMPROG-rm}"
Packit e4b6da
mkdirprog="${MKDIRPROG-mkdir}"
Packit e4b6da
Packit e4b6da
chmodcmd="$chmodprog 0755"
Packit e4b6da
chowncmd=
Packit e4b6da
chgrpcmd=
Packit e4b6da
stripcmd=
Packit e4b6da
rmcmd="$rmprog -f"
Packit e4b6da
mvcmd="$mvprog"
Packit e4b6da
src=
Packit e4b6da
dst=
Packit e4b6da
dir_arg=
Packit e4b6da
dstarg=
Packit e4b6da
no_target_directory=
Packit e4b6da
Packit e4b6da
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
Packit e4b6da
   or: $0 [OPTION]... SRCFILES... DIRECTORY
Packit e4b6da
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
Packit e4b6da
   or: $0 [OPTION]... -d DIRECTORIES...
Packit e4b6da
Packit e4b6da
In the 1st form, copy SRCFILE to DSTFILE.
Packit e4b6da
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
Packit e4b6da
In the 4th, create DIRECTORIES.
Packit e4b6da
Packit e4b6da
Options:
Packit e4b6da
-c         (ignored)
Packit e4b6da
-d         create directories instead of installing files.
Packit e4b6da
-g GROUP   $chgrpprog installed files to GROUP.
Packit e4b6da
-m MODE    $chmodprog installed files to MODE.
Packit e4b6da
-o USER    $chownprog installed files to USER.
Packit e4b6da
-s         $stripprog installed files.
Packit e4b6da
-t DIRECTORY  install into DIRECTORY.
Packit e4b6da
-T         report an error if DSTFILE is a directory.
Packit e4b6da
--help     display this help and exit.
Packit e4b6da
--version  display version info and exit.
Packit e4b6da
Packit e4b6da
Environment variables override the default commands:
Packit e4b6da
  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
Packit e4b6da
"
Packit e4b6da
Packit e4b6da
while test -n "$1"; do
Packit e4b6da
  case $1 in
Packit e4b6da
    -c) shift
Packit e4b6da
        continue;;
Packit e4b6da
Packit e4b6da
    -d) dir_arg=true
Packit e4b6da
        shift
Packit e4b6da
        continue;;
Packit e4b6da
Packit e4b6da
    -g) chgrpcmd="$chgrpprog $2"
Packit e4b6da
        shift
Packit e4b6da
        shift
Packit e4b6da
        continue;;
Packit e4b6da
Packit e4b6da
    --help) echo "$usage"; exit $?;;
Packit e4b6da
Packit e4b6da
    -m) chmodcmd="$chmodprog $2"
Packit e4b6da
        shift
Packit e4b6da
        shift
Packit e4b6da
        continue;;
Packit e4b6da
Packit e4b6da
    -o) chowncmd="$chownprog $2"
Packit e4b6da
        shift
Packit e4b6da
        shift
Packit e4b6da
        continue;;
Packit e4b6da
Packit e4b6da
    -s) stripcmd=$stripprog
Packit e4b6da
        shift
Packit e4b6da
        continue;;
Packit e4b6da
Packit e4b6da
    -t) dstarg=$2
Packit e4b6da
	shift
Packit e4b6da
	shift
Packit e4b6da
	continue;;
Packit e4b6da
Packit e4b6da
    -T) no_target_directory=true
Packit e4b6da
	shift
Packit e4b6da
	continue;;
Packit e4b6da
Packit e4b6da
    --version) echo "$0 $scriptversion"; exit $?;;
Packit e4b6da
Packit e4b6da
    *)  # When -d is used, all remaining arguments are directories to create.
Packit e4b6da
	# When -t is used, the destination is already specified.
Packit e4b6da
	test -n "$dir_arg$dstarg" && break
Packit e4b6da
        # Otherwise, the last argument is the destination.  Remove it from $@.
Packit e4b6da
	for arg
Packit e4b6da
	do
Packit e4b6da
          if test -n "$dstarg"; then
Packit e4b6da
	    # $@ is not empty: it contains at least $arg.
Packit e4b6da
	    set fnord "$@" "$dstarg"
Packit e4b6da
	    shift # fnord
Packit e4b6da
	  fi
Packit e4b6da
	  shift # arg
Packit e4b6da
	  dstarg=$arg
Packit e4b6da
	done
Packit e4b6da
	break;;
Packit e4b6da
  esac
Packit e4b6da
done
Packit e4b6da
Packit e4b6da
if test -z "$1"; then
Packit e4b6da
  if test -z "$dir_arg"; then
Packit e4b6da
    echo "$0: no input file specified." >&2
Packit e4b6da
    exit 1
Packit e4b6da
  fi
Packit e4b6da
  # It's OK to call `install-sh -d' without argument.
Packit e4b6da
  # This can happen when creating conditional directories.
Packit e4b6da
  exit 0
Packit e4b6da
fi
Packit e4b6da
Packit e4b6da
for src
Packit e4b6da
do
Packit e4b6da
  # Protect names starting with `-'.
Packit e4b6da
  case $src in
Packit e4b6da
    -*) src=./$src ;;
Packit e4b6da
  esac
Packit e4b6da
Packit e4b6da
  if test -n "$dir_arg"; then
Packit e4b6da
    dst=$src
Packit e4b6da
    src=
Packit e4b6da
Packit e4b6da
    if test -d "$dst"; then
Packit e4b6da
      mkdircmd=:
Packit e4b6da
      chmodcmd=
Packit e4b6da
    else
Packit e4b6da
      mkdircmd=$mkdirprog
Packit e4b6da
    fi
Packit e4b6da
  else
Packit e4b6da
    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
Packit e4b6da
    # might cause directories to be created, which would be especially bad
Packit e4b6da
    # if $src (and thus $dsttmp) contains '*'.
Packit e4b6da
    if test ! -f "$src" && test ! -d "$src"; then
Packit e4b6da
      echo "$0: $src does not exist." >&2
Packit e4b6da
      exit 1
Packit e4b6da
    fi
Packit e4b6da
Packit e4b6da
    if test -z "$dstarg"; then
Packit e4b6da
      echo "$0: no destination specified." >&2
Packit e4b6da
      exit 1
Packit e4b6da
    fi
Packit e4b6da
Packit e4b6da
    dst=$dstarg
Packit e4b6da
    # Protect names starting with `-'.
Packit e4b6da
    case $dst in
Packit e4b6da
      -*) dst=./$dst ;;
Packit e4b6da
    esac
Packit e4b6da
Packit e4b6da
    # If destination is a directory, append the input filename; won't work
Packit e4b6da
    # if double slashes aren't ignored.
Packit e4b6da
    if test -d "$dst"; then
Packit e4b6da
      if test -n "$no_target_directory"; then
Packit e4b6da
	echo "$0: $dstarg: Is a directory" >&2
Packit e4b6da
	exit 1
Packit e4b6da
      fi
Packit e4b6da
      dst=$dst/`basename "$src"`
Packit e4b6da
    fi
Packit e4b6da
  fi
Packit e4b6da
Packit e4b6da
  # This sed command emulates the dirname command.
Packit e4b6da
  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
Packit e4b6da
Packit e4b6da
  # Make sure that the destination directory exists.
Packit e4b6da
Packit e4b6da
  # Skip lots of stat calls in the usual case.
Packit e4b6da
  if test ! -d "$dstdir"; then
Packit e4b6da
    defaultIFS='
Packit e4b6da
	 '
Packit e4b6da
    IFS="${IFS-$defaultIFS}"
Packit e4b6da
Packit e4b6da
    oIFS=$IFS
Packit e4b6da
    # Some sh's can't handle IFS=/ for some reason.
Packit e4b6da
    IFS='%'
Packit e4b6da
    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
Packit e4b6da
    shift
Packit e4b6da
    IFS=$oIFS
Packit e4b6da
Packit e4b6da
    pathcomp=
Packit e4b6da
Packit e4b6da
    while test $# -ne 0 ; do
Packit e4b6da
      pathcomp=$pathcomp$1
Packit e4b6da
      shift
Packit e4b6da
      if test ! -d "$pathcomp"; then
Packit e4b6da
        $mkdirprog "$pathcomp"
Packit e4b6da
	# mkdir can fail with a `File exist' error in case several
Packit e4b6da
	# install-sh are creating the directory concurrently.  This
Packit e4b6da
	# is OK.
Packit e4b6da
	test -d "$pathcomp" || exit
Packit e4b6da
      fi
Packit e4b6da
      pathcomp=$pathcomp/
Packit e4b6da
    done
Packit e4b6da
  fi
Packit e4b6da
Packit e4b6da
  if test -n "$dir_arg"; then
Packit e4b6da
    $doit $mkdircmd "$dst" \
Packit e4b6da
      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
Packit e4b6da
      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
Packit e4b6da
      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
Packit e4b6da
      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
Packit e4b6da
Packit e4b6da
  else
Packit e4b6da
    dstfile=`basename "$dst"`
Packit e4b6da
Packit e4b6da
    # Make a couple of temp file names in the proper directory.
Packit e4b6da
    dsttmp=$dstdir/_inst.$$_
Packit e4b6da
    rmtmp=$dstdir/_rm.$$_
Packit e4b6da
Packit e4b6da
    # Trap to clean up those temp files at exit.
Packit e4b6da
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
Packit e4b6da
    trap '(exit $?); exit' 1 2 13 15
Packit e4b6da
Packit e4b6da
    # Copy the file name to the temp name.
Packit e4b6da
    $doit $cpprog "$src" "$dsttmp" &&
Packit e4b6da
Packit e4b6da
    # and set any options; do chmod last to preserve setuid bits.
Packit e4b6da
    #
Packit e4b6da
    # If any of these fail, we abort the whole thing.  If we want to
Packit e4b6da
    # ignore errors from any of these, just make sure not to ignore
Packit e4b6da
    # errors from the above "$doit $cpprog $src $dsttmp" command.
Packit e4b6da
    #
Packit e4b6da
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
Packit e4b6da
      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
Packit e4b6da
      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
Packit e4b6da
      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
Packit e4b6da
Packit e4b6da
    # Now rename the file to the real destination.
Packit e4b6da
    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
Packit e4b6da
      || {
Packit e4b6da
	   # The rename failed, perhaps because mv can't rename something else
Packit e4b6da
	   # to itself, or perhaps because mv is so ancient that it does not
Packit e4b6da
	   # support -f.
Packit e4b6da
Packit e4b6da
	   # Now remove or move aside any old file at destination location.
Packit e4b6da
	   # We try this two ways since rm can't unlink itself on some
Packit e4b6da
	   # systems and the destination file might be busy for other
Packit e4b6da
	   # reasons.  In this case, the final cleanup might fail but the new
Packit e4b6da
	   # file should still install successfully.
Packit e4b6da
	   {
Packit e4b6da
	     if test -f "$dstdir/$dstfile"; then
Packit e4b6da
	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
Packit e4b6da
	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
Packit e4b6da
	       || {
Packit e4b6da
		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
Packit e4b6da
		 (exit 1); exit 1
Packit e4b6da
	       }
Packit e4b6da
	     else
Packit e4b6da
	       :
Packit e4b6da
	     fi
Packit e4b6da
	   } &&
Packit e4b6da
Packit e4b6da
	   # Now rename the file to the real destination.
Packit e4b6da
	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
Packit e4b6da
	 }
Packit e4b6da
    }
Packit e4b6da
  fi || { (exit 1); exit 1; }
Packit e4b6da
done
Packit e4b6da
Packit e4b6da
# The final little trick to "correctly" pass the exit status to the exit trap.
Packit e4b6da
{
Packit e4b6da
  (exit 0); exit 0
Packit e4b6da
}
Packit e4b6da
Packit e4b6da
# Local variables:
Packit e4b6da
# eval: (add-hook 'write-file-hooks 'time-stamp)
Packit e4b6da
# time-stamp-start: "scriptversion="
Packit e4b6da
# time-stamp-format: "%:y-%02m-%02d.%02H"
Packit e4b6da
# time-stamp-end: "$"
Packit e4b6da
# End: