/******************/
/* include files  */
/******************/
#include stdio
#include descrip
#include jpidef
#include ssdef
#include ctype
#include time
#include "statedef.h"
#include "brkthru.h"

/***********************************/
/* quad is used for timer purposes */
/***********************************/
typedef int quad[2];

/********************************************/
/* define conditional codes and return code */
/********************************************/
#define GE 0
#define LE 1
#define NE 2
#define EQ 3                 
#define GT 4
#define LT 5
#define NO_PROCESS 0x0200

#define TIMER 1
#define default_seconds 30

/**************************/
/* descriptor definition  */
/**************************/
#define LENGTH(descriptor)	descriptor.dsc$w_length

/**********************************/
/* parameter_list contains a linked */
/* list of entries to examine and */
/* the conditions which trigger a */
/* warning message.               */
/**********************************/
struct parameter_list
{
 short flag; /* the jpi definition to examine */
 short comparison;	/* the condition code */
 int value;		/* the value to compare to */
 struct parameter_list *next;
};

/***********************************/
/* this structure contains the     */
/* list of processes to watch for, */
/* the notification list and points*/ 
/* to the warning list 	           */
/***********************************/
struct process_list
{
 int pidadr;
 char prcnam[16];
 char notify_list[80];
 struct parameter_list *dolist;
 struct process_list *next;
};

/*************************************/
/* used by the getjpi system service */
/*************************************/
struct jpi_item
{
 short buflen;
 short item_code;
 int *buffer;           
 int *retlen;
};                      


/**********************/
/* global variables   */
/**********************/
      
struct jpi_item jplist[24];
struct process_list *first = NULL,
		*curr = NULL; 
struct parameter_list *cwarn = NULL;
int seconds = default_seconds;


/***********************************/
/* storage for the values returned */
/* from GETJPI                     */
/***********************************/
long aptcnt,astcnt,biocnt,bufio,bytcnt,
     cputim,diocnt,dirio,enqcnt,filcnt,
     freptecnt,gpgcnt,imagecount,jobprccnt,
     pageflts,pagfilcnt,ppgcnt,prccnt,
     state,tqcnt,volumes,wssize;

/***************************/
/* return length variables */
/***************************/
short aptlen,astlen,biolen,buflen,
      bytlen,cpulen,diolen,dirlen,
      enqlen,fillen,freplen,gpglen,
      imaglen,jobprclen,paglen,pagfilen,
      ppglen,prclen,statelen,tqlen,vollen,wsslen;

/***************************/
/* predefines sys$getjpi   */
/***************************/
int sys$getjpiw(int,int,int,
                struct jpi_item *,int,int,int);
     
/******************************/
/* sets the seconds value for */
/* the timer                  */
/******************************/
void set_timer( linein)
char *linein;
{
 char *sloc;
 char hold_char[80];

 sloc = strchr(linein,'=');

/* no time specified, use default */
 if (sloc==NULL) return;	

 sloc++; /* move past the = sign */
 
 strncpy(hold_char,sloc,80);
 seconds = atoi(hold_char);
 if (seconds == 0)
  seconds = default_seconds;
}  /* end set_timer() function */

                                  
/******************************/
/* adds an entry to the       */
/* process_list, based on linein */
/******************************/
void add_list( linein )
char *linein;
{
 struct process_list *hparms;
 char *sloc;

  /* we don't have a warning list yet */
 cwarn = NULL; 
  /* get some space */
 hparms = malloc(sizeof (struct process_list)); 
 if (hparms == NULL) 
 {  /* failed */
  printf ("Error allocating space for parameter list\n");
  exit();
 } /* end hparms==NULL */

/* null the process id */
 hparms->pidadr = 0;
 /* extract the notify list */
 sloc = strchr(linein,':');
 /* must have one */
 if (sloc != NULL) 
 {
  *sloc = 0; /*null terminate the string */
  sloc++;   /* move past the null value */
  strncpy(hparms->notify_list,sloc,80); /* extract the text */
 } /* end sloc != NULL */

   /* now find the equal sign */
 sloc = strchr(linein,'='); 
 if (sloc  == NULL) /* failed, exit */
 {
  printf ("Error in parameter file on line %s\nNo equal sign\n",linein);
  exit();
 }  /* end sloc == NULL */

 sloc++; /* move past the = sign */
 strncpy(hparms->prcnam,sloc,15); /* extract the procedure name */
 hparms->prcnam[15] = 0;
 hparms->dolist = NULL; /* null the pointers to the other items */
 hparms->next = NULL;
 if (first == NULL) /* is this the very first procedure */
  first = hparms;
 else
  curr->next = hparms; /* extend the list */
 curr = hparms; /* now point to the entry we just added */
}  /* end add_list() function */

/***********************************/
/* add a warning entry to either   */
/* the current warning list or the */
/* current procedure               */
/***********************************/
void add_warn ( linein, ptype )
char *linein;
int ptype;
{
 struct parameter_list *hwarn;
 int sloc;

    /* get some space */
 hwarn = malloc(sizeof(struct parameter_list));

 if (hwarn == NULL) /* failed, exit */
 {
  printf ("Error allocating memory for warning list\n");
  exit();
 } /* end hwarn == NULL */
   /* if this is our first entry, point to it*/
 if (curr->dolist == NULL) 
  curr->dolist = hwarn;
 else
  cwarn->next = hwarn; /* otherwise extend the list */
 cwarn = hwarn; /* make this one the current end of list */


 cwarn->flag = ptype; /* set the flag */
 cwarn->value = 0;
 cwarn->next = NULL; /* don't point anywhere */
 sloc = strcspn(linein,"!=<>"); /* are we really checking anything?*/

 if (sloc == strlen(linein)) /* if not, fail and exit */
 {
  printf ("Error in line %s\nNo comparison characters\n",linein);
  exit(); 
 } /* end sloc == strlen(lineine)*/
                      
 if (strncmp(&linein[sloc],"<>",2)==0) /* find the comparison entry*/
  cwarn->comparison = NE;
 else
 if (strncmp(&linein[sloc],"!=",2)==0)
  cwarn->comparison = NE;
 else
 if (strncmp(&linein[sloc],"<=",2)==0)
  cwarn->comparison = LE;
 else
 if (strncmp(&linein[sloc],">=",2)==0)
  cwarn->comparison = GE;
 else
 if (linein[sloc]== '=')
  cwarn->comparison = EQ;
 else
 if (linein[sloc]== '<')
  cwarn->comparison = LT;
 else
 if (linein[sloc]== '>')
  cwarn->comparison = GT;

 sloc++;	/* move forward one character*/
 if (cwarn->comparison <= NE) sloc++;	/* two character comparisons */
 strcpy(linein,&linein[sloc]); /* get the numerical entry*/
 cwarn->value = atoi(linein); /* change it to a number*/
} /* end add_warn() function */

/***************************************/
/* this procedures finds out what      */
/* parameter is specified in           */
/* the character field linein          */
/* and returns a JPI parameter numeric */
/***************************************/
int parm_type (linein)         
char *linein;
{
                             
 if (strncmp(linein,"PRCNAM",6)==0)
  return (JPI$_PRCNAM);

 if (strncmp(linein,"APTCNT",6)==0)
  return (JPI$_APTCNT);
 if (strncmp(linein,"ASTCNT",6)==0)
  return (JPI$_ASTCNT);
 if (strncmp(linein,"BIOCNT",6)==0)
  return (JPI$_BIOCNT);
 if (strncmp(linein,"BUFIO",5)==0)
  return (JPI$_BUFIO);
 if (strncmp(linein,"BYTCNT",6)==0)
  return (JPI$_BYTCNT);
 if (strncmp(linein,"CPUTIM",6)==0)
  return (JPI$_CPUTIM);
 if (strncmp(linein,"DIOCNT",6)==0)
  return (JPI$_DIOCNT);
 if (strncmp(linein,"DIRIO",5)==0)
  return (JPI$_DIRIO);
 if (strncmp(linein,"ENQCNT",6)==0)
  return (JPI$_ENQCNT);          
 if (strncmp(linein,"FILCNT",6)==0)
  return (JPI$_FILCNT);
 if (strncmp(linein,"FREPTECNT",9)==0)
  return (JPI$_FREPTECNT);
 if (strncmp(linein,"GPGCNT",6)==0)
  return (JPI$_GPGCNT);
 if (strncmp(linein,"IMAGECOUNT",10)==0)
  return (JPI$_IMAGECOUNT);
 if (strncmp(linein,"JOBPRCCNT",9)==0)
  return (JPI$_JOBPRCCNT);
 if (strncmp(linein,"PAGEFLTS",8)==0)
  return (JPI$_PAGEFLTS);      
 if (strncmp(linein,"PAGFILCNT",9)==0)
  return (JPI$_PAGFILCNT);
 if (strncmp(linein,"PPGCNT",6)==0)
  return (JPI$_PPGCNT);
 if (strncmp(linein,"PRCCNT",6)==0)
  return (JPI$_PRCCNT);    
 if (strncmp(linein,"STATE",5)==0)
  return (JPI$_STATE);
 if (strncmp(linein,"TQCNT",5)==0)
  return (JPI$_TQCNT);
 if (strncmp(linein,"VOLUMES",7)==0)
  return (JPI$_VOLUMES);
 if (strncmp(linein,"WSSIZE",6)==0)
  return (JPI$_WSSIZE);
 if (strncmp(linein,"TIMER",5)==0)
  return (TIMER);
 return 0;
} /* end parm_type() function */

/***************************************/
/* this procedures takes the character */ 
/* field linein and parses it          */
/***************************************/
void parse_line ( linein )
char *linein;
{                               
 int prm_typ;

 /* what kind of line is it? */
 prm_typ = parm_type (linein);
 switch (prm_typ) 
 {
  case 0 : break; /* must have been empty or invalid */
  case JPI$_PRCNAM : add_list(linein); /* a process name */
		break;
  case TIMER : set_timer(linein);
		break;
  default : add_warn ( linein,prm_typ ); /* a parameter */
	break;
 } /* end switch */
}  /* end parse_line() function */
 

/************************************/
/* open and read the parameter file */
/************************************/
void read_parms()                                                
{
 FILE *infile;
 char linein[81];
 int i;

 infile = fopen("plist.dat","r");
 if (infile==NULL)
 {   
  printf ("Error opening plist.dat\n");
  exit();
 }  /* end infile == NULL */

 while (!feof(infile))
 {
  fgets(linein,80,infile);
  linein[80] = 0;
   /* make it upper case for cleanliness sake */
  for (i=0;i<strlen(linein);i++) 
    linein[i] = _toupper(linein[i]);
  parse_line(linein);
 } /* end while !feof */
  fclose (infile);
} /* end read_parms() */

/*******************************************/
/* set the program to wake up periodically */
/*******************************************/
void set_sleep()
{                  
 char stime[14];
 $DESCRIPTOR(_stime,stime);
 quad sbin;
 int retcode;
 int hour = 0,minute = 0,second = 0;
 int i;

 if (seconds > 3600)
 {
  hour = (int) seconds/3600;
  seconds -= (hour * 3600);
 }
 if (seconds > 60)
 {
  minute = (int) seconds/60;
  seconds -= (minute * 60);
 }      
 second = seconds;

 sprintf (stime,"0 %2d:%2d:%2d.00",hour,minute,second);
 for (i=2;i<strlen(stime);i++)
  if (stime[i]==32) stime[i]='0';
 LENGTH(_stime) = strlen(stime);

 retcode = SYS$BINTIM(&_stime,&sbin); /* get a quad time */
 if (retcode != SS$_NORMAL) exit(retcode);

 retcode = SYS$SCHDWK (0,0,&sbin,&sbin); /* schedule wakeup */
 if (retcode != SS$_NORMAL) exit(retcode);

} /* end set_sleep() function */

/********************************/
/* hibernates the program until */
/* SCHDWK wakes up              */
/********************************/
void sleep()
{
 int retcode;
 
 retcode = SYS$HIBER();
 if (retcode != SS$_NORMAL) 
     exit(retcode);
} /* end sleep() function */


/*********************************/
/* set the jplist item at offset */
/* to the current parameter      */
/*********************************/
void set_item ( offset )
int offset;                   
{
 jplist[offset].item_code = cwarn->flag;
 
 switch (jplist[offset].item_code)
 {
  case JPI$_APTCNT : 
     jplist[offset].buffer = &aptcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &aptlen;
     break;
  case JPI$_ASTCNT : 
     jplist[offset].buffer = &astcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &astlen;
     break;
  case JPI$_BIOCNT : 
     jplist[offset].buffer = &biocnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &biolen;
     break;
  case JPI$_BUFIO : 
     jplist[offset].buffer = &bufio;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &buflen;
     break;
  case JPI$_BYTCNT : 
     jplist[offset].buffer = &bytcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &bytlen;
     break;
  case JPI$_CPUTIM : 
     jplist[offset].buffer = &cputim;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &cpulen;
     break;
  case JPI$_DIOCNT : 
     jplist[offset].buffer = &diocnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &diolen;
     break;
  case JPI$_DIRIO : 
     jplist[offset].buffer = &dirio;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &dirlen;
     break;
  case JPI$_ENQCNT : 
     jplist[offset].buffer = &enqcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &enqlen;
     break;
  case JPI$_FILCNT : 
     jplist[offset].buffer = &filcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &fillen;
     break;
  case JPI$_FREPTECNT : 
     jplist[offset].buffer = &freptecnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &freplen;
     break;
  case JPI$_GPGCNT : 
     jplist[offset].buffer = &gpgcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &gpglen;
     break;
  case JPI$_IMAGECOUNT : 
     jplist[offset].buffer = &imagecount;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &imaglen;
     break;
  case JPI$_JOBPRCCNT : 
     jplist[offset].buffer = &jobprccnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &jobprclen;
     break;
  case JPI$_PAGEFLTS : 
     jplist[offset].buffer = &pageflts;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &paglen;
     break;
  case JPI$_PAGFILCNT : 
     jplist[offset].buffer = &pagfilcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &pagfilen;
     break;
  case JPI$_PPGCNT : 
     jplist[offset].buffer = &ppgcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &ppglen;
     break;
  case JPI$_PRCCNT : 
     jplist[offset].buffer = &prccnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &prclen;
     break;
  case JPI$_STATE : 
     jplist[offset].buffer = &state;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &statelen;
     break;
  case JPI$_TQCNT : 
     jplist[offset].buffer = &tqcnt;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &tqlen;
     break;
  case JPI$_VOLUMES : 
     jplist[offset].buffer = &volumes;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &vollen;
     break;
  case JPI$_WSSIZE : 
     jplist[offset].buffer = &wssize;
     jplist[offset].buflen = 16;          
     jplist[offset].retlen = &wsslen;
     break;
 } /* end switch */
} /* end set_item () function */

/***********************************/
/* set the current jplist item at  */
/* offset to nulls to terminate it */
/***********************************/
void null_item ( offset )
{
 jplist[offset].buflen = 0;
 jplist[offset].item_code = 0;
 jplist[offset].buffer = 0;
 jplist[offset].retlen = 0;
} /* end null_item() function */


/**************************************/
/* send a warning based on            */
/* stat_code to the distribution list */
/* for the current process.           */
/**************************************/
void send_warning( stat_code )
int stat_code;
{            
 char msg_buff[255]; /* msg to be sent */
 $DESCRIPTOR(_msg_buff,msg_buff);
 char hsend[80]; /* holding variable for dist list */
 int sloc;       /* used for offset into strings */
 char sendto[80];  /* a username to send to */
 $DESCRIPTOR(_sendto,sendto);
 char evaluation[20]; /* used to pretty up the text */
 int retcode;
 long carcon = 32;  /* carriage control spec */
 /* send it across the cluster, use screen control and put 
    the message at the bottom of the CRT */
 long flags = BRK$M_CLUSTER+BRK$M_SCREEN+BRK$M_BOTTOM;
 long sndtyp = BRK$C_USERNAME; /* sending to username */

 struct
 {
  short io_stat,count;
  short ecnt[2];
 } iosb; /* BRKTHRU I/O status block */

 /* if the error is not NO_PROCESS, 
    find out what the comparison was */

 if (stat_code != NO_PROCESS) 
 {
  switch (cwarn->comparison)   
  {           
   case GE : strcpy(evaluation,"greater or equal to");
	    break;
   case LE : strcpy(evaluation,"less than or equal to");
	    break;
   case NE : strcpy(evaluation,"not equal to");
	    break;
   case EQ : strcpy(evaluation,"equal to");
	    break;
   case LT : strcpy(evaluation,"less than");
	    break;
   case GT : strcpy(evaluation,"greater than");
	    break;
  } /* end switch */
 }  /* end if no_process*/
 
/* build the text describing the error */
 switch (stat_code)
 {
  case NO_PROCESS : sprintf(msg_buff,
"\n%cThe process %s is not on the system%c\n\n",7,curr->prcnam,7);
		    break;
  case JPI$_APTCNT : sprintf (msg_buff,
"\n%cThe process %s has an aptcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,aptcnt,evaluation,cwarn->value,7);
	break;
  case JPI$_ASTCNT : sprintf (msg_buff,
"\n%cThe process %s has an astcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,astcnt,evaluation,cwarn->value,7);
	break;
  case JPI$_BIOCNT : sprintf (msg_buff,
"\n%cThe process %s has a biocnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,biocnt,evaluation,cwarn->value,7);
	break;
  case JPI$_BUFIO : sprintf (msg_buff,
"\n%cThe process %s has a bufio of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,bufio,evaluation,cwarn->value,7);
	break;
  case JPI$_BYTCNT : sprintf (msg_buff,
"\n%cThe process %s has a bytcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,bytcnt,evaluation,cwarn->value,7);
	break;           
  case JPI$_CPUTIM : sprintf (msg_buff,
"\n%cThe process %s has a cputim of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,cputim,evaluation,cwarn->value,7);
	break;
  case JPI$_DIOCNT : sprintf (msg_buff,
"\n%cThe process %s has a diocnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,diocnt,evaluation,cwarn->value,7);
	break;                 
  case JPI$_DIRIO : sprintf (msg_buff,
"\n%cThe process %s has a dirio of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,dirio,evaluation,cwarn->value,7);
	break;
  case JPI$_ENQCNT : sprintf (msg_buff,
"\n%cThe process %s has an enqcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,enqcnt,evaluation,cwarn->value,7);
	break;
  case JPI$_FILCNT : sprintf (msg_buff,
"\n%cThe process %s has an filcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,filcnt,evaluation,cwarn->value,7);
	break;                    
  case JPI$_FREPTECNT : sprintf (msg_buff,
"\n%cThe process %s has an freptecnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,freptecnt,evaluation,cwarn->value,7);
	break;
  case JPI$_GPGCNT : sprintf (msg_buff,
"\n%cThe process %s has a gpgcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,gpgcnt,evaluation,cwarn->value,7);
	break;
  case JPI$_IMAGECOUNT : sprintf (msg_buff,
"\n%cThe process %s has an imagecount of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,imagecount,evaluation,cwarn->value,7);
	break;            
  case JPI$_JOBPRCCNT : sprintf (msg_buff,
"\n%cThe process %s has a jobprccnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,jobprccnt,evaluation,cwarn->value,7);
	break;
  case JPI$_PAGEFLTS : sprintf (msg_buff,
"\n%cThe process %s has had %d pagefaults, which is %s the value %d%c\n\n",
	 7,curr->prcnam,pageflts,evaluation,cwarn->value,7);
	break;
  case JPI$_PAGFILCNT : sprintf (msg_buff,
"\n%cThe process %s has a pagefilecnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,pagfilcnt,evaluation,cwarn->value,7);
	break;               
  case JPI$_PPGCNT : sprintf (msg_buff,
"\n%cThe process %s has a ppgcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,ppgcnt,evaluation,cwarn->value,7);
	break;
  case JPI$_PRCCNT : sprintf (msg_buff,
"\n%cThe process %s has an prccnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,prccnt,evaluation,cwarn->value,7);
	break;
  case JPI$_STATE : sprintf (msg_buff,
"\n%cThe process %s has a state of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,state,evaluation,cwarn->value,7);
	break;
  case JPI$_TQCNT : sprintf (msg_buff,
"\n%cThe process %s has a tqcnt of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,tqcnt,evaluation,cwarn->value,7);
	break;                                       
  case JPI$_VOLUMES : sprintf (msg_buff,
"\n%cThe process %s has mounted %d volumes, which is %s the value %d%c\n\n",
	 7,curr->prcnam,aptcnt,evaluation,cwarn->value,7);
	break;
  case JPI$_WSSIZE : sprintf (msg_buff,
"\n%cThe process %s has an wssize of %d, which is %s the value %d%c\n\n",
	 7,curr->prcnam,aptcnt,evaluation,cwarn->value,7);
	break;
 } /* end switch */
  LENGTH(_msg_buff) = strlen(msg_buff);

/* build the send list, and send the message 
  until all users have been notified	*/

/* put the list into a holding variable */
 strcpy(hsend,curr->notify_list); 
 /* loop until we have reached the end of the variable */
 while (hsend[0]!=0)     
 {
  sloc = strchr(hsend,','); /* find a comma*/
  if (sloc == 0) /* none left, must be one name only */
  {
   strcpy(sendto,hsend);
   hsend[0]=0;
  }
  else /* found a comma */
  {
   sloc = abs(&hsend[0] - sloc); /* move to line offset */
   strncpy(sendto,hsend,sloc);   /* copy to the comma */
   sendto[sloc] = 0;             /* terminate the line */
   strcpy(hsend,&hsend[sloc+1]); /* copy everything after the comma*/
  }
  LENGTH(_sendto) = strlen(sendto);

/* send the message */
  retcode = SYS$BRKTHRUW (0,&_msg_buff,&_sendto,sndtyp,&iosb,
             		carcon,flags,0,0,0,0);
  
  if (retcode != SS$_NORMAL && retcode != SS$_NOSUCHDEV)
   exit(retcode);
 } /* end while hsend[0] != 0 */
} /* end send_warning() function */
   
     
/*************************************/
/* this procedures checks the status */
/* of cwarn against the value        */
/* in job information retrieval      */
/* array at point offset             */
/*************************************/
void check_status( offset )
int offset;
{
 switch (cwarn->comparison)
 {
  case GE : 
    if (*jplist[offset].buffer >= cwarn->value)
		send_warning ( cwarn->flag);
	    break;
  case LE : 
     if (*jplist[offset].buffer <= cwarn->value)
		send_warning ( cwarn->flag);
	    break;
  case NE : 
     if (*jplist[offset].buffer != cwarn->value)
		send_warning ( cwarn->flag);
	    break;
  case EQ : 
     if (*jplist[offset].buffer == cwarn->value)
		send_warning ( cwarn->flag);
	    break;
  case GT : 
     if (*jplist[offset].buffer > cwarn->value)
		send_warning ( cwarn->flag);
	    break;
  case LT : 
     if (*jplist[offset].buffer < cwarn->value)
		send_warning ( cwarn->flag);
	    break;
 } /* end switch */
}  /* end check_status function */


/*************************************/
/* load the process id's.   findall  */
/* is a switch that is used to define*/
/* whether all the processes from    */
/* parameter file should be used or  */
/* only those that do not have their */
/* process id's established.         */
/*************************************/
void load_pid( findall )
int findall;
{         
 int pidadr = -1; /* wild card process id */
 int procid;      /* return the pid to here */
 long retid;      /* return field length */
 int iosb[2];     /* i/o status block */
 register jpi_status;
 char prcnam[16];  /* process name */
 long retlen = 0; /* process name return length */
   /* jpi call list, get the process name and the process id */
 struct jpi_item jplist[3] = {
  {sizeof(prcnam)-1,JPI$_PRCNAM,&prcnam[0],&retlen},
  {sizeof(procid),JPI$_PID,&procid,&retid},
 {0,0,0,0}};
  /* used to create the parameter list */
 struct process_list *hparms;
 /* switch to verify that a match was found */
 int fndmatch;

 do
 { /* get the process information */
  jpi_status = sys$getjpiw(0,&pidadr,0,&jplist,&iosb,0,0);
  if (jpi_status != SS$_NORMAL && jpi_status != SS$_NOMOREPROC)
   exit(jpi_status); /* indicates fatal error */
 /* found a process */
  if (jpi_status == SS$_NORMAL)
  {
   fndmatch = FALSE; /* turn off the switch */
     /* loop through the parm list 
        until a match is found or the
        end of the list is reached */

   for (hparms=first;hparms!=NULL && !fndmatch;hparms = hparms->next)
   { /* check for findall or a null process id */
    if (findall || (!findall && hparms->pidadr == 0))
     if (strcmp(hparms->prcnam,prcnam)== 0) /* process name match?*/
     {
      hparms->pidadr = procid; /* set the id */
      fndmatch = TRUE;         /* exit the loop */
    } /* end if strcmp*/
   } /* end for hparms*/
  } /* end if jpi_status */
 } while (jpi_status == SS$_NORMAL);  /* end do */
} /* end load_pid() function */


                   

/***********************************/
/* this procedure checks the       */
/* system for operational validity */
/***********************************/
void check_system()
{                          
 int iosb[2];       /* i/o status block */
 register jpi_status;
 int offset;
                                    
/* loop through the descriptors for the processes to watch */
 for (curr=first;curr!= NULL; curr = curr->next)
 {     
  if (curr->pidadr == 0) /* haven't found this one yet */
   load_pid (FALSE);
  if (curr->pidadr == 0) /*still haven't found it */
   send_warning(NO_PROCESS);
  else /* no process id found at this time */
  {
   offset = 0; /* build a list of the parameters to warn against */
   for (cwarn = curr->dolist;cwarn!=NULL;cwarn = cwarn->next)
    set_item(offset++); /* add an item */
   null_item(offset);  /* terminate with nulls */

  /* get the status */
   jpi_status = sys$getjpiw(0,&curr->pidadr,0,&jplist,&iosb,0,0);
                             
   if (jpi_status == SS$_NONEXPR)  /* doesn't exist! */
   {
    send_warning(NO_PROCESS);
    curr->pidadr = 0; /* prepare it to be checked again */
   } /* end if jpi_status */
   else
   {
    if (jpi_status != SS$_NORMAL) 
       exit(jpi_status); /* check for other errors*/
 
    offset = 0;
    for (cwarn = curr->dolist;cwarn != NULL;cwarn = cwarn->next)
     check_status(offset++); /* check each entry */
   } /* end else on status */
  } /* end else pidadr == 0 */
 }  /* end for loop */
} /* end check_system() function */


/******************************/
/* this is the infinite loop  */
/* that drives this program.  */
/******************************/
void watch_system()
{
 set_sleep();
 while (TRUE)
 {
  check_system();
  sleep();
 } /* end while true */
} /* end watch_system() function */



/**********************************/
/* the main procedure. Reads the  */
/* parameters and then watches    */
/**********************************/
main()
{
 read_parms();
 load_pid(TRUE);
 watch_system();
} /* end main() function */



TIMER=120
PRCNAM=SYSPROC:SNYDER,SMITH,OPERATOR
BIOCNT<200
BYTCNT<150
CPUTIM>120000
STATE<>5
PRCNAM=MYPROC:SMITH,OPERATOR
STATE<>7



$ cc/list/debug=notrace syswatch
$ link/notrace syswatch,sys$library:vaxcrtl/library



#define	BRK$C_DEVICE		1
#define	BRK$C_USERNAME		2
#define	BRK$C_ALLUSERS		3
#define	BRK$C_ALLTERMS		4
#define	BRK$C_MAXSENDTYPE	4

#define	BRK$C_GENERAL		0
#define	BRK$C_PHONE		1
#define	BRK$C_MAIL		2
#define	BRK$C_QUEUE		3
#define	BRK$C_SHUTDOWN		4
#define	BRK$C_URGENT		5
#define	BRK$C_DCL		6
#define	BRK$C_OPCOM		7
#define	BRK$C_USER1		32
#define	BRK$C_USER2		33
#define	BRK$C_USER3		34
#define	BRK$C_USER4		35
#define	BRK$C_USER5		36
#define	BRK$C_USER6		37
#define	BRK$C_USER7		38
#define	BRK$C_USER8		39      
#define	BRK$C_USER9		40
#define	BRK$C_USER10		41
#define	BRK$C_USER11		42
#define	BRK$C_USER12		43
#define	BRK$C_USER13		44
#define	BRK$C_USER14		45
#define	BRK$C_USER15		46
#define	BRK$C_USER16		47

#define	BRK$M_SCREEN		256
#define	BRK$M_BOTTOM		512
#define	BRK$M_NOREFRESH		1024
#define	BRK$M_CLUSTER		2048

#define	BRK$S_FLAGS_INPUT	2
#define	BRK$S_ERASE_LINES	8

#define	BRK$V_ERASE_LINES	0
#define	BRK$V_SCREEN		8
#define	BRK$V_BOTTOM		9
#define	BRK$V_NOREFRESH		10
#define	BRK$V_CLUSTER		11




#define SCH$C_COLPG	1
#define SCH$C_MWAIT	2
#define SCH$C_CEF	3
#define SCH$C_PFW	4
#define SCH$C_LEF	5
#define SCH$C_LEFO	6
#define SCH$C_HIB	7
#define SCH$C_HIBO	8
#define SCH$C_SUSP	9
#define SCH$C_SUSPO	10
#define SCH$C_FPG	11
#define SCH$C_COM	12
#define SCH$C_COMO	13
#define SCH$C_CUR	14

