/**
 *  TapeMon:  a monitor program for the BTNtape handler.
 */
#define MVERSION  "TapeMon V1.0"
/*
 *  (c) Copyright 1990  Robert Rethemeyer
 *   This software may be freely distributed and redistributed,
 *   for non-commercial purposes, provided this notice is included.
 *------------------------------------------------------------
 *   Run TapeMon from a CLI to receive informational messages
 *   from the BTN-Tape handler process.  To terminate the
 *   monitor program, break the CLI using control-C or BREAK.
 */
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <libraries/dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "/tplink.h"

#if defined AZTEC_C
  #include <functions.h>
#elif defined LATTICE
  #include <proto/exec.h>
  #include <proto/dos.h>
#endif

extern struct DosLibrary *DOSBase;

void main(int,char *[]);
void main(int argc, char *argv[])
{
 struct Task    *tapeproc;
 struct tplink  *linktp;
 char *tapename;
 ULONG x;
 short run = 1;
 BYTE  signum;
 BYTE  oldpri;

   printf("*** BTN-Tape Handler & Monitor ***\n(c) Copyright 1990 Robert Rethemeyer\n");

   if(argc > 1) tapename = argv[1];
   else         tapename = "TAPE";
   if (!(tapeproc = FindTask(tapename)))  {
         printf("Process %s not found...\n (be sure to use caps, no ':')\n",tapename);
         exit(30);
   }
   if (!(linktp = (struct tplink *) tapeproc->tc_UserData))  {
         printf("No linkage structure...\n wrong process, or\n handler not active yet?\n");
         exit(31);
   }
   printf("%s: Proc %X DevNode %X\n",tapename,tapeproc,linktp->devnode);

   if (strcmp(linktp->keyword,"TapeHandler"))  {
         printf("Process %s doesn't look like BTN-Tape\n",tapename);
         exit(32);
   }

   if (linktp->montask)  {
         printf("There is already a TapeMon running\n");
         exit(33);
   }

   if (!linktp->handsig) {
          printf("Handler has no signal\n");
          exit(34);
   }

   signum = AllocSignal(-1);
   if (signum == -1)  {
         printf("Unable to allocate signal for TapeMon\n");
         exit(35);
   }
   linktp->monsig  = 1UL << signum;      /* give mask to tape handler */
   linktp->montask = FindTask(0);        /* tell it where I am also   */
   printf("%s Unit %X\n",linktp->driver,*(linktp->unit));
   if(linktp->sense)
       printf("Last sense= %X,%02X\n",linktp->sense,linktp->xsense);
   printf("Use ^C to terminate TapeMon\n%s\n",linktp->version);

   /* Set the monitor priority to the same as that of the handler */
   oldpri = SetTaskPri (linktp->montask, (long)tapeproc->tc_Node.ln_Pri);

   /* The main loop.  Wait for a signal from the handler, then print the
      contents of dbb.  Some extra handshaking must then be done to sync
      the two processes and prevent races.  If a control-C occurs during
      a Wait, then finish whatever was in progress before ending the loop.
   */

   while(run)  {
     x=Wait(linktp->monsig | SIGBREAKF_CTRL_C);   /* Wait for req from hndlr */
     if  (x & SIGBREAKF_CTRL_C) run = 0;
     if(!(x & linktp->monsig) ) continue;

     printf(" %s",linktp->dbb);                   /* print handler's message */
     Signal(tapeproc, linktp->handsig);           /* tell it we are 'done'   */

     x=Wait(linktp->monsig | SIGBREAKF_CTRL_C);   /* Wait for ack of 'done'  */
     if  (x & SIGBREAKF_CTRL_C) run = 0;
     if(!(x & linktp->monsig) ) Wait(linktp->monsig);

     Signal(tapeproc, linktp->handsig);           /* Ack his ack */
   }

   /* Clean up and exit */

   SetTaskPri(linktp->montask, (long) oldpri);   /* restore priority */
   linktp->montask = NULL;                      /* break link with handler */
   linktp->monsig  = 0;
   FreeSignal((ULONG)signum);
   printf("TapeMon terminated\n");
   exit(0);
}
