#!/bin/sh
########################################################################
#                                                                      #
# jannet configuration shadow                                          #
# (c) 2000 jannet                                                      #
# Authors: Jan Lindemann                                               #
# contact@jannet.de                                                    #
# patches, bugfixes and comments are welcome at patch@jannet.de        #
#                                                                      #
# $Id$
#                                                                      #
# This program is free software; permission to use, copy, modify,      #
# distribute, and sell this software and its documentation under the   #
# terms of the GNU Public license as published by the Free Software    #
# Foundation, either version 2 or any later version of the license, is #
# hereby granted without fee, provided that (i) the above copyright    #
# notices and this permission notice appear in all copies of the       #
# software and related documentation, and (ii) the name of jannet may  #
# not be used in any advertising or publicity relating to the software #
# without the specific, prior written permission of jannet.            #
#                                                                      #
# This program is distributed in the hope that it will be useful, but  #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-  #
# TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General    #
# Public License for more details.                                     #
#                                                                      #
# You should have received a copy of the GNU General Public License    #
# along with this program; if not, write to the Free Software Founda-  #
# tion, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                  #
#                                                                      #
########################################################################


JCS_CONF_FILES="
    /etc/jcs/jcs.conf 
    /etc/jcs/jcs.mk
    /etc/jcs/templates/dir/module/Makefile
    /etc/jcs/templates/dir/src/Makefile
"

JCS_EXE_INSTALL_DIR=/usr/bin

txtout() {
	MARKER=$1
	MARKER="`echo $MARKER | sed -e 's/\//\\\\\//g'`"
	DELIM_START="-->>>-- $MARKER --"
	DELIM_END="--<<<-- $MARKER --"
	cat $SCRIPTNAME | 
		sed -n "/$DELIM_START/,/$DELIM_END/ p" |
		sed -n "1! p" |
		sed -n "\$! p"
}

usage() {
	txtout "global usage"
	txtout "commands"
	txtout "global usage 2"
}

eusage() {
	usage >&2
	exit 1
}

version() {
	txtout "jcs version" | sed -e s/Revision://g | 
				sed -e s/Date://g    |
				tr -d '$\047'        |
				tr -s ' '
}

checkroot() {
    if [ `whoami` != root ] ; then
	echo This function is only available to root. Exiting. >&2
	exit 1
    fi
}

get_file_attrib() {

	if [ ! -e "$1" ] ; then
		echo \"$1\" does not exist. Exiting. >&2
		exit 1
	fi

	case $2 in
	mode)
		PLACE=1;;
	owner)
		PLACE=3;;
	group)
		PLACE=4;;
	*)
		PLACE=-1;;
	esac

        ls -ld $1 | tr -s ' ' ' ' | cut -d' '  -f$PLACE
}

log() {
	echo $* | tee -a $cfg_jcs_log_dir/jcs.log
}

jcs_wipe() {
	checkroot
	echo "This will wipe the jcs executables and "
	echo "configuration files from this machine."

	echo -n "Are you shure you want to continue (y|n)? "

	while read ANSWER ; do
	    test $ANSWER != y -a $ANSWER != n && continue;
	    test $ANSWER = n && return
	    for FILE in $JCS_CONF_FILES ; do # $SCRIPTNAME 
		test ! -f $FILE && continue
		echo -n " + removing $FILE ... "
		rm -rf $FILE
		echo done
	    done
	    break
	done
}

jcs_init() {

usage() {
    txtout "usage init"
}

	TODO=0
	LOCAL_JCS_DIR=""

	checkroot
	set -- `getopt hc: $*`
	while [ $1 != -- ] ; do
	    case $1 in
	    -c)
		LOCAL_JCS_DIR=$2;
		test -d "$LOCAL_JCS_DIR" || {
			echo "\"$LOCAL_JCS_DIR\" is not a directory. Exiting." >$2
			exit 1
		}
		shift;;
	    -h)
		usage; exit 0;;
	    *)
		usage; exit 1;;
	    esac
	    shift
	done
	shift
	# --- be downward compatible >
	cat /etc/jcs/jcs.conf | cut -d\# -f1 | grep JNT_CONFDIR >/dev/null 2>&1
	if [ $? = 0 ] ; then
		txtout "old config warning"

		while echo -n "Are you shure you want to continue (y|n)? "; read ANSWER ; do
			test $ANSWER != y -a $ANSWER != n && continue;
			test $ANSWER = y && break
			echo "Coward!"
			exit 1
		done

		get_config

		CFG=/etc/jcs/jcs.conf
		echo "Saving old configuration to $CFG.oldstyle and creating new $CFG."

		mv $CFG $CFG.oldstyle

		txtout `basename $CFG` > $CFG

		echo "Changing configuration in $CFG:"
		$SCRIPTNAME setval $CFG jcs_dir "$JNT_CONFDIR"
		$SCRIPTNAME setval $CFG jcs_owner `get_file_attrib "$JNT_CONFDIR" owner`
		$SCRIPTNAME setval $CFG jcs_group `get_file_attrib "$JNT_CONFDIR" group`
		$SCRIPTNAME setval $CFG jcs_log_dir "/tmp/jcs/log"
		$SCRIPTNAME setval $CFG use_checksum `echo "$JNT_USE_CHECKSUM" | tr -s '[A-Z]' '[a-z]'`

		echo "Moving old /etc/jcs/jcs.mk to /etc/jcs/jcs.mk.oldstyle."
		mv /etc/jcs/jcs.mk /etc/jcs/jcs.mk.oldstyle
	fi
	if [ -f /usr/local/bin/jcs ]; then
		if [ $JCS_EXE_INSTALL_DIR != /usr/local/bin ]; then
			echo -n " + removing /usr/local/bin/jcs ... "
			rm /usr/local/bin/jcs
			echo done
		fi
	fi
	if [ -f /etc/jcs/jcs.mk ]; then
		echo -n " + removing /etc/jcs/jcs.mk ... "
		rm /etc/jcs/jcs.mk
		echo done
	fi
	# --- be downward compatible <
	# --- be downward compatible >
	if [ -f /etc/jcs/jcs.mk ] ; then
		MINOR=`$SCRIPTNAME -V | grep Version | cut -d. -f2 | cut -d" " -f1`
		test $MINOR -lt 50 && {
			test -f /etc/jcs/jcs.mk.autoinit || cp /etc/jcs/jcs.mk /etc/jcs/jcs.mk.autoinit
			rm -f /etc/jcs/jcs.mk
		}
	fi
	# --- be downward compatible <
	if [ $SCRIPTNAME -nt $JCS_EXE_INSTALL_DIR/jcs -o \
		! -e $JCS_EXE_INSTALL_DIR/jcs ] ; then
	    echo -n " + copying $SCRIPTNAME to $JCS_EXE_INSTALL_DIR ... "
	    mkdir -p $JCS_EXE_INSTALL_DIR
	    cp $SCRIPTNAME $JCS_EXE_INSTALL_DIR
	    chmod 755 $JCS_EXE_INSTALL_DIR/jcs
	    echo done
	else
	    echo Did not touch $JCS_EXE_INSTALL_DIR/jcs since it does not seem older than $SCRIPTNAME.
	fi
	for FILE in $JCS_CONF_FILES ; do
	    if [ ! -f $FILE ] ; then
		echo -n "creating $FILE "
		mkdir -p `dirname $FILE`
		if [ -n "$LOCAL_JCS_DIR" ] ; then
		    LOCAL_FILE=$LOCAL_JCS_DIR"`echo $FILE | sed -e s/\\\/etc\\\/jcs//`"
		    if [ -f $LOCAL_FILE ] ; then
			echo -n "from local ... "
			cp $LOCAL_FILE `dirname $FILE`
		    fi
		fi
		if [ ! -f $FILE ] ; then
		    echo -n "from default ... "
		    txtout "`basename $FILE`" > $FILE
		    test -s $FILE || txtout $FILE > $FILE
		fi
		echo done.
		TODO=1
	    elif [ $FILE -ot "$SCRIPTNAME" ] ; then
		echo $FILE is older than $SCRIPTNAME\!
		TODO=1
	    else
		echo Did not touch $FILE since it seems newer than $SCRIPTNAME.
	    fi
	done
	if [ "$TODO" = 1 ] ; then
	    echo You might want to revise the newly created or out-of-date files.
	fi
}

get_config() {

        if [ ! -f /etc/jcs/jcs.conf ] ; then
	    echo /etc/jcs/jcs.conf not found. >&2
	    echo Have you installed it or run "jcs init" yet? >&2
	    echo Exiting now. >&2
	    exit 1
	fi

	. /etc/jcs/jcs.conf

	VARS="`cat /etc/jcs/jcs.conf |
	    cut -d# -f1 |
	    grep = |
	    cut -d= -f1`"
	for VAR in $VARS ; do 
		eval cfg_$VAR=\$$VAR
		export cfg_$VAR
	done
}

# ==================== get.sh
jcs_get() {
usage() {
    txtout "usage get"
}

set -- `getopt ht: $*`
while [ ! "$1" = "--" ] ; do
        case $1 in
                -t) TEST=1 ; shift;;
                -h|*) usage; exit 0;;
        esac
done
shift

for FILE in $* ; do
        if [ ! -r $FILE ] ; then
                echo $FILE does not exist or not ready for reading. Exiting.
                test -z "$TEST" && exit 1
        fi
        if [ -z "$TEST" ] ; then
                cp $FILE .
                MODE="`ls -l $FILE | tr -s ' ' ' ' | cut -d' '  -f1`"
                OWNER="`ls -l $FILE | tr -s ' ' ' ' | cut -d' '  -f3`"
                GROUP="`ls -l $FILE | tr -s ' ' ' ' | cut -d' '  -f4`"
                echo $MODE $OWNER $GROUP > `basename $FILE`.prp 
        fi
done
}

# ==================== install.sh
jcs_install() {

LAST_LINE_MARKER="# THIS IS THE LAST LINE - readinf.sh stops here!"
TMP_INF_FILE=/tmp/readinf.tmp
TMP_SEC_FILE=/tmp/section.tmp
TMP_LIBS_FILE=/tmp/libs.tmp
DEFAULT_SEC_FILE=`dirname $0`/default_sec.inf

errorout() {
    echo $@ >&2
    exit 1
}

exec_scripts() {
  test -e $DEFAULT_SEC_FILE && . $DEFAULT_SEC_FILE
  . $TMP_SEC_FILE.$1
  test -n "$BCKPDIR" && BACKUP_DIR=$BCKPDIR
}

usage() {
  txtout "usage install"
}

# ================================================
# ============================ here we go!
# ================================================

set -- `getopt b:p:htf $*`
while [ ! "$1" = "--" ] ; do
  case $1 in
  -b)
  	BCKPDIR=$2
	shift;;
  -f)
  	FORCE=1;;
  -t)
  	TEST=1;;
  -p)
  	PREFIX=$2
	shift;;
  -h)
  	usage; exit 0;;
   *)
	usage; exit 1;;
   esac
shift
done
shift
	
INFFILE=$1

if [ ! "$INFFILE" ] ; then
  usage
fi

if [ ! `whoami` = root ] ; then
  errorout "$0 can only be executed by root!"
fi

WORKDIR="`pwd`"
if [ ! $# = 1 ] ; then
  for FILE in $@ ; do
    if [ ! `basename $FILE` = `basename $DEFAULT_SEC_FILE` ] ; then
      cd `dirname $FILE`       
      jcs install `basename $FILE` || exit $?
      cd $WORKDIR
    fi
  done  
fi
echo '====' processing file $1.

# ------------ determine relative and absolute paths
REL_INF_DIR=`dirname $INFFILE`
cd $REL_INF_DIR
INF_DIR="`pwd`"
# cd $WORKDIR
INFFILE="`basename $INFFILE`"

# ------------ delete comments
cat $INFFILE | cut -d\# -f1 > $TMP_INF_FILE   #delete comments
# ------------ set end mark
echo "$LAST_LINE_MARKER" >> $TMP_INF_FILE 
# ------------ get section names
SECTIONS="`cat $TMP_INF_FILE  | grep '\[' | cut -d\[ -f2 | cut -d\] -f1`"
FIRST_SECTION="`echo $SECTIONS | cut -d' ' -f1`"
# ------------ cut the 1st off
if [ "`echo $SECTIONS | wc -w`" -le 1 ] ; then
  SECTIONS=""
else
  SECTIONS="`echo $SECTIONS | cut -d' ' -f2-`"
fi

# ------------ first loop over all the sections (check the installation)
SECTION=$FIRST_SECTION
for NEXT_SECTION in $SECTIONS "$LAST_LINE_MARKER"; do 

  TODO=0

  # ------------ produce and execute shell script
#  COMMAND=x\\x"$SECTION"x,\\x"$NEXT_SECTION"x" "p
  COMMAND=/\\\[$SECTION\\\]/,/\\\[$NEXT_SECTION\\\]/" "p
#  echo \"$COMMAND\"
  cat $TMP_INF_FILE | sed -n  "$COMMAND" | grep -v "\[" | grep -v "$LAST_LINE_MARKER" > $TMP_SEC_FILE.$SECTION
  exec_scripts $SECTION

  # ------------ check installation variables
  if [ ! -d "$SOURCE_DIR" ] ; then
    errorout "The source directory \"$SOURCE_DIR\" doesn't exist!"; exit 1
  fi
  if [ "$BACKUP_DIR" ] ; then
    # if [ ! -d $BACKUP_DIR ] ; then
      # errorout "The backup directory \"$BACKUP_DIR\" doesn't exist!"; exit 1
    # fi
    if [ ! "$BACKUP_OWNER" ] ; then
      BACKUP_OWNER=$cfg_jcs_owner
    fi
    if [ ! "$BACKUP_GROUP" ] ; then
      BACKUP_GROUP=$cfg_jcs_group
    fi
  fi
  if [ -n "$PREFIX" ]; then
    TARGET_DIR=$PREFIX/$TARGET_DIR
  fi
  if [ ! -d "$TARGET_DIR" ] ; then
    if [ -z "$TARGET_DIR_MODE" ] ; then
	echo "Don't know how to create target directory \"$TARGET_DIR\". TARGET_DIR_MODE not specified."
 	exit 1
    fi
    if [ -z "$TARGET_DIR_OWNER" ] ; then
       echo "Don't know how to create target directory \"$TARGET_DIR\". TARGET_DIR_OWNER not specified."
       exit 1
    fi
  fi
  #  if [ "$LIB_DIR" ] ; then
      #if [ ! -d "$LIB_DIR" ] ; then
      # errorout "The library directory \"$LIB_DIR\" doesn't exist!" ; exit 1
     #fi
  #  fi

  rm $TMP_LIBS_FILE.$SECTION 2>/dev/null

  for FILE in $FILES ; do
    TARGETFILE="`echo $FILE | awk 'BEGIN {FS="->"}{print $2}'`"
    if [ -n "$TARGETFILE" ] ; then
       SOURCEFILE="`echo $FILE | awk 'BEGIN {FS="->"}{print $1}'`"
    else 
       TARGETFILE=$FILE
       SOURCEFILE=$FILE
    fi
    # echo TARGETFILE=$TARGETFILE,SOURCEFILE=$SOURCEFILE
    if [ ! -e $SOURCE_DIR/$SOURCEFILE ] ; then
      echo "The file $SOURCE_DIR/$SOURCEFILE doesn't exist!"; exit 1
      exit 1
    fi
    if [ $SOURCE_DIR/$SOURCEFILE -nt $TARGET_DIR/$TARGETFILE -o ! -e $TARGET_DIR/$TARGETFILE -o -n "$FORCE" ] ; then
      TODO=1
    fi

    if [ -n "$LIB_DIR" ] ; then
      LIBS="`ldd $SOURCE_DIR/$SOURCEFILE 2>/dev/null | grep -v 'not a dynamic executable' | awk '{print $3}' | grep -v $SOURCEFILE `"
      # the "dynamic exe" - stuff is a feature-workaround for linux ldd: doesn't output all error mess. to stderr
      for LIB_LONG in $LIBS ; do 
        if [ ! -e $LIB_LONG ] ; then
          echo $SOURCEFILE - $LIBS
          echo "The library file $LIB_LONG doesn't exist!"; exit 1
        fi

        LIB_SHORT=`echo $LIB_LONG | rev | cut -d/ -f1 | rev`
        if [ $LIB_LONG -nt $LIB_DIR/$LIB_SHORT -o -n "$FORCE" ] ; then
          TODO=1
          echo $LIB_LONG >> $TMP_LIBS_FILE.$SECTION
        fi
      done
    fi
  done

  # ------------ end check installation

  if [ $TODO = 0 ] ; then
    rm $TMP_SEC_FILE.$SECTION 2>/dev/null
    rm $TMP_LIBS_FILE.$SECTION 2>/dev/null
  fi

  SECTION="$NEXT_SECTION"
done

# ------------ second loop over all the sections (installation)
SECTION=$FIRST_SECTION
for NEXT_SECTION in $SECTIONS "$LAST_LINE_MARKER"; do 

  if [ ! -e $TMP_SEC_FILE.$SECTION ] ; then

    echo "---- Section [$SECTION] -- nothing to do! ----"

  else 

    # ------------ execute shell scripts
    exec_scripts $SECTION

    if [ -n "$PREFIX" ]; then
      TARGET_DIR=$PREFIX/$TARGET_DIR
    fi

    echo "---- Section [$SECTION] -- installing $INSTALLATION_SUBJECT ----" 
    echo "             ($SOURCE_DIR -> $TARGET_DIR)" 
   
    # ------------ create target directory if not yet existing
    if [ ! -d "$TARGET_DIR" ] ; then
      cd /
      DIR="`echo $TARGET_DIR | rev`"
      while [ ! $DIR = "." -a  ! $DIR = "/" ] ; do 
        CUR_DIR="`basename $DIR | rev`"
        if [ ! -d "$CUR_DIR" ] ; then
	  if [ -z "$TEST" ] ; then
             mkdir -m $TARGET_DIR_MODE $CUR_DIR
             chown $TARGET_DIR_OWNER.$TARGET_DIR_GROUP $CUR_DIR 2>/dev/null 
             echo created the subdirectory \"$CUR_DIR\"
	  else
	     echo would create the subdirectory \"$CUR_DIR\"
	  fi
        fi
        cd $CUR_DIR
        DIR=`dirname $DIR`
      done
      cd $INF_DIR
      if [ -n "$TEST" ] ; then
         echo created the target directory \"$TARGET_DIR\"
      else
         echo would have created the target directory \"$TARGET_DIR\"
      fi
    fi

    # ------------ copy the files
    for FILE in $FILES ; do
      TARGETFILE="`echo $FILE | awk 'BEGIN {FS="->"}{print $2}'`"
      if [ -n "$TARGETFILE" ] ; then
         SOURCEFILE="`echo $FILE | awk 'BEGIN {FS="->"}{print $1}'`"
      else 
         TARGETFILE=$FILE
         SOURCEFILE=$FILE
      fi
      if [ $SOURCE_DIR/$SOURCEFILE -nt $TARGET_DIR/$TARGETFILE -o ! -e $TARGET_DIR/$TARGETFILE -o -n "$FORCE" ] ; then
	if [ $BACKUP_DIR ] ; then
	  if [ ! -d $BACKUP_DIR ] ; then
	    test -z "$TEST" && mkdir -p $BACKUP_DIR
	    chown $BACKUP_OWNER.$BACKUP_GROUP $BACKUP_DIR 2>/dev/null 
	  fi
	  if [ -e $TARGET_DIR/$TARGETFILE ] ; then
	    if [ -z $TEST ] ; then
	        echo " + saving old file $TARGETFILE to $BACKUP_DIR/$SOURCEFILE"
	        mv -f $TARGET_DIR/$TARGETFILE $BACKUP_DIR/$SOURCEFILE
                chown $BACKUP_OWNER.$BACKUP_GROUP $BACKUP_DIR/$SOURCEFILE 2>/dev/null
		if [ -d $BACKUP_DIR/$SOURCEFILE ]; then
			tar -cjf $BACKUP_DIR/$SOURCEFILE.tar.bz2 $BACKUP_DIR/$SOURCEFILE
			# FIXME: make sure this doesn't delete root
			rm -rf $BACKUP_DIR/$SOURCEFILE
	        	chmod $BACKUP_MODE $BACKUP_DIR/$SOURCEFILE.tar.bz2 2>/dev/null
		else
	        	gzip -f $BACKUP_DIR/$SOURCEFILE
	        	chmod $BACKUP_MODE $BACKUP_DIR/$SOURCEFILE.gz 2>/dev/null
		fi
	    else
	        echo " + would save old file $TARGETFILE to $BACKUP_DIR/$SOURCEFILE"
	    fi
	  fi
	fi
	if [ -z "$TEST" ] ; then
		echo " + copying file $SOURCEFILE to $TARGET_DIR/$TARGETFILE"
		test -L $TARGET_DIR/$TARGETFILE && rm -f $TARGET_DIR/$TARGETFILE # better kill links
		cp -rf $SOURCE_DIR/$SOURCEFILE $TARGET_DIR/$TARGETFILE
		mkdir -p $cfg_jcs_log_dir
		echo $TARGET_DIR/$TARGETFILE >> $cfg_jcs_log_dir/changed_files.log
		chown $TARGET_OWNER.$TARGET_GROUP $TARGET_DIR/$TARGETFILE
		chmod $TARGET_MODE $TARGET_DIR/$TARGETFILE
	else
		echo " + would copy file $SOURCEFILE to $TARGET_DIR/$TARGETFILE"
      	fi
      fi

      if [ -s "$TMP_LIBS_FILE.$SECTION" ] ; then
        if [ "$LIB_DIR" ] ; then
          if [ ! -d "$LIB_DIR" ] ; then
	    if [ -z "$TEST" ] ; then
	         mkdir -p -m $LIB_DIR_MODE $LIB_DIR
        	 echo "created the lib directory \"$LIB_DIR\""
	    else
        	 echo "would create the lib directory \"$LIB_DIR\""
	    fi
          fi
        fi
        sort -u "$TMP_LIBS_FILE.$SECTION" |
          while read -r LIB_LONG ; do 
            LIB_SHORT=`echo $LIB_LONG | rev | cut -d/ -f1 | rev`
	    if [ -z "$TEST" ] ; then
		    echo "   - copying library $LIB_LONG to $LIB_DIR"
	            cp -f $LIB_LONG $LIB_DIR
		    chown $LIB_OWNER.$LIB_GROUP $LIB_DIR/$LIB_SHORT
        	    chmod $LIB_MODE $LIB_DIR/$LIB_SHORT
	    else
		    echo "   - would copy library $LIB_LONG to $LIB_DIR"
	    fi
          done
         rm $TMP_LIBS_FILE.$SECTION
      fi
    done
    rm $TMP_SEC_FILE.$SECTION
  fi
  SECTION="$NEXT_SECTION"

done
echo "---- Installation completed. ----" 

#TODO
rm -f $TMP_SEC_FILE. $TMP_INF_FILE 2>/dev/null
} # end function jcs_install

# ==================== install_source.sh
jcs_sinstall() {
INSTALLDIR=$cfg_jcs_dir/src
OWNER=$cfg_jcs_owner
GROUP=$cfg_jcs_group

usage() {
    txtout "usage sinstall" # TODO: never used
}

MYNAME=`basename $0`
ARCHIVE=$1

if [ ! -f "$ARCHIVE" ] ; then
	echo \"$ARCHIVE\" is not a regular file. Exiting.
	exit 1
fi

WD=`pwd`
PKGDIRNAME=`basename $WD`
echo  creating $INSTALLDIR/$PKGDIRNAME
mkdir -p $INSTALLDIR/$PKGDIRNAME
tar -zxf $ARCHIVE -C$INSTALLDIR/$PKGDIRNAME \
	--owner=$OWNER --group=$GROUP
cd $INSTALLDIR/$PKGDIRNAME
rm -f cur
ln -s `find . -maxdepth 1 -cmin -2 | grep -v Makefile | sed -e 's/\.\/\|\.$//g'` cur
# test -e Makefile || cp ../Makefile.template Makefile
#$JNT_JCSDIR/bin/prepare_directory.sh -t src .
jcs_newdir -t src .
make setup
chown -R $OWNER $INSTALLDIR
chgrp -R $GROUP $INSTALLDIR
} # end function jcs_sinstall

# ==================== make_srcpkg.sh
jcs_smake() {
#set -e

WD="`pwd`"
TARGET=$1
shift
SUBDIRS="$*"
test -z "$CONFIGURE" && CONFIGURE=configure

usage() {
	txtout "usage smake"
}

case $TARGET  in
	setup)
		for DIR in $SUBDIRS ; do
			set -e
			cd $DIR
			echo changing to directory $DIR
			./$CONFIGURE || {
				echo "$CONFIGURE does not exist. Exiting." >&2
				exit 1
			}
			if [ -f Makefile ] ; then make clean; fi
			make
			make install
			echo changing to directory $WD
			cd $WD
			set +e
		done
		;;
	install)
		for DIR in $SUBDIRS ; do
			make -C $DIR 
			make -C $DIR install
		done
		;;
	clean)
		for DIR in $SUBDIRS ; do
			make -C$DIR clean
		done
		;;
	*)
		usage
		;;
esac
} # end function jcs_make_srcpkg

# ==================== prepare_directory.sh
jcs_newdir() {
# ------------- constants
TEMPLATE_BASEDIR=/etc/jcs/templates/dir
MYNAME=`basename $0`

# ------------- default values
TEMPLATE=module

# ------------- functions
usage() {
	txtout "usage newdir"
}

# ------------- here we go
set -- `getopt t:h $*`
while [ ! "$1" = "--" ] ; do
case "$1" in
        -h)
                usage; exit 0;;
        -t)
		TEMPLATE="$2"; shift 2;;
        *)
                echo Unknown option $1. Exiting. >&2
                exit 1
esac
done
shift # get past --

if [ -z "$1" ] ; then
	usage
	exit 1
fi

TEMPLATE_DIR=$TEMPLATE_BASEDIR/$TEMPLATE
if [ ! -d "$TEMPLATE_DIR" ] ; then
	echo \"$TEMPLATE_DIR\" is not a directory. Exiting. >&2
	exit 1
fi

TARGETDIR="$1"

if [ ! -d "$TARGETDIR" ] ; then
	echo + creating directory \"$TARGETDIR\"
	mkdir -p "$TARGETDIR"
	if [ ! -d "$TARGETDIR" ] ; then
		echo could not create directory \"$TARGETDIR\". Exiting >&2
		exit 1	
	else
        	OWNR="`ls -ld "$TEMPLATE_BASEDIR" | tr -s ' ' | cut -d' ' -f3`"
		GRUP="`ls -ld "$TEMPLATE_BASEDIR" | tr -s ' ' | cut -d' ' -f4`"
		chown $OWNR $TARGETDIR
		chgrp $GRUP $TARGETDIR
	fi
fi

for FILE in `ls -d $TEMPLATE_DIR/* | grep -v CVS` ; do

	if [ ! -e $TARGETDIR/`basename $FILE` ]
		then echo + copying $FILE to $TARGETDIR
		cp $FILE $TARGETDIR
	fi
	
done
} # end function jcs_newdir

# ==================== config_add.sh
jcs_add() {

# ------------- constants
MYNAME=`basename $0`
WD="`/bin/pwd`"

# ------------- default values
MODE=GET_CONFIG

# ------------- functions
usage() {
	txtout "usage add"
}
#' reset vi fontification ... :->

ssh_wrapper() {

	ssh -n $TARGET_HOST "$@"
	if [ $? != 0 ] ; then
		echo "The secure shell connection could not be established. Exiting." >&2
		exit 1
	fi
}

cp_wrapper() {
	if [ "$1" = localhost ] ; then
		if [ "" ] ; then
			su - "$4" -c "cp -p $2 $3"
		else
			cp -p $2 $3
		fi
	else
		scp $1:$2 $3
	fi 
	
}
# ------------- get options
set -- `getopt b:hvl $*`
if [ "$?" != 0 ] ; then
	eusage
fi
while [ ! "$1" = "--" ] ; do
case "$1" in
	-b)
		CONFIG_BASEDIR="$2"
		shift 2;;
        -h)
                usage; exit 0;;
	-v)
		VERBOSE=1
		shift;;
        -l)
		MOVE_AND_LINK=1
		shift 1;;
        *)
                echo Unknown option $1. Exiting. >&2
                exit 1
esac
done
shift # get past --

# ---------- check for being root
#if [ "`whoami`" != root ] ; then
#	echo This program has to be executed by root. Exiting. >&2
#	exit 1
#fi

# ---------- rename input
test $# -ne 2 && eusage

FILE_LOCATION="$1"
MODULE="$2"
echo $FILE_LOCATION | grep ":" >/dev/null 2>&1
if [ $? = 0 ] ; then
	FILENAME="`echo $1 | cut -d: -f2`"
	TARGET_HOST="`echo $1 | cut -d: -f1`"
else
	FILENAME="$1"
	TARGET_HOST=localhost
	test `echo $FILENAME | cut -c1` != / && FILENAME=$WD/$FILENAME
fi

# ---------- check input

if [ -z "$CONFIG_BASEDIR" ] ; then
	if [ "$TARGET_HOST" != localhost ] ; then
		echo jcs_confdir has to be specified with remote files. Exiting. >&2
		exit 1
	fi
	if [ -z "$cfg_jcs_dir" ] ; then
		echo cfg_jcs_dir is not set and jcs_confdir has not been specified. Exiting. >&2
		exit 1
	fi
	CONFIG_BASEDIR="$cfg_jcs_dir"
fi
if [ "$TARGET_HOST" != localhost ] ; then
	ssh_wrapper "echo The ssh connection can be established. >/dev/null"
fi
if [ "`echo $CONFIG_BASEDIR | cut -c 1`" != / ] ; then
        usage
	echo CONFIG_BASEDIR has to be an absolute path name. Exiting. >&2
	exit 1
fi
if [ "`echo $FILENAME | cut -c 1`" != / ] ; then
        usage
	echo \"filename\" has to be an absolute path name. Exiting. >&2
	exit 1
fi

# ---------- here we go
CONFDIR=$CONFIG_BASEDIR/$MODULE
FILEBASE=`basename $FILENAME`
#cd `dirname $FILEBASE`
#SOURCEDIR=`pwd` 
SOURCEDIR="`dirname $FILENAME`"

mkdir -p $CONFIG_BASEDIR

if [ -e "$CONFDIR" -a ! -d "$CONFDIR" ] ; then
	echo \"$CONFDIR\" exists, but is not a directory. Exiting.
	exit 1
fi

TARGETDIR=`dirname $FILENAME`
#if [ ! -d $TARGETDIR ] ; then
#	echo $TARGETDIR is not a directory. Exiting.
#	exit 1
#fi


LINKFILEENTRY="link $FILEBASE $SOURCEDIR"
if test -r "$CONFDIR/new_link.sh" -a -n "`grep \"$LINKFILEENTRY\" $CONFDIR/new_link.sh 2>/dev/null`"; then
        echo Entry \"$LINKFILEENTRY\" already exists in $CONFDIR/new_link.sh. Exiting.
        exit 1
fi

#$JNT_LOCAL_SBINDIR/prepare_directory.sh $CONFDIR -t module || exit 1 
jcs_newdir $CONFDIR -t module || exit 1 
if [ -e $CONFDIR/$FILEBASE ] ; then 
	echo $CONFDIR/$FILEBASE exists! Exiting.
	exit 1
fi

# ------------------------ makeinf part >
if [ "$TARGET_HOST" = localhost ] ; then
	LSML="`ls -l $FILENAME`"
else
	LSML="`ssh_wrapper ls -l $FILENAME`"
fi
cd $CONFDIR
rm *.sec *.fil 2>/dev/null

UMOD="`echo $LSML | cut -d' ' -f1 | cut -c2-4 | sed -e s/-//g;`"
GMOD="`echo $LSML | cut -d' ' -f1 | cut -c5-7 | sed -e s/-//g;`"
OMOD="`echo $LSML | cut -d' ' -f1 | cut -c8-10| sed -e s/-//g;`"
MOD="u=$UMOD,g=$GMOD,o=$OMOD"
test -n "$DEF_NO_TARGET_WRITE_PERM" && \
    MOD="`echo $MOD | sed -e s/w//g;`"
			
OWNR="`echo $LSML | tr -s ' ' | cut -d' ' -f3`"
GRUP="`echo $LSML | tr -s ' ' | cut -d' ' -f4`"

# echo d=$TDIR f=$FILEBASE o=$OWNR g=$GRUP um=$UMOD gm=$GMOD om=$OMOD 
# ------------------------ makeinf part  <
if [ "$MOVE_AND_LINK" = 1 ] ; then
	mv $FILEBASE $CONFDIR
	echo + linking $CONFDIR/$FILEBASE -\> $SOURCEDIR/$FILEBASE
	cd $WD
	cd `dirname $FILENAME`
	ln -sf $CONFDIR/$FILEBASE
	if [ $? -gt 0 ] ; then
		echo mv failed! Exiting
		exit 1
	fi
else
	cp_wrapper $TARGET_HOST $FILENAME $CONFDIR $cfg_jcs_owner
fi
	
echo "$LINKFILEENTRY # properties: $OWNR $GRUP $MOD" >> $CONFDIR/new_link.sh 

OWNR=$cfg_jcs_owner
GRUP=$cfg_jcs_group
#chown -R $OWNR $CONFDIR
#chgrp -R $GRUP $CONFDIR
#chmod -R ug+rw $CONFDIR

} # end function jcs_add

# ==================== config_snapshot.sh
jcs_snapshot() {
# #/bin/bash

# ------------- constants
MYNAME=`basename $0`
WD="`/bin/pwd`"

# ------------- default values
MODE=GET_CONFIG

# ------------- functions
usage() {
    txtout "usage snapshot"
}
#' reset vi fontification ... :->

eusage() {
	usage
	exit 1
}

dump_conf_template() {
cat << EOF
#
# this is a sample configuration file for $MYNAME
#

[options]
HOSTNAME=$HOSTNAME
CONFIG_BASEDIR=$JNT_HOMEDIR/conf/$HOSTNAME.$DOMAINNAME/$OSVERSION

#[named]
#/etc/named.conf
#/var/named
#exclude slave
#exclude root.hint
EOF
}

get_conf_sec() {
        SECTION="$1"
        cat "$2" |
                cut -d\# -f1 |
                tr -s '\n' '\n' |
                sed -n "/\[$SECTION\]/,/\[/ p" |
                grep -v '\['
}
                     
ssh_wrapper() {

	ssh -n $HOSTNAME "$@"
	if [ $? != 0 ] ; then
		echo "The secure shell connection could not be established. Exiting." >&2
		exit 1
	fi
}
# ------------- get options
set -- `getopt dhvt: $*`
if [ "$?" != 0 ] ; then
	eusage
fi
while [ ! "$1" = "--" ] ; do
case "$1" in
        -h)
                usage; exit 0;;
	-d)
		VERBOSE=1
		DEBUG=1
		shift;;
	-v)
		VERBOSE=1
		shift;;
        -t)
		HOSTNAME="$2"
		MODE=DUMP_TEMPLATE
		shift 2;;
        *)
                echo Unknown option $1. Exiting. >&2
                exit 1
esac
done
shift # get past --

# ---------- check for being root
if [ "`whoami`" != root ] ; then
	echo This program has to be executed by root. Exiting. >&2
	exit 1
fi

# ---------- handle dump template mode
if [ "$MODE" = DUMP_TEMPLATE ] ; then

	ssh_wrapper "echo The ssh connection can be established. >/dev/null"
	HOSTNAME="`ssh_wrapper 'hostname' | cut -d. -f1`"
	DOMAINNAME="`ssh_wrapper 'dnsdomainname'`"
	OSVERSION="`ssh_wrapper 'uname -s'`-`ssh_wrapper 'uname -r'`"
	OSVERSION="`echo $OSVERSION | tr -t '[A-Z]' '[a-z]'`"
	dump_conf_template
	exit 0
fi

# ---------- read config file
if [ ! -r "$1" ] ; then
	echo \"$1\" is not a readable configuration file. Exiting >&2
	exit 1
fi

CONFFILE="$1"
eval "`get_conf_sec options $CONFFILE`"

# ---------- check configuration
ssh_wrapper "echo The ssh connection can be established. >/dev/null"
if [ `echo $CONFIG_BASEDIR | cut -c1` != / ] ; then
	echo CONFIG_BASEDIR has to be an absolute path name. Exiting. >&2
	exit 1
fi

# ---------- here we go
cd "`dirname $CONFFILE`"
CONFFILE="`/bin/pwd`/$CONFFILE"
mkdir -p $CONFIG_BASEDIR
cd $CONFIG_BASEDIR

MODULES="`cat $CONFFILE |
	cut -d\# -f1 |
	grep '\['      |
	cut -d\[ -f2 |
	cut -d\] -f1 |
	grep -v options`"

[ "$DEBUG" ] && echo The modules are \>$MODULES\<

# ----- main loop
for MOD in $MODULES ; do

	[ "$DEBUG" ] && echo processing module \"$MOD\":
	# [ "$DEBUG" ] && get_conf_sec $MOD $CONFFILE 

	TDIR=$CONFIG_BASEDIR/$MOD
	mkdir -p $TDIR

	EXCLUDE="`get_conf_sec $MOD $CONFFILE | 
		grep exclude | 
		cut -d' ' -f2 |
		tr -s ' '`"
	EXCLUDE="`echo $EXCLUDE | sed -e 's/ /\\\|/g'`" 
	test -z "$EXCLUDE" && EXCLUDE='*'

	get_conf_sec $MOD $CONFFILE |
		while read LINE ; do
			if [ -z "`echo $LINE | grep exclude`" ] ; then
				PATHNAME=`echo $LINE | cut -d' ' -f1`
				for FILE in `ssh_wrapper "find $PATHNAME -type f" | grep -ve "$EXCLUDE"` ; do
					[ "$VERBOSE" ] && echo processing $FILE ...
					# scp $HOSTNAME:$FILE $TDIR
#					$JNT_JCSDIR/bin/config_add.sh $HOSTNAME:$FILE $MOD -b $CONFIG_BASEDIR
					config_add $HOSTNAME:$FILE $MOD -b $CONFIG_BASEDIR
				done
			else
				[ "$DEBUG" ] && echo found exclude statement $LINE
			fi
		done
done

# ---------- save the snapshot definition file
SNAPLINKNAME=last-snapshot
mkdir -p $CONFIG_BASEDIR/snapshot
rm -f $CONFIG_BASEDIR/snapshot/$SNAPLINKNAME
NEW_SNAPSHOT=`basename $CONFFILE`-`date +'%Y%m%d-%H%M%S'`
cp -p $CONFFILE $CONFIG_BASEDIR/snapshot/$NEW_SNAPSHOT
cd $CONFIG_BASEDIR/snapshot 
ln -s $NEW_SNAPSHOT $SNAPLINKNAME
} # end function snapshot

# ==================== makeinf.sh
jcs_makeinf() {

DEF_NO_TARGET_WRITE_PERM=1
DEF_BACKUP_GROUP=$cfg_jcs_group
DEF_BACKUP_MODE=660
DEF_LOCAL_GROUP=$cfg_jcs_group
DEF_LOCAL_OWNER=$cfg_jcs_owner

if [ "$1" ] ; then
	if [ ! -d "$1" ] ; then
		echo \"$1\" is not a directory. Exiting. >&2
		exit 1
	fi
	CONFIG_BASEDIR="$1"
elif [ ! -d "$cfg_jcs_dir" ] ; then
	echo \"cfg_jcs_dir\" not set to a valid directory. Exiting.
	exit 1
else
	CONFIG_BASEDIR=$cfg_jcs_dir
fi

cd $CONFIG_BASEDIR


LINKFILES="`find . -name new_link.sh`"
test -z "$LINKFILES" && exit 0
echo creating .inf-files...
for LINKFILE in $LINKFILES ; do
	DIR="`dirname $LINKFILE`"
	cd $DIR
	rm *.sec *.fil 2>/dev/null
	echo +++ in $DIR...
	cat new_link.sh |
		while read -r LINE ; do

			TDIR="`echo $LINE | cut -d' ' -f3`"
			FILE="`echo $LINE | cut -d' ' -f2`"
			
			if [ -n "`echo $LINE | grep properties:`" ] ; then

				PROPS="`echo $LINE | awk 'BEGIN {FS="properties:"} {print $2}'`" 
				OWNR="`echo $PROPS | tr -s ' ' | cut -d' ' -f1`"
				GRUP="`echo $PROPS | tr -s ' ' | cut -d' ' -f2`"
				MOD="`echo $PROPS | tr -s ' ' | cut -d' ' -f3`"

			else

				OWNR="`ls -l $FILE | tr -s ' ' | cut -d' ' -f3`"
				GRUP="`ls -l $FILE | tr -s ' ' | cut -d' ' -f3`"
				UMOD="`ls -l $FILE | cut -d' ' -f1 | cut -c2-4 | sed -e s/-//g;`"
				GMOD="`ls -l $FILE | cut -d' ' -f1 | cut -c5-7 | sed -e s/-//g;`"
				OMOD="`ls -l $FILE | cut -d' ' -f1 | cut -c8-10| sed -e s/-//g;`"
				MOD="u=$UMOD,g=$GMOD,o=$OMOD"

			fi


			test -n "$DEF_NO_TARGET_WRITE_PERM" && \
			        MOD="`echo $MOD | sed -e s/w//g;`"
			

			SUBJ="`echo $TDIR | sed -e 's/\//_/g;'`"
			echo $SUBJ 
			echo -n "$FILE " >> $SUBJ.fil

			echo \[$SUBJ\] > $SUBJ.sec
			echo INSTALLATION_SUBJECT=\"$SUBJ\" >> $SUBJ.sec
			echo SOURCE_DIR=\$INF_DIR >> $SUBJ.sec
			echo TARGET_DIR=$TDIR >> $SUBJ.sec
			echo TARGET_OWNER=$OWNR >> $SUBJ.sec
			echo TARGET_GROUP=$GRUP >> $SUBJ.sec
			echo TARGET_MODE=$MOD >> $SUBJ.sec
			echo BACKUP_GROUP=$DEF_BACKUP_GROUP >> $SUBJ.sec
			echo BACKUP_MODE=$DEF_BACKUP_MODE >> $SUBJ.sec
			echo BACKUP_DIR=\$INF_DIR/trash >> $SUBJ.sec

			echo $TDIR/$FILE >> old_links.txt
			
			#chown $DEF_LOCAL_OWNER $FILE
			#chgrp $DEF_LOCAL_GROUP $FILE
			
			# echo d=$TDIR f=$FILE o=$OWNR g=$GRUP um=$UMOD gm=$GMOD om=$OMOD 
		
		done

		for SUBJ_SEC in `ls *.sec` ; do

			INF=new_`basename $DIR`.inf
			SUBJ="`echo $SUBJ_SEC | rev | cut -d. -f2- | rev`"
			FILES="`cat $SUBJ.fil`"
			cat $SUBJ_SEC >> $INF
			echo FILES=\"$FILES\" >> $INF 
			echo >> $INF
		done

		rm *.sec *.fil 2>/dev/null
		rm new_link.sh

		#echo The following links are obsolete now:
		#cat old_links.txt | awk '{print " + " $0}'
		#echo -n 'Do you want them removed (yes|no)? '
		#while read -r ANSW && test ! "$ANSW" = yes -a ! "$ANSW" = no ; do 
		#	echo -n "" 
		#done
		ANSW=yes
		if [ "$ANSW" = yes ] ; then 
			
			for FILE in `cat old_links.txt` ; do
				if [ -L $FILE ] ; then 
					echo + removing $FILE
					rm $FILE
				else
					echo + $FILE is not a link. Did not remove it. >&2
				fi
			done
			echo It is recommended that you check $INF.
		
			#echo -n "Do you want \"make install\" to be issued " 
			#echo -n "now to reinstall the files? "
			#
			#while read -r ANSW && test ! "$ANSW" = yes -a ! "$ANSW" = no ; do 
			#	echo -n "" 
			#done
			#test "$ANSW" = yes && make install
			
		else
			echo It is recommended that you do this yourself.
		fi

		rm -f old_links.txt

	cd $CONFIG_BASEDIR

done
} # end function makeinf

# ==================== setval.sh
jcs_setval() {

usage() {
    txtout "usage setval"
}

NO_QUOTES=0
set -- `getopt hn $*`
while [ $1 != -- ] ; do
    case $1 in
    -n)
	NO_QUOTES=1;;
    -h)
	usage; exit 0;;
    *)
	usage; exit 1;;
    esac
    shift
done
shift

if [ $# -lt 3 ] ; then
	usage
	exit 0
fi
if [ ! -e "$1" ] ; then
	echo $1 not found. Exiting.
	exit 1
fi
if [ ! -w "$1" ] ; then
	echo $1 is not a writable file. Exiting.
	exit 1
fi


MYNAME=`basename $0`
WD=`/bin/pwd`
DATE=`date`
FILE=$1
KEY=$2
shift 2
VALUES="$*"
test -e "$FILE".$MYNAME && rm "$FILE".$MYNAME
grep "$KEY" "$FILE" >/dev/null 2>&1 || cat << EOF >> "$FILE"
#
# added by $MYNAME on $DATE
# called from within $WD
#
$KEY="dummy"

EOF

if [ -n "` echo "$VALUES" | grep -e ' \|\t'`" -a "$NO_QUOTES" != 1 ] ; then
	# put multi-word value in quotes 
	# but delete all quotes before so we don't end up
	# with a ""quotation"".
	VAL=\"`echo $VALUES | tr -d "\""`\"
else
	VAL="$VALUES"
fi

echo -n " + $FILE: set $KEY to $VAL ... "


awk '
BEGIN    {
	FS = "="
} 
{
	left=$1
	sub(/^ */,"",left)
	sub(/ *$/,"",left)
	if (left == key) { 
		if ($2$3$4$5$6$7$8$9$10$11$12$13$14$15$16 != val) { 
    			print key"="val >> outfile  
			changed = changed $2 "-->" val" "
			++occ
			next 
		} 
	}
	{ 
		print >> outfile 
	}
}
END	{
	print "changed " (occ ? occ " occurence: " changed : "nothing."); 
     	exit occ
} ' \
	key="$KEY" val="$VAL" outfile="$FILE.$MYNAME" "$FILE"

if [ ! $? = 0 ] ; then
	mv "$FILE".$MYNAME "$FILE"
	mkdir -p $cfg_jcs_log_dir
	echo "$FILE" >> $cfg_jcs_log_dir/changed_files.log
else
	rm "$FILE".$MYNAME
fi
} # end function jcs_setval

# ==================== setvals
jcs_setvals() {

MYNAME=`basename $0`
TMPFILE=/tmp/missing_keys.$MYNAME
DATE=`date`
WD=`/bin/pwd`

# ------------- functions
usage() {
    txtout "usage setvals"
}

eusage() {
	usage
	exit 1
}

if [ $# != 2 ] ; then
	eusage
fi
if [ ! -e "$1" ] ; then
	echo $1 not found. Exiting.
	exit 1
fi
if [ ! -f "$2" ] ; then
	echo $2 is not a regular file. Exiting.
	exit 1
fi
if [ ! -w "$1" ] ; then
	echo $1 is not a writable file. Exiting.
	exit 1
fi

rm -f $TMPFILE
cat $2 | cut -d\# -f1 | sed -e 's/=/ /' |
while read KEY VAL; do
	test -n "$KEY" && (grep "$KEY" $1 >/dev/null 2>&1 ||\
		echo $KEY=\"dummy\" >> $TMPFILE)
done

if [ -f $TMPFILE ] ; then
cat << EOF >> $1

#
# missing keys inserted by $MYNAME
# on $DATE
# from $WD
#
EOF

cat $TMPFILE >> $1
fi

cat $2 | cut -d\# -f1 | sed -e 's/=/ /' |
while read KEY VAL; do
	if test -n "$KEY" ; then
		jcs_setval $1 $KEY "$VAL"
	fi
done
}

# ==================== mkdirs
jcs_mkdirs() {

PREFIX=""
WD=`pwd`

usage() {
    txtout "usage mkdirs"
}

eusage() {
	usage
	exit 1
}

# ------------- get options
set -- `getopt p:h $*`
if [ "$?" != 0 ] ; then
	eusage
fi
while [ ! "$1" = "--" ] ; do
case "$1" in
        -h)
                usage; exit 0;;
        -p)
                PREFIX="$2"; shift 2;;
        *)
                echo Unknown option $1. Exiting. >&2
                exit 1
esac
done
shift # get past --

if [ $# != 1 ] ; then
	eusage
fi
if [ ! -f "$1" ] ; then
	echo $1 is not a regular file. Exiting.
	exit 1
fi
if [ -n "$PREFIX" -a ! -d "$PREFIX" ] ; then
	echo \"$PREFIX\" is not a directory. Exiting. >&2
	exit 1
else
	echo changing to directory \"$PREFIX\"
	cd $PREFIX
fi

cat $WD/$1 | cut -d\# -f1 |
while read DIR USER GROUP MODE ; do
	if [ -n "$MODE" ] ; then
		echo -n Creating directory $DIR ..." "
		mkdir -p $DIR
		chown $USER $DIR
		chgrp $GROUP $DIR
		chmod $MODE $DIR
		echo done.
	fi
done

}

# ==================== useradd
jcs_useradd() {

usage() {
    txtout "usage useradd"
}

eusage() {
	usage
	exit 1
}

test "`whoami`" = root || {
	echo "This program has to be executed by root. Exiting." >&2
	exit 1
}

set -- `getopt hu:g: $*`
while [ $1 != -- ] ; do
	case $1 in
	-u)
		USERFILE=$2
		test -r "$USERFILE" || {
			echo "\"$USERFILE\" is not a readable file. Exiting." >$2
			exit 1
		}
		shift;;
	-g)
		GROUPFILE=$2
		test -r "$GROUPFILE" || {
			echo "\"$GROUPFILE\" is not a readable file. Exiting." >$2
			exit 1
		}
		shift;;
	-h)
		usage; exit 0;;
	*)
		usage; exit 1;;
	esac
	shift
done
shift

for CMD in which useradd groupadd ; do
	test -z "`which $CMD 2>/dev/null`" && {
		echo $CMD not found. Exiting. >&2
		exit 1
	}
done

if [ $# != 1 ] ; then
	eusage
fi
if [ ! -f "$1" ] ; then
	echo $1 is not a regular file. Exiting.
	exit 1
fi

cat $1 |

while read CMD ARG1 ARG2 ARG3 ARG4 ARG5 ARGN ; do
	NEWGRPS=""
	case "$CMD" in
		USER)
			test -n "$USERFILE" && grep -e "^ *$ARG1 *$" $USERFILE >/dev/null || continue
			if ! grep -e "^$ARG1:" /etc/passwd >/dev/null 2>&1 ; then 
				echo -n adding user $ARG1, uid $ARG2, dir $ARG3, \
					groups $ARG4 $ARG5 $REST ..." "
				#GRPS=`echo "$ARG4 $ARG5 $ARGN $REST" | tr "\t" " " | tr -s ' ' | 
				#	sed -e 's/ $//' | sed -e 's/ /,/g' | tr -d " \n\r\t"`
				for NEWGRP in $ARG4 $ARG5 $ARGN $REST; do
					NEWGRP=$NEWGRP
					if [ -n "$GROUPFILE" ]; then
						grep -e "^ *$NEWGRP *$" $GROUPFILE >/dev/null || continue
					fi
					NEWGRPS="$NEWGRPS,$NEWGRP"
				done
				NEWGRPS=`echo $NEWGRPS | sed -e 's/^ *,//'`
				useradd -u $ARG2 -d $ARG3 -g $ARG4 -G $NEWGRPS $ARG1
				[ -d $ARG3 ] || {
					mkdir -p $ARG3/dat $ARG3/local
					chown $ARG1 $ARG3 $ARG3/dat $ARG3/local
					chgrp $ARG4 $ARG3 $ARG3/dat $ARG3/local
				}
				echo done
			else 
				echo -n user $ARG1 already exists on this system
				NEWGRPS=""
				OLDGRPS=`groups $ARG1 | cut -d: -f2` 
				for NEWGRP in $ARG4 $ARG5 $ARGN $REST ; do
					test -n "$GROUPFILE" && grep -e "^ *$NEWGRP *$" $GROUPFILE >/dev/null || continue
					if ! echo $OLDGRPS | tr " " "\n" |
                                                         grep -e "^$NEWGRP$" >/dev/null 2>&1 ; then
						NEWGRPS="$NEWGRPS $NEWGRP"
					fi
				done
				if [ -n "$NEWGRPS" ] ; then
					echo
					echo "   but adding him to group(s) $NEWGRPS"
					usermod -G "`echo $OLDGRPS $NEWGRPS | tr -s ' ' |
							sed -e 's/^ \| $//' | 
							tr ' ' ','`" $ARG1
				else
					echo " - skipping"
				fi
			fi
			;;
		GROUP)
			test -n "$GROUPFILE" && grep -e "^ *$ARG1 *$" $GROUPFILE >/dev/null || continue
			if ! grep -e "^$ARG1:" /etc/group >/dev/null 2>&1 ; then 
				echo adding group $ARG1, gid $ARG2
				groupadd $ARG1 -g $ARG2
			
			else 
				echo group $ARG1 already exists on this system - skipping
			fi
			;;
		*)
			;;
	esac
done

}

jcs_touch() {
	touch $1
	chown $cfg_jcs_owner $1
	chgrp $cfg_jcs_group $1
}

jcs_fetch() {
	local cvs_dir=`echo $cfg_jcs_dir | sed 's%/conf/.*%%'`
	local cvs_mod=`echo $cfg_jcs_dir | sed 's%.*/conf/%conf/%'`
	if [ "$cvs_dir" -a "$cvs_mod" ]; then
		(
			mkdir -p $cvs_dir || return 1
			cd $cvs_dir 
			cvs checkout -P $cvs_mod || return 1
			cd $cvs_mod
		)
	fi
}

jcs_setup() {
	test -d "$cfg_jcs_dir" && {
		(
			cd $cfg_jcs_dir
			make setup
		)
	}
}

# ===================== This is jcs

SCRIPTNAME=$0

test -z "$1" && eusage

while test -n "$1" ; do
	if test "`echo $1 | cut -c1`" != - ; then
		break
	fi
	case $1 in
		-h)
			usage
			exit 0;;
		-V)
			version
			exit 0;;
		-q)
			GLOB_OPT_QUIET=1
			exit 0;;
		-v)
			GLOB_OPT_VERBOSE=1
			exit 0;;
		*)
			echo unknown option $1. Exiting. >&2
			eusage 1;;
	esac
	shift
done

txtout commands | grep $1 >/dev/null
if test $? != 0 ; then
	echo \"$1\" is not a known command. >&2
	eusage
fi

if [ "`echo $@ | cut -d' ' -f1`" != init ] ; then
    get_config
fi

CMD=$1
shift

jcs_$CMD "$@" || exit 1

exit 0

-->>>-- commands --
	init
	wipe
	add
        get
	install
	sinstall
	smake
	makeinf
	newdir
	setval
	setvals
	mkdirs
	useradd
	touch
	setup
	fetch
--<<<-- commands --

-->>>-- global usage --

usage: jcs [global_opts] command [command_opts]

where global_opts is out of

  	-h		: display this help screen
	-v		: be verbose about what is done
	-q		: work in silence
	-V              : display version number and exit

command is one of

--<<<-- global usage --

-->>>-- global usage 2 --

Most of the commands understand the option -h and 
display a usage message explaining its meaning.

--<<<-- global usage 2 --

-->>>-- jcs version --
Jannet Configuration Shadow
Version '$Revision$' - '$Date$' 
(c) 2000, 2001 jannet it services
--<<<-- jcs version --

-->>>-- usage init --
usage: jcs init [-h] [-c jcs_config_source_dir]

jcs init is used to create the directory tree under /etc/jcs
which is necessary for jcs to work correctly. In this 
directory structure the files jcs.conf, where some variables 
are set and jcs.mk, the standard makefile that is included 
in most makefiles in the jcs, can be found. Also, in the 
subdirectory "templates", there are template directories that 
are used by "jcs newdir" and "jcs add" upon creation of a new 
module directory. "jcs add" searches for a template directory 
"module" by default.

if -c jcs_config_source_dir is specified, the relevant files under 
jcs_config_source_dir are copied to /etc/jcs. For relevant files 
that are not present under jcs_config_source_dir, a default version 
is created.
--<<<-- usage init --

-->>>-- usage add --

	jcs add is used to add a file from either the local or a remote 
	machine to the jannet configuration shadow (jcs). 

	usage: 
		jcs add [-lv] [-b jcs_basedir] [hostname:]filename module
		jcs add -h

	-b jcs_basedir: 
		use jcs_basedir/module rather than cfg_jcs_dir/module 
		(as specified in /etc/jcs/jcs.conf) for storing the file. 
		This option is mandatory if hostname is specified.
	-h: 	show this usage message
	-v:	run in verbose mode
	-l:	move the file to the jcs rather than just copy it.
		Substitute the original file with a symbolic link to 
		its new location (only available if hostname is not 
		specified).

	see also:

		jcs makeinf for automatically creating .inf information files
	
--<<<-- usage add --

-->>>-- usage snapshot --

	jcs snapshot is used to store the configuration
	of a given machine into a jannet configuration 
	shadow (jcs) directory tree. The connection
	to the given machine is set up via ssh. Thus, 
	if you don't want to enter passwords many times
	it is recomendable that you set up a passwordless
	login from this host to the target machine.

	usage: 
		jcs snapshot [-v] configfile
		jcs snapshot -h
		jcs snapshot [-v] -t hostname

	-h: 	shows this usage message
	-v:	verbose
	-t:	writes a template for a configuration
		file to standard output. It is attempted
		to establish a connection to hostname as 
		root via ssh.

--<<<-- usage snapshot --

-->>>-- usage install --

jcs install installs files according to an installation
description in a .inf file

	usage:
		jcs install .inf-file [-h] [-f] [-t] [-b backup-dir]

	-b dir:	make a backup into directory dir

	-f:	force an installation, irrespective of the
		files' modification dates. If this option
		is not present, jcs overwrites destination files
		only when the source file is newer than the
		destination

	-p prefix: prepend target directories with prefix

	-t:	test mode (don't actually install anything, but log
		what would be installed)

--<<<-- usage install --

-->>>-- usage smake --
usage: jcs smake: {install|setup|clean} subdirs...
--<<<-- usage smake --

-->>>-- usage sinstall --
usage: jcs sinstall tar.gz-archive
--<<<-- usage sinstall --

-->>>-- usage makeinf --
	jcs makeinf looks for files named new_link.sh under 
	the directory specified by JCS_CONFDIR in /etc/jcs/jcs.conf.
	it then transforms the contents of these files into 
	.inf - files.
--<<<-- usage makeinf --

-->>>-- usage newdir --
usage: jcs newdir [-h] [-t template_directory] target_directory
--<<<-- usage newdir --

-->>>-- usage setval --
usage  : jcs setval [-n] config-file key value
options: -n:  don't put quotation marks around a multiword value
--<<<-- usage setval --

-->>>-- usage setvals --
usage : jcs setvals config-file template-file
--<<<-- usage setvals --

-->>>-- usage mkdirs --

usage : jcs mkdirs [-p prefix] config-file

jcs mkdirs is used to create some directories, as specified in
config-file. Each line in config-file describes one directory 
to be created. It consists of 4 words, in the order:

	NAME USER GROUP MODE

which have the obvious meanings.
Everything on the right hand side of a # sign is ignored.

If a prefix is specified with -p, all directories that don't
start with a "/" character, will be created relative to the
directory specified by prefix. The directory specified by 
prefix will not be created, it has to exist beforehand, other-
wise jcs will display an error message and quit.
--<<<-- usage mkdirs --

-->>>-- usage useradd --

usage : jcs useradd [-u user-file] [-g group-file] config-file

jcs useradd is used to add users and groups to the system. 
Each line in config-file describes either a user to be added
or a group to be added. If a user or a group already exists on 
the system neither is their id changed nor are users removed 
from groups. They are added, however if this is specified by
an entry in config-file.

Lines in config file start either with the word "USER" or with
the word "GROUP" and have the following formats:

	USER  username  uid homedir group [group ...]
	GROUP groupname gid	

Everything on the right hand side of a # sign is ignored.

If user-file is specified, only users listed in user-file will be
added. If group-file is specified, only groups listed in
group-file will be added. The lines in these files must contain
one entry each.

--<<<-- usage useradd --

-->>>-- usage get --
usage: jcs get [-t] files ...
       jcs get [-h]
--<<<-- usage get --

-->>>-- jcs.mk --
SHELL = /bin/sh

WD            := $(shell pwd)
MOD           := $(shell pwd | xargs basename)
LOG_DIR       := $(shell . /etc/jcs/jcs.conf; echo $$jcs_log_dir)
INSTALL_LOG   := $(LOG_DIR)/install.log
SETUP_LOG     := $(LOG_DIR)/setup.log
TEE           := /usr/bin/tee
BINDIR        := /usr/local/bin
SBINDIR       := /usr/local/bin
INF           := $(wildcard *.inf)
INF_DONE      := $(addsuffix .done,$(basename $(INF)))
INF_SU_DONE   := $(addsuffix .su_done,$(basename $(INF)))
JCS_HTTP_PATH := $(shell . /etc/jcs/jcs.conf; echo $$jcs_http_path)

export SETUP_LOG INSTALL_LOG TEE BINDIR SBINDIR

all:

define recurse_subdirs
	@set -e ;\
	TARGET=$@ ;\
	N="`echo $(SUBDIRS) | wc -w`" ;\
	I=1 ;\
	while [ $$I -le $$N ] ; do \
		SUBDIR="`echo $(SUBDIRS) | cut -d' ' -f$$I`" ;\
		$(MAKE) -C $$SUBDIR $$TARGET;\
		I=`expr $$I + 1`;\
	done
endef

%.done: %.inf
	sudo jcs install $<
	touch $@

%.su_done: %.inf
	sudo jcs install -b setup -f $<
	touch $@

install_inf: $(INF_DONE)

install_inf.old: checkroot checkdirs
	@echo "####" checking installation information files ... ;\
	if [ -n "`find . -name '*.inf' -maxdepth 1`" ] ; then \
		sudo jcs install *.inf ;\
	fi |  $(TEE) -a $(INSTALL_LOG)

install_link:

install_link.old: checkroot checkdirs
	@echo "####" checking link information files ... ;\
	if [ -e link.sh ] ; then \
		jcs linkout link.sh -b install ;\
	fi | $(TEE) -a $(INSTALL_LOG)

setup_inf: $(INF_SU_DONE)

setup_inf.old: checkroot checkdirs
	@echo "####" checking installation information files ... ;\
	if [ -n "`find . -name '*.inf' -maxdepth 1`" ] ; then \
		sudo jcs install -b setup -f *.inf ;\
	fi | $(TEE) -a $(SETUP_LOG)

setup_link: checkroot checkdirs
	@echo "####" checking link information files ... ;\
	if [ -e link.sh ] ; then \
		jcs linkout -f -b setup link.sh ;\
	fi | $(TEE) -a $(SETUP_LOG)

test_inf: checkdirs
	@echo "####" testing installation information files ... ;\
	if [ -n "`find . -name '*.inf' -maxdepth 1`" ] ; then \
		sudo jcs install *.inf -t ;\
	fi | $(TEE) -a $(INSTALL_LOG)

test_link: checkdirs
	@echo "####" testing link information files ... ;\
	if [ -e link.sh ] ; then \
		jcs linkout -t link.sh ;\
	fi | $(TEE) -a $(INSTALL_LOG)

get: checkdirs
	@echo "####" getting files. ;\
	if [ -n "$(GETFILES)" ] ; then jcs get $(GETFILES) ; fi

getall: $(LOCAL_GET) get $(LOCAL_POST_GET)
	$(recurse_subdirs)

checksum: checkroot # TODO integrate tripwire
	@if [ "$$cfg_use_checksum" = TRUE ] ; then \
		echo "####" updating checksum database ... ;\
		$$update_checksum_command ;\
	fi

install: checkroot $(LOCAL_INSTALL) install_inf install_link $(LOCAL_POST_INSTALL) checksum
	$(recurse_subdirs)
	
setup: checkroot $(LOCAL_SETUP) setup_inf setup_link $(LOCAL_POST_SETUP) checksum
	$(recurse_subdirs)

test: $(LOCAL_TEST) test_inf test_link $(LOCAL_POST_TEST)
	$(recurse_subdirs)

dist: clean
	cd ..;\
	find $(MOD) -type f -o -type l | \
		grep -ve "CVS\|trash\|$(MOD)/setup" | \
		xargs tar -cvzf $(MOD).tar.gz ;\
	mv $(MOD).tar.gz $(MOD)
	
checkroot:
#	@if [ `whoami` != root ] ; then echo "Only root can do this." >&2; exit 1; fi

checkdirs:
	@test -f /etc/jcs/jcs.conf || exit 1 ;\
	test -d `dirname $(SETUP_LOG)`    || mkdir -p `dirname $(SETUP_LOG)` ;\
	test -d `dirname $(INSTALL_LOG)`  || mkdir -p `dirname $(INSTALL_LOG)`

clean: $(LOCAL_CLEAN)
	$(recurse_subdirs) ;\
	rm -f *~ *.swp *.rep .\#* *.done *.su_done $(MOD).tar.gz default.cache 2>/dev/null
--<<<-- jcs.mk --

-->>>-- jcs.conf.oldstyle --
JNT_CONFDIR=/tmp
JNT_USE_CHECKSUM=FALSE
JNT_JCSDIR=/tmp
--<<<-- jcs.conf.oldstyle --

-->>>-- jcs.conf --
jcs_dir=$HOME/local/src/jw.dev/conf/`hostname -d`/`hostname -s`/`/opt/ytools/bin/get_os.sh`
jcs_owner=root
jcs_group=root
jcs_log_dir=$jcs_dir/log
jcs_file_extension=inf
use_checksum=false
update_checksum_command="/home/tripwire/bin/fs_checksum.sh update"
jcs_http_path=http://www.jannet.de
--<<<-- jcs.conf --

-->>>-- /etc/jcs/templates/dir/module/Makefile --
# jannet configuration shadow
# (c) 2000 - 2001 jannet
# contact@jannet.de

include /etc/jcs/jcs.mk
--<<<-- /etc/jcs/templates/dir/module/Makefile --

-->>>-- /etc/jcs/templates/dir/src/Makefile --
# jannet configuration shadow
# (c) 2000 jannet
# contact@jannet.de
MAKE_SH := jcs smake
 
SUBDIRS = cur
 
setup:
	$(MAKE_SH) setup $(SUBDIRS)
 
install:
	$(MAKE_SH) install $(SUBDIRS)
 
clean:
	$(MAKE_SH) clean $(SUBDIRS)                                             
--<<<-- /etc/jcs/templates/dir/src/Makefile --

-->>>-- old config warning --
+--------------------------------------------+
|                                            |
|            C A U T I O N                   |
|                                            |
| It looks like you are using an old style   |
| jcs configuration file /etc/jcs/jcs.conf.  |
| Use of this format is deprecated. JCS will |
| now translate it into the new style format.|
| Also the file /etc/jcs/jcs.mk will be re-  |
| placed, since it's default version also    |
| makes use of /etc/jcs/jcs.conf. If you have|
| edited it yourself, you will have to adapt |
| it to meet your needs, otherwise JCS will  |
| cease to function properly.                |
|                                            |
| Both files will be backed up with an       |
| ".oldstyle" appended to their names.       |
|                                            |
+--------------------------------------------+
--<<<-- old config warning --
