#!/bin/sh
# $Id: ocsadmin 615 2010-09-30 15:49:42Z florenz@TU-BERLIN.DE $

## initialise SHELL
SHELL=/bin/sh
export SHELL

## define functions

SourceSpecs() {
    ok=no
    for d in $OCSSPECS 
    do
#       echo "trying $d/$OSARCH/ShSpecs.$1 $d/$OSARCH/Specs.$1 $d/ShSpecs.$1 $d/Specs.$1"
        if [ -f "$d/$OSARCH/ShSpecs.$1" ] ; then
            . $d/$OSARCH/ShSpecs.$1; ok=yes; break;
        elif [ -f "$d/$OSARCH/Specs.$1" ] ; then
            $OCSHOME/lib/om/etc/gmake2sh < $d/$OSARCH/Specs.$1 > /tmp/gmake2sh.$$
            . /tmp/gmake2sh.$$
            $RM /tmp/gmake2sh.$$
            ok=yes
            break
        elif [ -f "$d/ShSpecs.$1" ]; then
            . "$d/ShSpecs.$1"; ok=yes; break;
        elif [ -f "$d/Specs.$1" ]; then
            $OCSHOME/lib/om/etc/gmake2sh < $d/Specs.$1 > /tmp/gmake2sh.$$
            . /tmp/gmake2sh.$$
            $RM /tmp/gmake2sh.$$
            ok=yes
            break
        fi  
    done
    if [ $ok = no ]; then
       echo "+++ cannot find ShSpecs.$1 or Specs.$1 in $OCSSPECS"
       exit 3
    fi
}

CheckRequireds() {
    ok="yes"
    for r in $REQUIRED
    do
      if [ ! -f "$OCSHOME/packages/$r" ]; then
        if [ -n "$PKGNAME" ]; then
            echo "+++ package $PKGNAME requires $r"
        fi
        if [ -n "$LIBNAME" ]; then
            echo "+++ library $LIBNAME requires $r"
        fi
        ok="no"
      fi
    done
    if [ $ok = "no" ]; then 
        exit 4;
    fi
}
        

## initialise standard OCS variables
if [ -z "$OCS" ] 
then
  OCS=`expr $0 : '\(..*\)/bin/..*$'`  
  export OCS
fi

if [ -z "$OCSOM" ] 
then
  OCSOM=$OCS/lib/om
  export OCSOM
fi

if [ -z "$OCSPROJECT" ]
then
  OCSPROJECT=$OCSOM/specs/empty
  export OCSPROJECT
fi

if [ -z "$DOSFOP" ]
then
  DOSFOP=$OCS/dosfop
  export DOSFOP
fi

#echo "OCS $OCS; OCSOM $OCSOM; OCSPROJECT $OCSPROJECT; DOSFOP $DOSFOP; $0"

## initialise special ocsadmin variables

# usage info
usage () {
echo "usage: ocsadmin <flags> <command>"
echo ""
echo "  <flags> are optional"
echo "  -ocssrc <path>    path to the Opal source directory"
echo "              defaults to \$OCS/src"
echo "  -ocshome <path>   path to the root directory of the Opal installation"
echo "              defaults to \$OCS"
echo "  -ocsetc <path>    path to the om/etc scripts"
echo "              defaults to \$OCSSRC/om/etc"
echo "  -ocsspecs <path>  path to the package and library specifications,"
echo "              may be repeated"
echo "  [\$OCS defaults to the path to bin/ocsadmin]"
echo "   "
echo "  <command> is one of"
echo "  init [ -sed <SED> ]          initialise Opal installation,"
echo "                               SED is filename of sed program to be used"
echo "                               (default sed)"
echo "  install <lib-or-pkg-spec>*   install named libraries and packages"
echo "  info                         show installed libraries and packages"
echo "  checkdeps <lib-or-pkg-dep>   check dependencies "
echo "  ocs [ -command <cmd> ]   "
echo "      <lib-or-pkg-spec>*       do specified ocs command on"
echo "                               named libraries/packages"
}

# myself
OCSADMIN=$0

# OCSSRC the path to Opal sources
if [ -z "$OCSSRC" ]
then
  OCSSRC=${OCS}/src
  export OCSSRC
fi

# OCSHOME the place where the Opal installation resides
if [ -z "$OCSHOME" ]
then
  OCSHOME=${OCS}
  export OCSHOME
fi

# OCSETC the place where auxiliary scripts are found
if [ -z "$OCSETC" ]
then
  OCSETC=${OCSOM}/etc
  export OCSETC
fi

# OCSSPECS the place where Specs files are looked for
if [ -z "$OCSSPECS" ]
then
  OCSSPECS=". ${OCSOM}/specs"
  export OCSSPECS
fi

#echo "SRC $OCSSRC; HOME $OCSHOME; ETC $OCSETC; SPECS $OCSSPECS"

## analyse commandline arguments 

ok=yes
while [ -n "$ok" ]
do
#echo "Checking $1"
ok=`echo $1 | grep '-'`
#echo "ok #$ok#"
if [ -n "$ok" ]; then
  case $1 in
    -ocssrc)
        shift
        OCSSRC="$1"
        OCSETC="$OCSSRC/om/etc"
        shift ;;
    -ocshome)
        shift
        OCSHOME="$1"
        shift ;;
    -ocsetc)
        shift
        OCSETC="$1"
        shift ;;
    -ocsspecs)
        shift
        OCSSPECS="$OCSSPECS $1"
        shift;;
    *)
        echo "Unknown option $1" 
        usage
        exit 1;;
  esac
fi
done

# echo "SRC $OCSSRC; HOME $OCSHOME; ETC $OCSETC; SPECS $OCSSPECS"

## the init command is special (does not read ShSpecs.basic)
# therefore it is handled here

if [ "$1" = "init" ]; then
    shift
    if [ "$1" = "-sed" ]; then
      SED=$2
      shift
      shift ;
    else
      SED=sed ;
    fi
    export SED
    if [ "$1" = "reinit" ]; then
      if [ ! -d "$OCSHOME" ]; then
        echo "directory $OCSHOME does not exist -- use make install to create"
        exit 2
      fi
      shift
    else
      if [ ! -d "$OCSHOME" ]; then
        mkdir $OCSHOME
        ok=$?
        if [ "$ok" != "0" ]; then
            echo "cannot create $OCSHOME"
            exit 2
        fi
      else
        if [ ! -w "$OCSHOME" ]; then
          echo "$OCSHOME exists, but is not writeable"
          exit 2
        fi
        checkdir=`ls $OCSHOME`
        if [ -n "$checkdir" ]; then
          echo "$OCSHOME is not empty. Use make reinstall"
          exit 2
        fi
      fi
    fi
    SpecsDir=no
    for s in $OCSSPECS
    do
        if [ -f "$s/Specs.basic" ]; then
            SpecsDir=$s
        fi
    done
    if [ "$SpecsDir" = no ]; then
        echo "Specs.basic not found in $OCSSPECS"
        exit 2
    fi
    if [ ! -f "$OCSETC/gmake2sh" ]; then
        echo "cannot find $OCSETC/gmake2sh"
        exit 2
    fi
    for d in $OCSHOME/bin $OCSHOME/lib $OCSHOME/lib/opal_base $OCSHOME/lib/om $OCSHOME/lib/om/etc $OCSHOME/lib/om/specs $OCSHOME/lib/om/make $OCSHOME/packages $OCSHOME/man $OCSHOME/man/man1
    do
      if [ ! -d $d ] ; then
        mkdir $d
      fi
    done
    cp $OCSADMIN $OCSHOME/bin
    cp $OCSSRC/lib/System/Commands/_ostart.c $OCSHOME/lib/opal_base
    cp $OCSETC/gmake2sh $OCSHOME/lib/om/etc
    cp $SpecsDir/Specs.basic $OCSHOME/lib/om/specs
    $OCSHOME/lib/om/etc/gmake2sh < $OCSHOME/lib/om/specs/Specs.basic > $OCSHOME/lib/om/specs/ShSpecs.basic
    echo "$1" > $OCSHOME/VERSION

    echo package: basic administration for Opal installation > $OCSHOME/packages/basic
    echo version: $1 >> $OCSHOME/packages/basic
    echo installed `date` >> $OCSHOME/packages/basic

    echo "finished initialising of OCS installation"
    echo "you may add $OCSHOME/bin to your path"
    exit 0
fi

## for all other commands, read first the basic definitions

SpecsDir=no
for s in $OCSSPECS
do
    if [ -f $s/ShSpecs.basic ]; then
        . $s/ShSpecs.basic
    fi
done

## now interpret commands
case "$1" in
    install)
        shift
        INSTALLBINPATH=$OCSHOME/bin; export INSTALLBINPATH
        INSTALLDOCPATH=$OCSHOME/doc; export INSTALLDOCPATH
        INSTALLLIBPATH=$OCSHOME/lib; export INSTALLLIBPATH
        INSTALLMANPATH=$OCSHOME/man; export INSTALLMANPATH
        INSTALLBINFLAGS="-s -m 0555 -dm 0755"; export INSTALLBINFLAGS
        INSTALLDOCFLAGS="-m 0444 -dm 0755"; export INSTALLDOCFLAGS
        INSTALLLIBFLAGS="-m 0444 -dm 0755"; export INSTALLLIBFLAGS
        INSTALLMANFLAGS="-m 0444 -dm 0755"; export INSTALLMANFLAGS
        PATH=$OCSHOME/bin:$PATH; export PATH
        while [ -n "$1" ]
        do
            SourceSpecs $1
            CheckRequireds
            case "$1" in
                lib.*)
                    $ECHO "Installing library $1 ..."
                    $OCSOM/etc/genshlib -v $LIBVERSION -d "${LIBDEPS}" ${LIBSYSTEMS} ${LIBDIR}
                    # echo "now evaluating :${LIBHOOK}:"
                    eval ${LIBHOOK}
                    echo "ready"
                    echo library: $LIBDESCR > $OCSHOME/packages/$1
                    echo version: $LIBVERSION >> $OCSHOME/packages/$1
                    echo installed `date` >> $OCSHOME/packages/$1
                    shift 
                    ;;
                pkg.*)
                    $ECHO "Installing package $1 ..."
                    (   cd $PKGBASE
                        # echo "INSTALLBINPATH is $INSTALLBINPATH"
                        # echo "evaluating >$PKGPREHOOK<"
                        eval $PKGPREHOOK
                        if [ -z "$PKGHOOK" ]; then
                            # echo "PKGHOOK is empty"
                            ocs $PKGOCSFLAGS install
                        else    
                            # echo "evaluating PKGHOOK >$PKGHOOK<"
                            eval $PKGHOOK
                        fi
                        if [ -n "$PKGPOSTHOOK" ]; then
                            # echo "evaluating PKGPOSTHOOK >$PKGPOSTHOOK<"
                            eval $PKGPOSTHOOK
                        fi
                    )
                    echo package: $PKGDESCR > $OCSHOME/packages/$1
                    echo version: $PKGVERSION >> $OCSHOME/packages/$1
                    echo installed `date` >> $OCSHOME/packages/$1
                    shift
                    ;;    
                *)
                    $ECHO "don't know how to install $1"
                    exit 1
            esac
        done
        ;;
    info)
      echo "The following packages are installed: "
      echo `$LS $OCSHOME/packages/* | $SED -e s%$OCSHOME/packages/%%g`
      ;;
    checkdeps)
      shift
      SourceSpecs $1
      CheckRequireds
      echo "can be installed"
      ;;      
    ocs)
      shift
      opaltarget=""
      if [ "$1" = "-command" ]; then
        shift
        opaltarget="$opaltarget $1"
        shift
      fi
      PATH=$OCSHOME/bin:$PATH; export PATH
      while [ -n "$1" ]
        do
            SourceSpecs $1
            CheckRequireds
            case "$1" in
                lib.*)
                    opalcmd="ocs $LIBOCSFLAGS $opaltarget"
                    CINCPATH="$CINCPATH $LIBINCLUDES"
                    export CINCPATH
                    $ECHO "Doing '$opalcmd' on library $1 ..."
                    for d in $LIBSYSTEMS
                    do
                    echo "now in libsystem $d"
                    if [ -n "$LIBPREOCSHOOK" ] ; then
                      (cd $d; eval $LIBPREOCSHOOK)
                    fi  
                    (cd $d; $opalcmd); status=$?
                    if [ $status -gt 0 ] ; then exit $status; fi
                    done
                    shift
                    ;;
                pkg.*)
                    opalcmd="ocs $PKGOCSFLAGS $opaltarget"
                    $ECHO "Doing '$opalcmd' on package $1 ..."
                    if [ -n "$PKGPREOCSHOOK" ] ; then
                      (cd $PKGBASE; eval $PKGPREOCSHOOK)
                    fi  
                    (cd $PKGBASE; $opalcmd); status=$?
                    shift
                    ;;
                *)
                    $ECHO "Don't know how to do '$opalcmd' with $1"
                    exit 5
                    ;;
            esac
            if [ $status -gt 0 ] ; then exit $status; fi
        done
        ;;
    update_inter)			# Basically only for opal_base, oc_oc1, oc_oc2, oc_shared.
      shift
      opaltarget=""
      if [ "$1" = "-command" ]; then
        shift
        opaltarget="$opaltarget $1"
        shift
      fi
      PATH=$OCSHOME/bin:$PATH; export PATH
      while [ -n "$1" ]
        do
	    echo "BOOTING $1"
            SourceSpecs $1
            CheckRequireds
            case "$1" in
                lib.*)
                    opalcmd="ocs $LIBOCSFLAGS $opaltarget"
		    echo "OPALCMD $opalcmd"
                    CINCPATH="$CINCPATH $LIBINCLUDES"
                    export CINCPATH
                    $ECHO "Doing '$opalcmd' on library $1 ..."
                    for d in $LIBSYSTEMS
                    do
                        echo "now in libsystem $d"
                        if [ -n "$LIBPREOCSHOOK" ] ; then
                            (cd $d; eval $LIBPREOCSHOOK)
                        fi
                        (cd $d; rm -rf OCS; $opalcmd); status=$?
                        if [ $status -gt 0 ] ; then exit $status; fi

			# Now copy inter files to destination.
			# This code is basically from genshlib.sh
			sys=$d/OCS
			echo "SYS $sys"
			dest=$LIBDIR
			echo "DEST $dest"
                        structs="`( cd $sys; $LS *.sign.inter | \
                                 $SED -e 's@\([^ ][^ ]*\)\.sign.inter@\1@')`"
			for s in $structs
			do
			    if [ ! "$sys/$s.sign.inter" = "$dest/$s.sign.inter" ]
			    then
				echo Copying $sys/$s.sign.inter
				$RM -f $dest/$s.sign.inter
				cp -f $sys/$s.sign.inter $dest
				if [ -f $sys/$s.opt ]
				then
				    cp -f $sys/$s.opt $dest
				fi
				if [ -f $sys/$s.h ]
				then
				    cp -f $sys/$s.h $dest
				fi
				if [ -f $sys/$s.hc.h ]
				then
				    cp -f $sys/$s.hc.h $dest
				fi
			    fi
			done
                    done
                    shift
                    ;;
                *)
                    $ECHO "Don't know how to do '$opalcmd' with $1"
                    exit 5
                    ;;
            esac
            if [ $status -gt 0 ] ; then exit $status; fi
      done
      ;;
    *)
        usage
        exit 1
esac
  
exit 0
