#ifndef lint
static char *RCSid = "$Header: /afs/athena/astaff/project/xmit/Xcluster/snmp/RCS/setup.c,v 1.2 1996/02/20 14:50:56 tom Exp $";
#endif

/*
 * $Log: setup.c,v $
 * Revision 1.2  1996/02/20  14:50:56  tom
 * added SGI
 *
 * Revision 1.1  1993/08/03  12:58:12  tom
 * Initial revision
 *
 * Revision 1.1  89/11/03  15:20:23  snmpdev
 * Initial revision
 * 
 */

/******************************************************************************
**
**			setup.c
**
** Function to determine workstation type of each agent in the poll list. 
**
**
******************************************************************************/
#include "conf.h"
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/time.h>
#include "snmp_hs.h"
#include "cmon.h"

static jmp_buf env;			/* to save environment for timeouts */
static short retries;			/* number of retries */
static struct itimerval interval, disable;	/* for timeouts and retries */
static getreq req;				/* the request message */

void setup(), poll(), initialize();	/* declarations of procs. */
int lonintr();				/* timeout interrupt handler */


void
setup()
{
  AGENT *a;				/* to traverse list of agents */

  for (a = first_agent; a != (AGENT *)NULL; a = a->nxt)
    poll(a);
}



void
poll(a)
     AGENT *a;				/* agent to query */
{
  getrsp rsp;				/* buffer for reply */
  struct in_addr from;			/* source of message received */
  long rreq_id;				/* req id of message received */
  short type;				/* type of message received */
  char r_sid[SNMPMXSID];		/* community id of message received */
  short sidlen;				/* length of community id */
  short rc;				/* return code */
  int i;			
  static init = FALSE;

/* initializations */
  if (!init)
    initialize();

/* do agent specific (re)initializations */
  req.reqid = (long)time(0) ^ getpid();
  retries = 0;

  fprintf(stderr,"Poll: send to %s... ", a->nm);
  (void) fflush(stderr);
  a->ntype = MAXMACHTYPE - 1;		/* IN CASE we don't get a rsp */
					/* set ntype to unknown       */


/* preserve environment etc. */
  if(setjmp(env))
    if(retries < RETRIES)
      {
	fprintf(stderr, "retry %d... ", retries);
	(void) fflush(stderr);
	retries++;
      }
    else				/* exceeded number of retries */
      {
	fprintf(stderr,"giving up.\n");
	return;
      }

/* send off request */
  (void) signal(SIGALRM, SIG_IGN);
  if((rc = snmpsend(REQ,req.reqid,&a->agnt,"snmp",&req,
		    COMMUNITY,strlen(COMMUNITY),TIMEOUT)) < 0)
    {
      error(rc, stderr);
      return;
    }

/* receive reply */
  rreq_id = req.reqid;			/* save request id */
  (void) signal(SIGALRM,lonintr);
  setitimer(ITIMER_REAL,&interval,(struct itimerval *)NULL);
  if((type = snmprecv(&from,(char *)NULL,&rreq_id,r_sid,&sidlen,
		      (char *)&rsp,sizeof(rsp))) < 0)
    {
      error(type, stderr);
      longjmp(env,1);
    }
  setitimer(ITIMER_REAL,&disable,(struct itimerval *)NULL);

/* check reply */
  if(type != RSP)			/* not a response */
    {
      fprintf(stderr,"Poll: did not receive a response\n");
      longjmp(env,1);
    }
  if(rsp.errstat != 0)			/* error in message */
    {
      fprintf(stderr,"Poll: error in reply errstat = %d errindex = %d\n",
	      rsp.errstat, rsp.errindex);
      longjmp(env,1);
    }
  if(rreq_id != req.reqid)		/* wrong request id */
    {
      fprintf(stderr,"Poll: wrong message received\n");
      longjmp(env,1);
    }

  if ((oidncmp(&(req.varlist.elem[0].name),&(rsp.varlist.elem[0].name),
	       req.varlist.elem[0].name.ncmp) != 0)
      || (oidncmp(&(req.varlist.elem[1].name),&(rsp.varlist.elem[1].name),
		  req.varlist.elem[1].name.ncmp) != 0))
    {
      fprintf(stderr,"Poll: unknown variable received\n");
      longjmp(env,1);
    }
  if ((rsp.varlist.elem[0].val.type != STR)	/* check value type */
      || (rsp.varlist.elem[1].val.type != INT))
    {
      fprintf(stderr,"Poll: variable was of wrong type\n");
      longjmp(env,1);
    }

/* variable was correct, copy in value */
  a->status = rsp.varlist.elem[1].val.value.intgr;
  if (a->status>1)
    a->status = 1;			/* clamp it at 1 */

  a->type = rsp.varlist.elem[0].val.value.str.str;  
  i = strlen(a->type) - 1;
  if (a->type[i] == '\n')
    a->type[i] = '\0';

				/* Figure out machine type. */
  if (!strcmp(a->type, "MVAX-II"))
    a->ntype = 0;

  for(i=0; i < MAXMACHTYPE; i++)
    {
      if(strncasecmp(a->type, machine[i], strlen(machine[i])) == 0)
	{
	  a->ntype = i;
	  break;
	}
    }

  fprintf(stderr, "%s, %s(%d), %s(%d), %d\n",
	  a->nm, machine[a->ntype], a->ntype,
	  clusters[a->nloc], a->nloc, a->status);
}

int
lonintr()
{
  longjmp(env,1);
}

void
initialize()
{
/* timing structures */
  interval.it_interval.tv_sec = 0;	/* don't want to reload timer */
  interval.it_interval.tv_usec = 0;
  interval.it_value.tv_sec = 3;		/* HARD CODE 3 sec interval */
  interval.it_value.tv_usec = 0;

  disable.it_interval.tv_sec = 0;	/* to disable timer */
  disable.it_interval.tv_usec = 0;
  disable.it_value.tv_sec = 0;
  disable.it_value.tv_usec = 0;

/* request message */
  req.errstat = req.errindex = 0;
  req.varlist.len = 2;			  /* two variables */
  req.varlist.elem[0].name.cmp[0] = 0x01; /* iso */
  req.varlist.elem[0].name.cmp[1] = 0x03; /* org */
  req.varlist.elem[0].name.cmp[2] = 0x06; /* dod */
  req.varlist.elem[0].name.cmp[3] = 0x01; /* internet */
  req.varlist.elem[0].name.cmp[4] = 0x02; /* mgmt */
  req.varlist.elem[0].name.cmp[5] = 0x01; /* mib */
  req.varlist.elem[0].name.cmp[6] = 0x01; /* system */
  req.varlist.elem[0].name.cmp[7] = 0x01; /* sysDescr */
  req.varlist.elem[0].name.cmp[10]= 0x00; /* instance */
  req.varlist.elem[0].name.ncmp = 9;	  /* number of components */
  req.varlist.elem[0].val.type = EMPTY;	  /* no values in request */

  req.varlist.elem[1].name.cmp[0] = 0x01; /* iso */
  req.varlist.elem[1].name.cmp[1] = 0x03; /* org */
  req.varlist.elem[1].name.cmp[2] = 0x06; /* dod */
  req.varlist.elem[1].name.cmp[3] = 0x01; /* internet */
  req.varlist.elem[1].name.cmp[4] = 0x04; /* enterprise */
  req.varlist.elem[1].name.cmp[5] = 0x01; /* mib */
  req.varlist.elem[1].name.cmp[6] = 0x14; /* MIT */
  req.varlist.elem[1].name.cmp[7] = 0x01; /* Athena */
  req.varlist.elem[1].name.cmp[8] = 0x03; /* status */
  req.varlist.elem[1].name.cmp[9] = 0x04; /* stLogin */
  req.varlist.elem[1].name.cmp[10]= 0x00; /* instance */
  req.varlist.elem[1].name.ncmp = 11;     /* number of components */
  req.varlist.elem[1].val.type = EMPTY;   /* no values in request */
}
