Blame install-sh

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