#! /bin/bash
#
# INSTALL : Install a package
# 
# This script was written to install packages for The System Manager
# and was inspired by the Linux kernel configure script by 
# raymondc@microsoft.com (well, I think it's a neat hack :-)
#
# I'm sure this script can be used for any general purpose installation,
# and I hope it'll catch on big-time.  Let me say that again, louder.
#
# PLEASE USE THIS SCRIPT TO PROVIDE AN INSTALLATION SYSTEM FOR YOUR OWN
# SOFTWARE.  PLEASE USE THIS SCRIPT ON AS MANY UNIX PLATFORMS AS POSSIBLE.
# PLEASE MAKE USE OF IT'S SISTER SCRIPT, REMOVE, TO PROVIDE A WAY TO REMOVE
# YOUR SOFTWARE.
#
# Please send comments/suggestions/bug fixes to S.Herbert@sheffield.ac.uk

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--

set -h

COLOR_BLACK="\033[0;30m"
COLOR_RED="\033[1;31m"
COLOR_GREEN="\033[1;32m"
COLOR_YELLOW="\033[1;33m"
COLOR_BLUE="\033[1;34m"
COLOR_CYAN="\033[1;36m"
COLOR_LIGHT_GREY="\033[0;37m"
COLOR_DARK_GREY="\033[1;30m"
COLOR_WHITE="\033[1;37m"

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = succeed/found/forced/warning/fail (0/1/2/254/255)
# $2 = general report
# $3 = fail report
# $4 = don't log skipped entries

Report()
{
  if [ "$1" -eq 255 ]; then
    echo -ne "$COLOR_RED"
    echo -n  "Skipping"
    if [ -z "$4" ]; then
      echo -n  "Skipping : $2" >> $LOG
      if [ -n "$3" ]; then
        echo " ($3)" >> $LOG
      fi
      echo "(Use INSTALL -f <package> to force installation)" >> $LOG
    fi
  elif [ "$1" -eq 254 ]; then
    echo -ne "$COLOR_YELLOW"
    echo -n  "Warning "
    echo -n  "Skipping : $2" >> $LOG
    if [ -n "$3" ]; then
      echo " ($3)" >> $LOG
    fi
  elif [ "$1" -eq 2 ]; then
    echo -ne "$COLOR_YELLOW"
    echo -n  "Forced  "
  elif [ "$1" -eq 1 ]; then
    echo -ne "$COLOR_CYAN"
    echo -n  "Found   "
  else
    echo -ne "$COLOR_GREEN"
    echo -n  "Adding  "
  fi
  echo -ne "$COLOR_LIGHT_GREY"
  echo -n  " : $2"
  if [ ! "$3" = "" ]; then
    echo " ($3)"
  else
    echo ""
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# no arguements

Usage()
{
  if [ -d .MANIFEST ]; then
    echo "INSTALL: Install a package"
    echo "Packages available for installation are :"
    echo ""
    ls .MANIFEST
    echo ""
    echo "Type 'INSTALL [ -f ] <package> ...' to install a package or two."
  else
    echo "INSTALL: Directory .MANIFEST does not exist."
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = author name
# $2 = author address

author()
{
  echo -en "$COLOR_DARK_GREY: $COLOR_LIGHT_GREY"
  echo -e  "Copyright (c) $COLOR_WHITE$1$COLOR_LIGHT_GREY ($2)"
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = comment
# $2 = log it?

comment()
{
  echo -ne "$COLOR_DARK_GREY: $COLOR_LIGHT_GREY"
  echo     "$1"
  
  if [ "$2" = "y" -o "$2" = "Y" ]; then
    echo $1 >> $LOG
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $2 = directory/file
# $1 = test

depend()
{
  if [ $1 $2 ]; then
    echo > /dev/null
  else
    Report "254" "$1" "required, but not found"
    return 254
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = directory
# $2 = permissions
# $3 = consider directory for deletion?

dir()
{
  if [ -e "$1" ]; then
    Report "255" "$1" "dir: exists" "N"
    if [ "$3" = "y" -o "$3" = "Y" ]; then
      echo "$1/" >> $MANIFEST
    fi
    return 255
  else
    Report "0" "$1/" "mode : $2"
    install -m "$2" -d "$1"
    if [ "$3" = "y" -o "$3" = "Y" ]; then
      echo "$1/" >> $MANIFEST
    fi
    return 0
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# no arguements

endinfo()
{
  echo > /dev/null
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = source
# $2 = dest
# $3 = permissions

file()
{
  if [ -e "$2" ]; then
    if [ $FORCED -eq 1 ] ; then
      Report "255" "$2" "file: exists"
      return 255
    fi
  fi
  
  if [ ! -e "$1" ]; then
    Report "255" "$2" "file: $1 not found"
    return 255
  fi
  
  if [ -e "$2" ]; then
    Report "2" "$2" "mode : $3"
  else
    Report "0" "$2" "mode : $3"
  fi

  install -m "$3" "$1" "$2"
  echo "$2" >> $MANIFEST
  return 0
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = file to link to
# $2 = link

link()
{
  if [ -e "$2" ]; then
    if [ $FORCED -eq 1 ]; then
      Report "255" "$2" "link: exists"
      return 255
    fi
  fi
  
  if [ ! -e "$1" ]; then
    Report "255" "$1" "link: not found"
    return 255
  fi

  if [ -e "$2" ]; then
    Report "2" "$2" "symlink"
    rm -f $2
  else
    Report "0" "$2" "symlink"
  fi
  
  ln -s "$1" "$2"
  echo "$2" >> $MANIFEST
  return 0
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = log comment
# $2 = echo it?

log()
{
  echo "$1" >> $LOG
  if [ "$2" = "y" ]; then
    echo -ne "$COLOR_DARK_GREY: COLOR_LIGHT_GREY"
    echo     "$1"
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# no arguements

pause()
{
  local x
  echo
  echo -ne "$COLOR_RED"
  echo -n  "!"
  echo -e  "$COLOR_LIGHT_GREY Press ENTER or RETURN to continue, or ctrl-c to quit."
  read x < /dev/tty
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = required util

require()
{
  if [ -e "$1" ]; then
    Report "1" "$1" "required"
    return 0
  elif which "$1" > /dev/null ; then
    Report "1" "$1" "required"
    return 0
  else
    Report "254" "$1" "required, but not found"
    return 254
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# no arguements

root()
{
  if [ ! $UID -eq 0 ]; then
    echo "INSTALL: insufficient privilege (must be root)"
    exit 1
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = default hierarchy
# $2 = root directory of package

target()
{
  local targetdir
  local x
  
  if [ $UID -eq 0 ]; then
    x="YES"
    echo
    echo -ne "$COLOR_RED"
    echo -ne "!"
    echo -ne "$COLOR_LIGHT_GREY "
    echo      "Where do you want to install the package to?"
    echo -ne "$COLOR_RED! $COLOR_LIGHT_GREY"
    echo     "(Press ENTER for $1/$2)"
    read targetdir < /dev/tty
    if [ -z $targetdir ]; then
      TARGETDIR="$1/$2"
    else
      TARGETDIR="$targetdir"
    fi
    TARGETBIN="/usr/local/bin"
    TARGETLIB="/usr/local/lib"
    TARGETMAN="/usr/local/man"
  else
    TARGETDIR="$HOME/$2"
    TARGETBIN="$HOME/bin"
    TARGETLIB="$HOME/lib"
    TARGETMAN="$HOME/man"
    x="NO"
  fi
  
  export TARGETBIN
  export TARGETDIR
  export TARGETLIB
  export TARGETMAN

  echo -ne "$COLOR_DARK_GREY: $COLOR_LIGHT_GREY"
  echo     "Target destination is $TARGETDIR"

  if [ "$x" = "YES" ]; then
    pause
  fi
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# $1 = title

title()
{
  echo -e "$COLOR_DARK_GREY--*-- --*-- --*-- --*-- --*--"
  echo -ne "$COLOR_LIGHT_GREY"
  echo -e  "Installing '$COLOR_WHITE$1$COLOR_LIGHT_GREY'"
  echo -e "$COLOR_DARK_GREY--*-- --*-- --*-- --*-- --*--"
}

#--*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*-- --*--
# this is where the fun begins

LOG="README.install"
MANIFEST="INSTALLed"

# if no arguements, show usage and quit
if [ "$1" = "" ]; then
  Usage
  exit 0
fi

# okay, time to ditch the old log file
if [ -e $LOG ]; then
  rm -f $LOG
fi
if [ -e $MANIFEST ]; then
  rm -f $MANIFEST
fi

# do they want to force the issue?
if [ "$1" = "-f" ]; then
  FORCED=0
  shift
else
  FORCED=1
fi

# make sure the target is unset
if [ -n "$TARGETDIR" ]; then
  unset TARGETDIR
fi

# right, now work through arguements ...
for x in $@ ; do
  if [ -r .MANIFEST/$x ]; then
    Report "0" "$x" "package"
    . .MANIFEST/$x
    if [ -e $MANIFEST ]; then
      install -d $HOME/.INSTALLed
      install -m 640 $MANIFEST $HOME/.INSTALLed/$x
      rm $MANIFEST
    fi
  else
    Report "255" "$x" "package not found"
  fi
done

echo 
echo -en "$COLOR_WHITE"
echo -ne "INSTALL"
echo -e  "$COLOR_LIGHT_GREY: Installation is complete"

# do we have a log file?
if [ -s $LOG ]; then
  echo -e "Please read $COLOR_WHITE$LOG$COLOR_LIGHT_GREY for further information."
fi

# that's it folks!
