#! /bin/sh

############################################################################
#              Copyright 1992 Digital Equipment Corporation
#                         All Rights Reserved
#
# Permission to use, copy, and modify this software and its documentation is
# hereby granted only under the following terms and conditions.  Both the
# above copyright notice and this permission notice must appear in all copies
# of the software, derivative works or modified versions, and any portions
# thereof, and both notices must appear in supporting documentation.
#
# Users of this software agree to the terms and conditions set forth herein,
# and hereby grant back to Digital a non-exclusive, unrestricted, royalty-
# free right and license under any changes, enhancements or extensions 
# made to the core functions of the software, including but not limited to 
# those affording compatibility with other hardware or software 
# environments, but excluding applications which incorporate this software.
# Users further agree to use their best efforts to return to Digital any
# such changes, enhancements or extensions that they make and inform Digital
# of noteworthy uses of this software.  Correspondence should be provided
# to Digital at:
#
#                       Director of Licensing
#                       Western Research Laboratory
#                       Digital Equipment Corporation
#                       100 Hamilton Avenue
#                       Palo Alto, California  94301
#
# This software may be distributed (but not offered for sale or transferred
# for compensation) to third parties, provided such third parties agree to
# abide by the terms and conditions of this notice.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
# CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
############################################################################

# sccsid = "@(#)scanqueue	@(#)scanqueue	2.0	Network Systems Lab 4/15/92"
#
# Author: Geoff Mulligan (mulligan@pa.dec.com)
#	Please send any modifications or comments to me.
#
# Original code from Brian Reid
#
# This program is called from cronscan to process the archive-server
# work queue in arrival sequence.  It will not run if another scan is
# already running.  It also sleeps or exists if the load factor rises
# to high.   

. ./setup

TmpFile=/tmp/rec-arc.$$
LogFile=${REQDIR}/out.log
Limit1=${1-300}
Limit2=${2-500}

trap "rm -f /tmp/*.$$; exit" 0 1 2 3 15

# Lock to make sure that only one scanqueue is running at a time
cd $WORKDIR
CurrentTime=`date+ 0 hours "%S"`
if test -f .ScanLock ;then
  LockTime=`cat .ScanLock`
  BreakTime=`expr 3600 + $LockTime`
  if [ $CurrentTime -lt $BreakTime ] ;then
    exit 0
  fi
fi
echo $CurrentTime > .ScanLock

# process the queue, oldest-first
for WorkFile in `ls -tr in.* 2> /dev/null` ;do
  while true ;do
    Load=`uptime | sed -e 's/.*average: \([^ ]*\),.*$/\1/' -e 's/\.//g'`
    if [ $Load -gt $Limit2 ] ;then
      rm -f .ScanLock
      exit
    else
      if [ $Load -gt $Limit1 ] ;then
        echo Waiting - Load Factor=$Load
        sleep 30
	continue
      else
	break
      fi
    fi
  done

  echo Processing `$ONELINE < $WorkFile`
  NewName=`cat seq 2> /dev/null`
  if [ ! "$NewName" ] ;then
    NewName="`ls ${DONEDIR}/done.* 2> /dev/null | sed "s:${DONEDIR}/done.::" | sort -nr | $ONELINE`"
  fi
  if [ ! "$NewName" ] ;then
    NewName="0"
  fi
  NewName=`expr $NewName + 1`
  echo $NewName > $WORKDIR/seq
  NewName="${DONEDIR}/done.$NewName"

  tr 'A-Z' 'a-z' < $WorkFile | \
  awk '
    /^subject: / {
      SUBL=substr($0,9);
      while (substr(SUBL,0,1)==" ") {
        SUBL=substr(SUBL,2);
      }
      if (substr(SUBL,0,4)=="re: ") SUBL="";
      next
    }
    /^$/ {
      print; print SUBL; SUBL=""; next
    }
    {print}' | \
  awk '
    BEGIN {
      InHeader=1; OFS=" "; Arguments=""; First = 1; BadgeNo=0; OrderId=0;
      BadFrom[0]="daemon"; BadFrom[3]="mailer-daemon"; BadFrom[6]="system";
    }
    First == 1 {First = 0; Sender=$2;}
    /^reply-to: / {
      if (!InHeader) next;
      ReplyTo=$2; for(i=3;i<=NF;i++) ReplyTo = ReplyTo " " $i;
    }
    /^from: / {
      if (!InHeader) next;
      From=$2; for(i=3;i<=NF;i++) From = From " " $i;
      for (i in BadFrom) {
        if (index($0,BadFrom[i])) {Verb="abort";exit}
      }
    }
    /^$/ {InHeader=0; next}
    InHeader==1 {next}
    / *path/ {ReplyTo=$2; next}
    / *badge/ {BadgeNo=$2; next}
    /^ *status/ {Verb="status"; OrderId=$2; next}
    /^ *add/ {Verb="add"; next}
    /^ *order/ {
      Verb="order"; 
      for(i=2;i<=NF;i++) {
        Arguments = Arguments " " $i;
      }
      next 
    }
    /^ *send/ {
      if (Verb == "help" || Verb == "index") next;
      Verb="send";
      if ($2 == "help") {
        Verb="help"; next
      }
      else if ($2 == "index") { 
        Verb="index";
        if (NF<3) Arguments = Arguments " .";
      }
      for(i=2;i<=NF;i++) {
        if ($i != "to" && $i != "from" && $i != "for" && $i != "of" && $i != "the")
          Arguments = Arguments " " $i;
      }
      next
    }
    /help/ {Verb="help"; Arguments=$0; next}
    /^ *index/ {
      if (Verb == "send" || Verb=="help") next;
      Verb="index";
      if (NF<2) Arguments=Arguments " ."
      else {
        for(i=1;i<=NF;i++) {
          if ($i != "to" && $i != "from" && $i != "for" && $i != "of" && $i != "the")
            Arguments = Arguments " " $i;
        }
      }
      next
    }
    {if (Verb == "") {Verb="reject"; Arguments=""; next} }
    END {
      print "REQUEST",'$$';
      print "DATE", "'"`date`"'"
# To exclude specific people, put the test here:
      if (Sender=="on-the-shitlist") Verb="ignore";
      if (ReplyTo != "")
	BestPath=ReplyTo
      else {
        if (index(Sender,"!") > 0 && index(Sender,"@") == 0)
          BestPath=Sender
        else 
          if (From == "") BestPath=Sender
            else BestPath=From 
      }
      if (substr(BestPath,length(BestPath)-4,5) == ".uucp") {
        UUhost=substr(BestPath,1,length(BestPath)-5)
        print | "echo ADDR `mailpath " UUhost "`"; 
      }
      else print "ADDR",BestPath
      if (From != "") print "FROM",From
      else print "FROM",Sender;
      print "ARGS",Arguments
      print "BADGE",BadgeNo
      print "ORDER",OrderId
      if (Verb == "order")
         print "FILE '$WorkFile'";
      if ((Verb!="abort") && (Verb!="send") && (Verb!="help") && (Verb!="index") && (Verb!="find") && (Verb!="ignore") && (Verb!="status") && (Verb!="add") && (Verb!="order")) 
	Verb="reject";
      print "VERB",Verb}' > $TmpFile
    
  if egrep -s '^VERB ignore' $TmpFile ;then
    echo "`$DATE`" ignore >> $LogFile
    mv $WorkFile $NewName
    rm -f .ScanLock
    exit 0
  fi
    
  if egrep -s '^VERB abort' $TmpFile ;then
    cat $TmpFile $WorkFile | head -100 | Mail -s "SCANQUEUE: TROUBLE!" $AUTHORITY
    rm -f $WorkFile
    rm -f .ScanLock
    exit 
  fi
    
  if egrep -s '^VERB add' $TmpFile ;then
    cp $WorkFile $ADDDIR
  fi
    
  if egrep -s '^VERB order' $TmpFile ;then
    cp $WorkFile $ORDDIR
  fi
    
# if it's anything but a "send" command, process immediately
  if egrep -s '^VERB send' $TmpFile ;then
    enqueue < $TmpFile
  else
    cat $TmpFile | awk '
      $1 == "ADDR" {Addr=$2; for(i=3;i<=NF;i++) Addr = Addr " " $i; next}
      $1 == "ARGS" {Args=$2; for(i=3;i<=NF;i++) Args = Args " " $i; next}
      $1 == "FROM" {From=$2; for(i=3;i<=NF;i++) From = From " " $i; next}
      $1 == "DATE" {Date=$2; for(i=3;i<=NF;i++) Date = Date " " $i; next}
      $1 == "BADGE" {BadgeNo=$2; for(i=3;i<=NF;i++) BadgeNo = BadgeNo " " $i; next}
      $1 == "ORDER" {Order=$2; for(i=3;i<=NF;i++) Order = Order " " $i; next}
      $1 == "FILE" {File=$2; for(i=3;i<=NF;i++) File = File " " $i; next}
      $1 == "VERB" {
        if ($2 == "help") {
          print | "help " "'\''" Addr "'\'' " "'\''" From "'\''"
          next; }
        if ($2 == "reject") {
          print | "reject " "'\''" Addr "'\'' " "'\''" From "'\''"
          next; }
        if ($2 == "index") {
          print | "index " "'\''" Addr "'\'' " "'\''" From "'\'' " Args }
        if ($2 == "add") {
          print | "add " "'\''" Addr "'\'' " "'\''" From "'\'' " Args }
        if ($2 == "order") {
          print | "order " "'\''" Addr "'\'' " "'\''" From "'\'' " "'\''" Date "'\'' " "'\''" BadgeNo "'\'' " "'\''" File "'\'' " Args }
        if ($2 == "status") {
          print | "status " "'\''" Addr "'\'' " "'\''" From "'\'' " "'\''" Order "'\'' " Args }
      }'
  fi

  mv $WorkFile $NewName

done
rm -f .ScanLock

