#! /bin/sh

# This shell script loops picking up tasks, touching the .run file so
# that checkrun won't start another copy, and firing off the mpqs program
# whenever a new copy is needed.  It also decides whether to pause
# factoring based on excessive load, terminal activity, and on killing
# factoring based on the existence of a {short,medium,long}kill file or
# a stop file.  Make sure that your FACTORPATH, and all variables named
# in environ have the right values before you start.

trap "" 1

if test -z "${FPATH+yes}"
then
  FPATH=/bin:/usr/bin:/usr/ucb:/etc:${FACTORPATH-.}; export FPATH 
fi
PATH=$FPATH; export PATH

. environ

# The goal of the next line is to change 2 to 200, 2.1 to 210, and 
# 2.103 to 210.  If you can't make this work, just get rid of these
# and use 210 if you want a pauseload of 2.10. 
pauseload=`echo 0 k 100 $pauseload '*' 1 / p | dc`

docheck=`witch atcheck`; tick=`witch ticktock`
run=$OUTDIR/.run.$MACH; dont=$OUTDIR/stop.$MACH
skill=$OUTDIR/shortkill.$MACH; mkill=$OUTDIR/mediumkill.$MACH;
lkill=$OUTDIR/longkill.$MACH; restart=$FACTORDIR/RESTART
pause=$OUTDIR/.pause.$MACH

rm -f $pause $skill $mkill $lkill

TICKSEC=`expr 60 '*' $TICKLEN`; export TICKSEC

if test -s $run
then
  OLDPID=`sed 1d $run`
  $RESUMECMD $OLDPID > /dev/null 2>&1
  kill $OLDPID > /dev/null 2>&1
fi

while test -r $template -a '!' -r $dont
do
  if test -s $run
  then
    oldout=`sed 1q $run`
    test -r $oldout && $MAILCMD $MAILTO < $oldout && rm -f $oldout
  fi

  teller=1

  . $tick

  domail="$DOMAIL"
  while num=`getnum`; test -z "$num" -a -r $template -a '!' -r $dont
  do
    test -n "$domail" && echo "Out of factoring tasks" | $MAILCMD $MAILUSER
    domail=""
    . $tick
  done

  rm -f $run
  echo $num | awk '{printf("'$OUTDIR'/OUT%07d\n", $1);}' > $run

  echo `date`: Starting mpqs with input $num >> $control
  if test -r $template
  then
    oldtemp="`sum $template 2>&1`"
    MAILER="$MAILCMD $MAILTO < `cat $run`"
    sed -e "s/UID/$num/" $template | \
        nice -19 mpqs $restart - $log $OUTDIR/ "$MAILER" &
    pid=$!; echo $pid >> $run; counter=${pausetty-1}
    shouldrun=1; isrun=$shouldrun; oldsum="`ls -lu $ttydevs | sum`"
  fi
  while 
    ps=`${PS} $pid | wc -l`
    if test  -r $template
    then
      newtemp="`sum $template 2>&1`"
    fi
    test $ps -eq 2 -a "$newtemp" = "$oldtemp" -a '!' -r $dont
  do
    . $tick
    why="No reason"
    shouldrun=1
    if test -f $pause
    then
      shouldrun=0
      why="$pause file exists"
    fi
    if test $pausetty -ne 0 -a $shouldrun -ne 0
    then
      newsum="`ls -lu $ttydevs | sum`"
      if test "$newsum" = "$oldsum"
      then
        shouldrun=`expr $counter '>=' $pausetty`
        if test shouldrun -eq 0
        then counter=`expr $counter + 1`
        fi
        if test $isrun -ne $shouldrun
        then why="Terminals idle for $pausetty tick-periods"
        fi
      else
        counter=0; oldsum="$newsum"; shouldrun=0
        if test $isrun -ne $shouldrun
        then why="Terminal activity"
        fi
      fi
    fi
    if test $pauseload -ne 0 -a $shouldrun -ne 0
    then
      load=`uptime | \
awk ' {i = 1; while (i < NF && $i != "average:") i++; print $(i+1); } ' | \
sed -e 's/,//' | sed -e 's/\.//'`
      shouldrun=`expr $shouldrun '&' $load '<=' \
'(' $pauseload '+' '(' '100' '*' $isrun ')' ')'`
      if test $shouldrun -ne $isrun
      then why="Load average is $load"
      fi
    fi
    if test $isrun -ne $shouldrun
    then
      if test $shouldrun -ne 0
      then 
	$RESUMECMD $pid
        echo `date`: $RESUMECMD $pid '(mpqs)--'$why >> $control 
      else 
        $PAUSECMD $pid
	echo `date`: $PAUSECMD $pid '(mpqs)--'$why >> $control
      fi
      isrun=$shouldrun
    fi
    sltel=0
    if test -r $skill
    then
	sltel=45
    fi
    if test -r $mkill
    then
	sltel=90
    fi
    if test -r $lkill
    then
	sltel=135
    fi

    if test $sltel -ne 0
    then
	teller=0
	$RESUMECMD $pid >/dev/null 2>&1
	kill $pid >/dev/null 2>&1
	echo `date`: user kill >> $control
	while test $sltel -ne 0
	do
	  . $tick
	  sltel=`expr $sltel - 1 `
          if test '!' -r $mkill -a '!' -r $lkill -a '!' -r $skill
	  then
		sltel=0
	  fi
	done
	rm -f $mkill $lkill $skill
    fi

  done
  $RESUMECMD $pid >/dev/null 2>&1
  kill $pid >/dev/null 2>&1
  counter=15
  while test $counter -ne 0
  do
    . $tick
    counter=`expr $counter - 1`
  done
done
