/*
 * Port. This file deals with the display screen. All of the formatting
 * and termcap stuff is here.
 *
 * Copyright 1992 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 *
 * Tom Coppeto
 * MIT Network Operations
 * 26 January 1992
 *
 *    $Source: /afs/.net.mit.edu/tools/src/port/RCS/display.c,v $
 *    $Author: nocuser $
 *    $Locker:  $
 * 
 */

#ifndef lint
static char *rcsid = "$Header: /afs/.net.mit.edu/tools/src/port/RCS/display.c,v 1.15 94/06/21 15:44:24 nocuser Exp $";
#endif

#include "port.h"
#include <sys/time.h>
#include <signal.h>
#include <setjmp.h>
#include <mit-copyright.h>

static jmp_buf ret;
static int ret_set = 0;
static jmp_buf more;
static int more_set = 0;
extern getreq reply;
#define MAX_THINGS 100      /* we will lose here ! */

static char termbuf[BUFSIZ];
static char *termptr = termbuf;
static char cpbuf[BUFSIZ];
static char *cp = (char *) NULL;
extern char *BC;
extern char PC;
static char *CM;           /* cursor move */
static char *CL;           /* clear screen & home cursor */
static char *HC;           /* home cursor */
static char *UO;           /* up one line */
static char *DO;           /* down one line */
static int   LI;           /* down one line */

static int dumb_term = 0;
static int locked    = 1;
static int page      = 1;

static char     *descr;
double avexp = 0;

struct stats
{
  int      n;
  time_t   pre_time[MAX_THINGS];
  int      pre_tot_pkts[MAX_THINGS];
  int      pre_xmit_colls[MAX_THINGS];
  int      pre_rec_colls[MAX_THINGS];

  int      pre_tot_inbytes[MAX_THINGS];
  int      pre_tot_outbytes[MAX_THINGS];
  int      pre_tot_inpkts[MAX_THINGS];
  int      pre_tot_outpkts[MAX_THINGS];
  int      pre_tot_inucasts[MAX_THINGS];
  int      pre_tot_outucasts[MAX_THINGS];
  int      pre_tot_innucasts[MAX_THINGS];
  int      pre_tot_outnucasts[MAX_THINGS];
  int      pre_tot_inerrors[MAX_THINGS];
  int      pre_tot_outerrors[MAX_THINGS];
  int      pre_tot_indiscards[MAX_THINGS];
  int      pre_tot_outdiscards[MAX_THINGS];
  int      pre_tot_outqlens[MAX_THINGS];

  int      del_tot_pkts[MAX_THINGS];
  int      del_xmit_colls[MAX_THINGS];
  int      del_rec_colls[MAX_THINGS];

  int      del_tot_inbytes[MAX_THINGS];
  int      del_tot_outbytes[MAX_THINGS];
  int      del_tot_inpkts[MAX_THINGS];
  int      del_tot_outpkts[MAX_THINGS];
  int      del_tot_inucasts[MAX_THINGS];
  int      del_tot_outucasts[MAX_THINGS];
  int      del_tot_innucasts[MAX_THINGS];
  int      del_tot_outnucasts[MAX_THINGS];
  int      del_tot_inerrors[MAX_THINGS];
  int      del_tot_outerrors[MAX_THINGS];
  int      del_tot_indiscards[MAX_THINGS];
  int      del_tot_outdiscards[MAX_THINGS];
  int      del_tot_outqlens[MAX_THINGS];

  int      ave1_tot_pkts[MAX_THINGS];
  int      ave1_xmit_colls[MAX_THINGS];
  int      ave1_rec_colls[MAX_THINGS];

  int      ave1_tot_inbytes[MAX_THINGS];
  int      ave1_tot_outbytes[MAX_THINGS];
  int      ave1_tot_inpkts[MAX_THINGS];
  int      ave1_tot_outpkts[MAX_THINGS];
  int      ave1_tot_inucasts[MAX_THINGS];
  int      ave1_tot_outucasts[MAX_THINGS];
  int      ave1_tot_innucasts[MAX_THINGS];
  int      ave1_tot_outnucasts[MAX_THINGS];
  int      ave1_tot_inerrors[MAX_THINGS];
  int      ave1_tot_outerrors[MAX_THINGS];
  int      ave1_tot_indiscards[MAX_THINGS];
  int      ave1_tot_outdiscards[MAX_THINGS];
  int      ave1_tot_outqlens[MAX_THINGS];

  int      ave2_tot_pkts[MAX_THINGS];
  int      ave2_xmit_colls[MAX_THINGS];
  int      ave2_rec_colls[MAX_THINGS];
 
  int      ave2_tot_inbytes[MAX_THINGS];
  int      ave2_tot_outbytes[MAX_THINGS];
  int      ave2_tot_inpkts[MAX_THINGS];
  int      ave2_tot_outpkts[MAX_THINGS];
  int      ave2_tot_inucasts[MAX_THINGS];
  int      ave2_tot_outucasts[MAX_THINGS];
  int      ave2_tot_innucasts[MAX_THINGS];
  int      ave2_tot_outnucasts[MAX_THINGS];
  int      ave2_tot_inerrors[MAX_THINGS];
  int      ave2_tot_outerrors[MAX_THINGS];
  int      ave2_tot_indiscards[MAX_THINGS];
  int      ave2_tot_outdiscards[MAX_THINGS];
  int      ave2_tot_outqlens[MAX_THINGS];

  int      ave3_tot_pkts[MAX_THINGS];
  int      ave3_xmit_colls[MAX_THINGS];
  int      ave3_rec_colls[MAX_THINGS];

  int      ave3_tot_inbytes[MAX_THINGS];
  int      ave3_tot_outbytes[MAX_THINGS];
  int      ave3_tot_inpkts[MAX_THINGS];
  int      ave3_tot_outpkts[MAX_THINGS];
  int      ave3_tot_inucasts[MAX_THINGS];
  int      ave3_tot_outucasts[MAX_THINGS];
  int      ave3_tot_innucasts[MAX_THINGS];
  int      ave3_tot_outnucasts[MAX_THINGS];
  int      ave3_tot_inerrors[MAX_THINGS];
  int      ave3_tot_outerrors[MAX_THINGS];
  int      ave3_tot_indiscards[MAX_THINGS];
  int      ave3_tot_outdiscards[MAX_THINGS];
  int      ave3_tot_outqlens[MAX_THINGS];

  int      items[MAX_THINGS];
  int      types[MAX_THINGS];
  char    *descs[MAX_THINGS];
  int      speeds[MAX_THINGS];
  int      mtus[MAX_THINGS];
  int      timeouts[MAX_THINGS];

  int      cur_tot_pkts;
  int      cur_xmit_colls;
  int      cur_rec_colls;

  int      cur_tot_inbytes[MAX_THINGS];
  int      cur_tot_outbytes[MAX_THINGS];
  int      cur_tot_inpkts[MAX_THINGS];
  int      cur_tot_outpkts[MAX_THINGS];
  int      cur_tot_inucasts[MAX_THINGS];
  int      cur_tot_outucasts[MAX_THINGS];
  int      cur_tot_innucasts[MAX_THINGS];
  int      cur_tot_outnucasts[MAX_THINGS];
  int      cur_tot_inerrors[MAX_THINGS];
  int      cur_tot_outerrors[MAX_THINGS];
  int      cur_tot_indiscards[MAX_THINGS];
  int      cur_tot_outdiscards[MAX_THINGS];
  int      cur_tot_outqlens[MAX_THINGS];

  time_t   cur_time;
};


static int really_locked = 0;
int current_selection    = -1;
static int mode          = 0;
static int margin        = 12;
static char *mode_str[] = {"per second", 
			     "per second (1 min av.)",
			     "per second (5 min av.)", 
			     "per second (15 min av.)"};
struct stats agent_stats;
struct stats board_stats;
struct stats port_stats;
struct stats total_stats;

int      uptime                     = 0;
int      ostatus[MAX_THINGS];
int      astatus[MAX_THINGS];
int      lstatus[MAX_THINGS];

static void onintr();
static void restore_intr();
static struct   itimerval interval;
static struct   itimerval disable;
static void (*previous_signal)();
static int siginit = 0;


int
determine_vendor(agent)
     Agent *agent;
{
  objident *o;
  caddr_t dat;

  o = &vSysDescr;
  if(!(dat = make_snmp_query(agent, o)))
    return(0);

  if(strncasecmp(dat, "asantehub 2072", 14) == 0)
    agent->vendor = ASANTE2072;
  else
    if(strncasecmp(dat, "asantehub 1012", 14) == 0)
      agent->vendor = ASANTE;
  else
    if(strncasecmp(dat, "MRXI", 4) == 0)
      agent->vendor = CABLETRON;
  else
    if(strncasecmp(dat, "IRM", 3) == 0)
      agent->vendor = CABLETRON;
  else
    if(strncasecmp(dat, "MMAC", 4) == 0)
      agent->vendor = CABLETRON;
  else
    if(strncasecmp(dat, "Cabletron", 9) == 0)
      agent->vendor = CABLETRON;
  else
      agent->vendor = MIB2;
  return(agent->vendor);
}


display_agents(agents)
     Agent **agents;
{
  Agent    *agent;
  objident *obj[SNMPMAXVARS+1];
  caddr_t  *dat           = (caddr_t *) NULL;
  caddr_t  datt           = (caddr_t) NULL;
  int      len            = 0;
  int      i              = 0;
  int      a              = 0;
  int      p              = 0;
  int      o              = 0;
  unsigned int number     = 0;
  int      skip_sleep     = 1;
  char     c[2];
  getreq   save;

  init_screen();
  clear_agent_stats();
  bzero(c, sizeof(c));
  bzero(&interval, sizeof(interval));
  bzero(&disable,  sizeof(disable));
  previous_signal = (void *) signal(SIGINT,  restore_intr);
  siginit = 1;
  raw_mode();
  if(setjmp(ret))
    return(1);
  else
    ret_set = 1;
  
  while(1)
    {
      a = 0;
      agent_stats.cur_time = time(0);
      dpy_home();
      display_agent_header();	  

      while(agents[a])
	{
	  agent = agents[a];
	  agent_stats.items[a] = a+1;

	  if(!agent->vendor)
	    {
	      if(!determine_vendor(agent))
		{
		  agent_stats.timeouts[a] = 1;
		  display_agent_data(agent, a);
		  ++a;
		  continue;
		}
	      else
		agent_stats.timeouts[a] = 0;
	    }
	      
	if(agent->vendor == MIB2)
        {

      o = 0;      
      obj[o++] = &vIfSpeed;
      obj[o++] = &vIfInOctets;
      obj[o++] = &vIfOutOctets;
      obj[o++] = &vIfInUcastPkts;
      obj[o++] = &vIfOutUcastPkts;
      obj[o++] = &vIfInNUcastPkts;
      obj[o++] = &vIfOutNUcastPkts;
      obj[o++] = &vIfInDiscards;
      obj[o++] = &vIfOutDiscards;
      obj[o++] = &vIfInErrors;
      obj[o++] = &vIfOutErrors;
      obj[o++] = (objident *) NULL;
      
	  vIfSpeed.ncmp--;	  
	  datt = make_snmp_next(agent, obj[0]);	  
	  vIfSpeed.ncmp++;

	  if(!datt)
	    {
	          agent_stats.timeouts[a] = 1;
	          display_agent_data(agent, a);
	          ++a;
	          continue;
	    }

          agent_stats.speeds[a] = 0;
          agent_stats.cur_tot_inbytes[a] = 0;
          agent_stats.cur_tot_outbytes[a] = 0;
          agent_stats.cur_tot_inucasts[a] = 0;
          agent_stats.cur_tot_outucasts[a] = 0;
          agent_stats.cur_tot_innucasts[a] = 0;
          agent_stats.cur_tot_outnucasts[a] = 0;
          agent_stats.cur_tot_indiscards[a] = 0;
          agent_stats.cur_tot_outdiscards[a] = 0;
          agent_stats.cur_tot_inerrors[a] = 0;
          agent_stats.cur_tot_outerrors[a] = 0;

      while(datt)
	{
	      if(oidncmp(obj[0], &(reply.varlist.elem[0].name),
			 vIfSpeed.ncmp - 1) != 0)
		break;	  
	      p = reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-1];

	  vIfSpeed.cmp[vIfSpeed.ncmp-1]                 = p;
	  vIfInOctets.cmp[vIfInOctets.ncmp-1]           = p;
	  vIfOutOctets.cmp[vIfOutOctets.ncmp-1]         = p;
	  vIfInUcastPkts.cmp[vIfInUcastPkts.ncmp-1]     = p;
	  vIfOutUcastPkts.cmp[vIfOutUcastPkts.ncmp-1]   = p;
	  vIfInNUcastPkts.cmp[vIfInNUcastPkts.ncmp-1]   = p;
	  vIfOutNUcastPkts.cmp[vIfOutNUcastPkts.ncmp-1] = p;
	  vIfInDiscards.cmp[vIfInDiscards.ncmp-1]       = p;
	  vIfOutDiscards.cmp[vIfOutDiscards.ncmp-1]     = p;
	  vIfInErrors.cmp[vIfInErrors.ncmp-1]           = p;
	  vIfOutErrors.cmp[vIfOutErrors.ncmp-1]         = p;

	  if(!(dat = make_lots_o_snmp_queries(agent, obj)))
	    {
	          agent_stats.timeouts[a] = 1;
	          display_agent_data(agent, a);
	          ++a;
	          continue;
	    }
	  else
	  {
	    if(agent_stats.timeouts[a] == 1)
	      agent_stats.timeouts[a] = 2;
	    else
	      agent_stats.timeouts[a] = 0;
	 }

	  o = 0;
	  bcopy(dat[o++], &number, sizeof(number));
          agent_stats.speeds[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_inbytes[a] += number/1024;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_outbytes[a] += number/1024;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_inucasts[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_outucasts[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_innucasts[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_outnucasts[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_indiscards[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_outdiscards[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_inerrors[a] += number;
          bcopy(dat[o++], &number, sizeof(number));
          agent_stats.cur_tot_outerrors[a] += number;

           if(agent_stats.pre_time[a] && 
	     (agent_stats.cur_time != agent_stats.pre_time[a]))
	    {
	      agent_stats.del_tot_inbytes[a]   = 
		(agent_stats.cur_tot_inbytes[a]   - 
		agent_stats.pre_tot_inbytes[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_outbytes[a]   = 
		(agent_stats.cur_tot_outbytes[a]   - 
		agent_stats.pre_tot_outbytes[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_inucasts[a]   = 
		(agent_stats.cur_tot_inucasts[a]   - 
		agent_stats.pre_tot_inucasts[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_outucasts[a]   = 
		(agent_stats.cur_tot_outucasts[a]   - 
		agent_stats.pre_tot_outucasts[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_innucasts[a]   = 
		(agent_stats.cur_tot_innucasts[a]   - 
		agent_stats.pre_tot_innucasts[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_outnucasts[a]   = 
		(agent_stats.cur_tot_outnucasts[a]   - 
		agent_stats.pre_tot_outnucasts[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_indiscards[a]   = 
		(agent_stats.cur_tot_indiscards[a]   - 
		agent_stats.pre_tot_indiscards[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_outdiscards[a]   = 
		(agent_stats.cur_tot_outdiscards[a]   - 
		agent_stats.pre_tot_outdiscards[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_inerrors[a]   = 
		(agent_stats.cur_tot_inerrors[a]   - 
		agent_stats.pre_tot_inerrors[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_outerrors[a]   = 
		(agent_stats.cur_tot_outerrors[a]   - 
		agent_stats.pre_tot_outerrors[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	      agent_stats.del_tot_outqlens[a]   = 
		(agent_stats.cur_tot_outqlens[a]  - 
		agent_stats.pre_tot_outqlens[a])   
		/ (agent_stats.cur_time     - agent_stats.pre_time[a]);

	    }

	  agent_stats.pre_tot_inbytes[a]     = agent_stats.cur_tot_inbytes[a];
	  agent_stats.pre_tot_outbytes[a]    = agent_stats.cur_tot_outbytes[a];
	  agent_stats.pre_tot_inucasts[a]    = agent_stats.cur_tot_inucasts[a];
	  agent_stats.pre_tot_outucasts[a]   = agent_stats.cur_tot_outucasts[a];
	  agent_stats.pre_tot_innucasts[a]   = agent_stats.cur_tot_innucasts[a];
	  agent_stats.pre_tot_outnucasts[a]  = agent_stats.cur_tot_outnucasts[a];
	  agent_stats.pre_tot_inerrors[a]    = agent_stats.cur_tot_inerrors[a];
	  agent_stats.pre_tot_outerrors[a]   = agent_stats.cur_tot_outerrors[a];
	  agent_stats.pre_tot_indiscards[a]  = agent_stats.cur_tot_indiscards[a];
	  agent_stats.pre_tot_outdiscards[a] = agent_stats.cur_tot_outdiscards[a];

	  if(!agent_stats.pre_time[a] || 
	     (agent_stats.cur_time == agent_stats.pre_time[a]))
	    {
	      if((a == 0) && (p == 0))
		printf("porting...\n");
	      agent_stats.pre_time[a] = agent_stats.cur_time;
	      datt = make_snmp_next(agent, obj[0]);
	      skip_sleep = 1;
	      continue;
	    }

	      if(!(datt = make_snmp_next(agent, obj[0])))
		{
	      agent_stats.timeouts[a] = 1;
	      display_agent_data(agent, a);
	      ++a;
	      continue;
		}
	     else
	       datt = (caddr_t) NULL;
	}  

	  avexp = (double) calculate_ave_exponent(agent_stats.cur_time 
					       - agent_stats.pre_time[a], 60);
	  average(&agent_stats.ave1_tot_inbytes[a],   
		  agent_stats.del_tot_inbytes[a],   avexp);
	  average(&agent_stats.ave1_tot_outbytes[a],   
		  agent_stats.del_tot_outbytes[a],   avexp);
	  average(&agent_stats.ave1_tot_inucasts[a],   
		  agent_stats.del_tot_inucasts[a],   avexp);
	  average(&agent_stats.ave1_tot_outucasts[a],   
		  agent_stats.del_tot_outucasts[a],   avexp);
	  average(&agent_stats.ave1_tot_innucasts[a],   
		  agent_stats.del_tot_innucasts[a],   avexp);
	  average(&agent_stats.ave1_tot_outnucasts[a],   
		  agent_stats.del_tot_outnucasts[a],   avexp);
	  average(&agent_stats.ave1_tot_inerrors[a],   
		  agent_stats.del_tot_inerrors[a],   avexp);
	  average(&agent_stats.ave1_tot_outerrors[a],   
		  agent_stats.del_tot_outerrors[a],   avexp);
	  average(&agent_stats.ave1_tot_indiscards[a],   
		  agent_stats.del_tot_indiscards[a],   avexp);
	  average(&agent_stats.ave1_tot_outdiscards[a],   
		  agent_stats.del_tot_outdiscards[a],   avexp);
	  average(&agent_stats.ave1_tot_outqlens[a],   
		  agent_stats.del_tot_outqlens[a],   avexp);
	  
	  avexp = (double) calculate_ave_exponent(agent_stats.cur_time 
					       - agent_stats.pre_time[a], 300);

	  average(&agent_stats.ave2_tot_inbytes[a],   
		  agent_stats.del_tot_inbytes[a],   avexp);
	  average(&agent_stats.ave2_tot_outbytes[a],   
		  agent_stats.del_tot_outbytes[a],   avexp);
	  average(&agent_stats.ave2_tot_inucasts[a],   
		  agent_stats.del_tot_inucasts[a],   avexp);
	  average(&agent_stats.ave2_tot_outucasts[a],   
		  agent_stats.del_tot_outucasts[a],   avexp);
	  average(&agent_stats.ave2_tot_innucasts[a],   
		  agent_stats.del_tot_innucasts[a],   avexp);
	  average(&agent_stats.ave2_tot_outnucasts[a],   
		  agent_stats.del_tot_outnucasts[a],   avexp);
	  average(&agent_stats.ave2_tot_inerrors[a],   
		  agent_stats.del_tot_inerrors[a],   avexp);
	  average(&agent_stats.ave2_tot_outerrors[a],   
		  agent_stats.del_tot_outerrors[a],   avexp);
	  average(&agent_stats.ave2_tot_indiscards[a],   
		  agent_stats.del_tot_indiscards[a],   avexp);
	  average(&agent_stats.ave2_tot_outdiscards[a],   
		  agent_stats.del_tot_outdiscards[a],   avexp);
	  average(&agent_stats.ave2_tot_outqlens[a],   
		  agent_stats.del_tot_outqlens[a],   avexp);
	  
	  avexp = (double) calculate_ave_exponent(agent_stats.cur_time 
					       - agent_stats.pre_time[a],1500);
	  average(&agent_stats.ave3_tot_inbytes[a],   
		  agent_stats.del_tot_inbytes[a],   avexp);
	  average(&agent_stats.ave3_tot_outbytes[a],   
		  agent_stats.del_tot_outbytes[a],   avexp);
	  average(&agent_stats.ave3_tot_inucasts[a],   
		  agent_stats.del_tot_inucasts[a],   avexp);
	  average(&agent_stats.ave3_tot_outucasts[a],   
		  agent_stats.del_tot_outucasts[a],   avexp);
	  average(&agent_stats.ave3_tot_innucasts[a],   
		  agent_stats.del_tot_innucasts[a],   avexp);
	  average(&agent_stats.ave3_tot_outnucasts[a],   
		  agent_stats.del_tot_outnucasts[a],   avexp);
	  average(&agent_stats.ave3_tot_inerrors[a],   
		  agent_stats.del_tot_inerrors[a],   avexp);
	  average(&agent_stats.ave3_tot_outerrors[a],   
		  agent_stats.del_tot_outerrors[a],   avexp);
	  average(&agent_stats.ave3_tot_indiscards[a],   
		  agent_stats.del_tot_indiscards[a],   avexp);
	  average(&agent_stats.ave3_tot_outdiscards[a],   
		  agent_stats.del_tot_outdiscards[a],   avexp);
	  average(&agent_stats.ave3_tot_outqlens[a],   
		  agent_stats.del_tot_outqlens[a],   avexp);

	  agent_stats.pre_time[a] = agent_stats.cur_time;
	  display_agent_data(agent, a);
	  ++a;
       }
        else
        {
	  o = 0;	  
	  obj[o++] = &vDeviceType[agent->vendor];
	  obj[o++] = &vDeviceTotalPkts[agent->vendor];
	  obj[o++] = &vDeviceXmitColls[agent->vendor];
	  obj[o++] = &vDeviceRecColls[agent->vendor];
	  obj[o++] = (objident *) NULL;


	  if(!(dat = make_lots_o_snmp_queries(agent, obj)))
	    {
	      agent_stats.timeouts[a] = 1;
	      display_agent_data(agent, a);
	      ++a;
	      continue;
	    }
	  else
	    if(agent_stats.timeouts[a] == 1)
	      agent_stats.timeouts[a] = 2;
	    else
	      if(agent_stats.timeouts[a] == 2)
		agent_stats.timeouts[a] = 0;

	  o = 0;
	  bcopy(dat[o++], &agent_stats.types[a], 
		sizeof(agent_stats.types[a]));
	  bcopy(dat[o++], &agent_stats.cur_tot_pkts, 
		sizeof(agent_stats.cur_tot_pkts));
	  bcopy(dat[o++], &agent_stats.cur_xmit_colls, 
		sizeof(agent_stats.cur_xmit_colls));
	  bcopy(dat[o++], &agent_stats.cur_rec_colls,   
		sizeof(agent_stats.cur_rec_colls));
	  

	  if(agent_stats.pre_time[a] &&
	     (agent_stats.cur_time != agent_stats.pre_time[a]))
	    {
	      agent_stats.del_tot_pkts[a]   = 
		(agent_stats.cur_tot_pkts   - agent_stats.pre_tot_pkts[a])   
		  / (agent_stats.cur_time   - agent_stats.pre_time[a]);
	      agent_stats.del_xmit_colls[a] = 100 *
		(agent_stats.cur_xmit_colls - agent_stats.pre_xmit_colls[a]) 
		  / (agent_stats.cur_time   - agent_stats.pre_time[a]);
	      agent_stats.del_rec_colls[a]  = 100 *
		(agent_stats.cur_rec_colls  - agent_stats.pre_rec_colls[a])  
		  / (agent_stats.cur_time   - agent_stats.pre_time[a]);
	    }
	  
	  agent_stats.pre_tot_pkts[a]   = agent_stats.cur_tot_pkts;
	  agent_stats.pre_xmit_colls[a] = agent_stats.cur_xmit_colls;
	  agent_stats.pre_rec_colls[a]  = agent_stats.cur_rec_colls;
	  
	  if(!agent_stats.pre_time[a] || 
	     (agent_stats.cur_time == agent_stats.pre_time[a]))
	    {
	      if(a == 0)
		printf("porting...\n");
	      agent_stats.pre_time[a] = agent_stats.cur_time;
	      ++a;
	      skip_sleep = 1;
	     	      continue;
	    }
	  
	  avexp = (double) calculate_ave_exponent(agent_stats.cur_time 
					       - agent_stats.pre_time[a], 60);
	  average(&agent_stats.ave1_tot_pkts[a],
		  agent_stats.del_tot_pkts[a],   avexp);
	  average(&agent_stats.ave1_xmit_colls[a], 
		  agent_stats.del_xmit_colls[a], avexp);
	  average(&agent_stats.ave1_rec_colls[a],  
		  agent_stats.del_rec_colls[a],  avexp);
	  
	  avexp = (double) calculate_ave_exponent(agent_stats.cur_time 
					       - agent_stats.pre_time[a], 300);
	  average(&agent_stats.ave2_tot_pkts[a],   
		  agent_stats.del_tot_pkts[a],   avexp);
	  average(&agent_stats.ave2_xmit_colls[a], 
		  agent_stats.del_xmit_colls[a], avexp);
	  average(&agent_stats.ave2_rec_colls[a],  
		  agent_stats.del_rec_colls[a],  avexp);
	  
	  avexp = (double) calculate_ave_exponent(agent_stats.cur_time 
					       - agent_stats.pre_time[a],1500);
	  average(&agent_stats.ave3_tot_pkts[a],   
		  agent_stats.del_tot_pkts[a],   avexp);
	  average(&agent_stats.ave3_xmit_colls[a], 
		  agent_stats.del_xmit_colls[a], avexp);
	  average(&agent_stats.ave3_rec_colls[a],  
		  agent_stats.del_rec_colls[a],  avexp);
	  
	  agent_stats.pre_time[a] = agent_stats.cur_time;
	  display_agent_data(agent, a);
	  ++a;
	}  
      }

      agent_stats.n = a;
      
      if(!skip_sleep)
	{
	  display_agent_footer(agent);
	  dpy_end();
restart:
	  if(setjmp(more))	    
	    continue;
	  else
	    more_set = 1;
	  
	  signal(SIGALRM, onintr);
	  interval.it_value.tv_sec = the_update;
	  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
	  
	  while(*c = getchar())
	    {
	      raw_mode();
	      if(*c == '\014')
		{
		  refresh_agent_stats(agents);
		  continue;
		}

	      if(*c == '\020')
		{
		  up_agent_marker(agents);
		  continue;
		}

	      if(*c == '\016')
		{
		  down_agent_marker(agents);
		  continue;
		}

	      if(*c == '\006')
                {
                  ++page;
                  if(page > (((agent_stats.n - 1)/ (LI - margin)) + 1))
                    page = 1;
                  if(current_selection >= 0)
                    current_selection = -1;
                  refresh_agent_stats(agents);
                  continue;
                }

	      if(*c == '\002')
                {
                  --page;
                  if(page < 1)
                    page = ((agent_stats.n - 1) / (LI - 12)) + 1;
                  if(current_selection >= 0)
                    current_selection = -1;
                  refresh_agent_stats(agents);
                  continue;
                }

	      if(isdigit(*c))
		{
		  o = atoi(c);
		  if((o > 0) && (o <= agent_stats.n))
		    {
		      setitimer(ITIMER_REAL, &disable, 
				(struct itimerval *) NULL);
		      if(display_boards(agents[o-1]) == 1)
			{
			  restore();
			  return(1);
			}
		      refresh_agent_stats(agents);
		      raw_mode();
		      goto restart;
		    }
		}
	      if(((*c == '\n') || (*c == '\r')) && (current_selection >= 0))
		{
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  if(display_boards(agents[current_selection]) == 1)
		    {
		      restore();
		      return(1);
		    }
		  
		  refresh_agent_stats(agents);
		  raw_mode();
		  goto restart;
		}
	      
	      if((*c == 'R') && !locked)
		restart_agent(agent);
	      else
		if(*c == 'R')
		  {
		    really_locked = 1;
		    dpy_home();
		    display_agent_header();
		    dpy_end();
		    continue;
		  }
	      
	      if((*c == 'q') || (*c == ' '))
		break;
	      
	      if(*c == 'U')
		{
		  locked = 0;
		  dpy_home();
		  display_agent_header();
		  dpy_end();
		}
	      
	      if((*c == 'l') || (*c == 'L'))
		{
		  locked = 1;
		  dpy_home();
		  display_agent_header();
		  dpy_end();
		}
	      
	      if(*c == 't')
		{
		  ++mode;
		  if(mode > 3)
		    mode = 0;
		  refresh_agent_stats(agents);
		}
	      
	      if(*c == '?')
		{
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  clear_screen();
		  printf("KEY MAPPINGS \n\n");
		  printf("\t L       \t lock against agent writes\n");
		  printf("\t U       \t unlock to enable agent writes\n");
		  printf("\t R       \t reset agent\n");
		  printf("\t t       \t toggle display mode\n");
		  putchar('\n'); 
		  printf("\t ^L      \t refresh screen\n");
		  printf("\t ^F      \t forward page\n");
		  printf("\t ^B      \t back page\n");
		  printf("\t ^N      \t select next agent\n");
		  printf("\t ^P      \t select previous agent\n");
		  printf("\t <n>     \t display agent n\n");	       
		  printf("\t <space> \t update screen\n");
		  printf("\t <return>\t goto selected agent\n");
		  putchar('\n');
		  printf("\t q       \t quit display mode\n");
		  printf("\t ?       \t help screen\n");
		  printf("\nhit any key to continue... ");
		  getchar();
		  stuff();
		  refresh_agent_stats(agents);
		  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
		  continue;
		} 
	    }
	  
	  if(*c == 'q')
	    {
	      restore();
	      return(1);
	    }

	  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);	 
	}
      else
	{
	  skip_sleep = 0;
	  sleep(1);
	}
    }
}




display_agent_header()
{
  char buf[64];

  printf("port %75s\n", ctime(&agent_stats.cur_time));
  sprintf(buf, " (agent %2d)", agent_stats.items[current_selection]);
  printf("AGENT SUMMARIES%-16s%-31s%17s\n\n", current_selection >= 0 ? buf:" ",
	 mode_str[mode], really_locked ? "write PROTECT" :
	 locked ? "write protect" : "WRITE ENABLE");
  printf(" agent                    packets      transmit coll       receive coll \n");
  really_locked = 0;
}



display_agent_data(agent, index)
     Agent *agent;
     int index;
{
  char     buf1[16];
  char     buf2[16];
  char     buf3[16];
  char     buf4[16];

  if((index < ((page - 1) * (LI - margin))) || 
     (index >= (page * (LI - margin))))
    return;

  if(agent_stats.timeouts[index] > 0) 
    {
      printf( "%s%-3d %-20s %-10s   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index],
	     agent->alias,  "*", "*", "*", "*", "*");
      return;
    }


  if(agent->vendor == MIB2)
  {
  if(mode == 0)
    {
      sprintf(buf1, "%-3.2f%%", (double) (800 * (agent_stats.del_tot_inbytes[index] + agent_stats.del_tot_outbytes[index])) / agent_stats.speeds[index]);
      printf( "%s%-3d %-20s %-10d %-5s  %-5d %-8s %-10d %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias, 
	     agent_stats.del_tot_inucasts[index] + 
	     agent_stats.del_tot_innucasts[index], buf1,
	     agent_stats.del_tot_inerrors[index], "",
	     agent_stats.del_tot_outerrors[index], "");
    }

  if(mode == 1)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave1_xmit_colls[index] 
	      / agent_stats.ave1_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave1_rec_colls[index]
	      / agent_stats.ave1_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.ave1_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.ave1_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias,
	     agent_stats.ave1_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 2)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave2_xmit_colls[index] 
	      / agent_stats.ave2_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave2_rec_colls[index]
	      / agent_stats.ave2_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.ave2_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.ave2_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias,
	     agent_stats.ave2_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
  
  if(mode == 3)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave3_xmit_colls[index] 
	      / agent_stats.ave3_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave3_rec_colls[index]
	      / agent_stats.ave3_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.ave3_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.ave3_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias,
	     agent_stats.ave3_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
  }

  else 

  {
  if(mode == 0)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.del_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.del_xmit_colls[index] 
	      / agent_stats.del_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.del_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.del_rec_colls[index]
	      / agent_stats.del_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.del_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.del_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias, 
	     agent_stats.del_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 1)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave1_xmit_colls[index] 
	      / agent_stats.ave1_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave1_rec_colls[index]
	      / agent_stats.ave1_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.ave1_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.ave1_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias,
	     agent_stats.ave1_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 2)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave2_xmit_colls[index] 
	      / agent_stats.ave2_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave2_rec_colls[index]
	      / agent_stats.ave2_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.ave2_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.ave2_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias,
	     agent_stats.ave2_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
  
  if(mode == 3)
    {
      sprintf(buf1, "%-3.2f%%", agent_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave3_xmit_colls[index] 
	      / agent_stats.ave3_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", agent_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) agent_stats.ave3_rec_colls[index]
	      / agent_stats.ave3_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) agent_stats.ave3_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) agent_stats.ave3_rec_colls[index]/100);
      printf( "%s%-3d %-20s %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     agent_stats.items[index], agent->alias,
	     agent_stats.ave3_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
  }
}



display_agent_footer(agent)
     Agent *agent;
{
  char buf[64];

  printf("\n\n");
  sprintf(buf, "page %d of %d", page, agent_stats.n/(LI - margin) + 1);
  printf("%42s\n", buf); 
}


refresh_agent_stats(agents)
     Agent **agents;
{
  int i;
  
  clear_screen();
  display_agent_header();
  for(i = 0; i < agent_stats.n; i++)
    display_agent_data(agents[i], i);
  display_agent_footer(agents[i]);
  dpy_end();
}


clear_agent_stats()
{
  bzero(&agent_stats, sizeof(agent_stats));
  page = 1;
  current_selection = -1;
  descr = (char *) NULL;
}


up_agent_marker(agents)
     Agent **agents;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; ++i)
	downline();
      putchar(' ');
      current_selection--;
    }

  if(current_selection < 0)
    {
      current_selection = agent_stats.n - 1;
      page =  ((agent_stats.n - 1)/(LI - margin)) + 1;
      refresh_agent_stats(agents);
      return;
    }

   if(current_selection < top)
    {
      page--;
      refresh_agent_stats(agents);
      return;
    }

  move_cursor_to_data();
  for(i = top; i <= current_selection; i++)
    downline();

  putchar('*');
  dpy_home();
  display_agent_header();
  dpy_end();
}



down_agent_marker(agents)
     Agent **agents;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; i++)
	downline();
      putchar(' ');
    }

  downline();
  current_selection++;
  if(current_selection >= agent_stats.n)
    {
      current_selection = 0;
      page = 1;
      refresh_agent_stats(agents);
      return;
    }

   if(current_selection >= bottom)
    {
      page++;
      if(page > ((agent_stats.n - 1)/(LI - margin) + 1))
        page = 1;
      refresh_agent_stats(agents);
      return;
    }


  putchar('*');
  dpy_home();
  display_agent_header();
  dpy_end();
}




display_boards(agent)
     Agent *agent;
{
  objident *obj[SNMPMAXVARS];
  caddr_t  *dat           = (caddr_t *) NULL;
  caddr_t  datt           = (caddr_t) NULL;
  int      len            = 0;
  int      i              = 0;
  int      b              = 0;
  int      o              = 0;
  int      knowit         = 0;
  int      skip_sleep     = 1;
  int      nslots;
  char     c1;
  char     c[2];
  getreq   save;

  init_screen();
  clear_board_stats();
  bzero(c, sizeof(c));
  bzero(&interval, sizeof(interval));
  bzero(&disable,  sizeof(disable));
  if(!siginit)
    {
      previous_signal = (void *) signal(SIGINT,  restore_intr);
      siginit = 1;
    }
  raw_mode();
  if(setjmp(ret))
    return(1);
  else
    ret_set = 1;

  while(1)
    {
      dpy_home();

      if(!agent->vendor)
	{
	  if(!determine_vendor(agent))
	    {
	      descr = "*";
	      uptime = -1;
	    }
	}

      if(agent->vendor == MIB2)
	return(display_interfaces(agent));

      o = 0;
      obj[o++] = &vSysUptime;
      obj[o++] = &vSysDescr;
      obj[o++] = &vDeviceOccSlots[agent->vendor];
      obj[o++] = (objident *) NULL;
      dat = make_lots_o_snmp_queries(agent, obj);
      if(dat)
	{
	  o = 0;
	  bcopy(dat[o++], &uptime, sizeof(uptime));
	  descr = dat[o++];
	  bcopy(dat[o++], &c1, sizeof(c1));
	  nslots = (int) c1;
	}
      else
	{
	  descr = "*";
	  uptime = -1;
	}

      uptime /= 100;
      board_stats.cur_time = time(0);
      display_board_header(agent);

      vBoardType[agent->vendor].cmp[vBoardType[agent->vendor].ncmp - 1]              = 0;
      vBoardTotalPkts[agent->vendor].cmp[vBoardTotalPkts[agent->vendor].ncmp - 1]    = 0;
      vBoardXmitColls[agent->vendor].cmp[vBoardXmitColls[agent->vendor].ncmp - 1]    = 0;
      vBoardRecColls[agent->vendor].cmp[vBoardRecColls[agent->vendor].ncmp - 1]      = 0;
      
      o = 0;
      obj[o++] = &vBoardType[agent->vendor];
      obj[o++] = &vBoardTotalPkts[agent->vendor];
      obj[o++] = &vBoardXmitColls[agent->vendor];
      obj[o++] = &vBoardRecColls[agent->vendor];
      obj[o++] = (objident *) NULL;

      if(!knowit)
	{
	  vBoardType[agent->vendor].ncmp--;
	  vBoardTotalPkts[agent->vendor].ncmp--;
	  vBoardXmitColls[agent->vendor].ncmp--;
	  vBoardRecColls[agent->vendor].ncmp--;
	  
	  datt = make_snmp_next(agent, obj[0]);
	  
	  vBoardType[agent->vendor].ncmp++;
	  vBoardTotalPkts[agent->vendor].ncmp++;
	  vBoardXmitColls[agent->vendor].ncmp++;
	  vBoardRecColls[agent->vendor].ncmp++;
	  
	  if(!datt)
	    {
	      printf("no response from %s. unable to continue.\n", 
		     agent->alias);
	      restore();
	      sleep(3);
	      return(-1);
	    }
	}

      b = 0;
      while(datt || (knowit && (b < board_stats.n)))
	{
	  if(!knowit)
	    {
	      if(oidncmp(obj[0], &(reply.varlist.elem[0].name), 
			 vBoardType[agent->vendor].ncmp - 1) != 0)
		break;
	      if((agent->vendor == ASANTE) &&
		 !(power(reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-1]-1) & nslots))
		{
		  vBoardType[agent->vendor].cmp[vBoardType[agent->vendor].ncmp - 1] = reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-1];
		  bcopy(datt, &board_stats.types[b],
			sizeof(board_stats.types[b]));
		  goto skip;
		}

	      board_stats.items[b] = 
		reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-1];
	    }
	  
	  vBoardType[agent->vendor].cmp[vBoardType[agent->vendor].ncmp - 1]
	    = board_stats.items[b];
	  vBoardTotalPkts[agent->vendor].cmp[vBoardTotalPkts[agent->vendor].ncmp - 1]    
	    = board_stats.items[b];
	  vBoardXmitColls[agent->vendor].cmp[vBoardXmitColls[agent->vendor].ncmp - 1]    
	    = board_stats.items[b];
	  vBoardRecColls[agent->vendor].cmp[vBoardRecColls[agent->vendor].ncmp - 1]      
	    = board_stats.items[b];
	
	  if(!(dat = make_lots_o_snmp_queries(agent, obj)))
	    {
	      if(!knowit)
		{
		  printf("no response from %s. unable to continue.\n", 
			 agent->alias);
		  restore();
		  sleep(3);
		  return(-1);
		}
	      else
		{
		  board_stats.timeouts[b] = 1;
		  display_board_data(agent, b);
		  ++b;
		  continue;
		}
	    }
	  else
	    if(board_stats.timeouts[b] == 1)
	      board_stats.timeouts[b] = 2;
	    else
	      board_stats.timeouts[b] = 0;

	  o = 0;
	  bcopy(dat[o++], &board_stats.types[b],        
		sizeof(board_stats.types[b]));
	  bcopy(dat[o++], &board_stats.cur_tot_pkts,    
		sizeof(board_stats.cur_tot_pkts));
	  bcopy(dat[o++], &board_stats.cur_xmit_colls,  
		sizeof(board_stats.cur_xmit_colls));
	  bcopy(dat[o++], &board_stats.cur_rec_colls,   
		sizeof(board_stats.cur_rec_colls));
	  
	  if(board_stats.pre_time[b] &&
	     (board_stats.cur_time != board_stats.pre_time[b]))
	    {
	      board_stats.del_tot_pkts[b]   = 
		(board_stats.cur_tot_pkts   - board_stats.pre_tot_pkts[b])   
		  / (board_stats.cur_time   - board_stats.pre_time[b]);
	      board_stats.del_xmit_colls[b] = 100 *
		(board_stats.cur_xmit_colls - board_stats.pre_xmit_colls[b]) 
		  / (board_stats.cur_time   - board_stats.pre_time[b]);
	      board_stats.del_rec_colls[b]  = 100 *
		(board_stats.cur_rec_colls  - board_stats.pre_rec_colls[b])  
		  / (board_stats.cur_time   - board_stats.pre_time[b]);
	    }
	  
	  board_stats.pre_tot_pkts[b]   = board_stats.cur_tot_pkts;
	  board_stats.pre_xmit_colls[b] = board_stats.cur_xmit_colls;
	  board_stats.pre_rec_colls[b]  = board_stats.cur_rec_colls;

	  if(!board_stats.pre_time[b] || 
	     (board_stats.cur_time == board_stats.pre_time[b]))
	    {
	      if(b == 0)
		printf("gathering data...\n");
	      board_stats.pre_time[b] = board_stats.cur_time;
	      ++b;
	      if(!knowit)
		datt = make_snmp_next(agent, obj[0]);
	      else
		datt = (caddr_t) NULL;
	      skip_sleep = 1;
	      continue;
	    }
	    
	  avexp = (double) calculate_ave_exponent(board_stats.cur_time 
					       - board_stats.pre_time[b], 60);
	  average(&board_stats.ave1_tot_pkts[b],   
		  board_stats.del_tot_pkts[b],   avexp);
	  average(&board_stats.ave1_xmit_colls[b], 
		  board_stats.del_xmit_colls[b], avexp);
	  average(&board_stats.ave1_rec_colls[b],  
		  board_stats.del_rec_colls[b],  avexp);
	  
	  avexp = (double) calculate_ave_exponent(board_stats.cur_time 
					       - board_stats.pre_time[b], 300);
	  average(&board_stats.ave2_tot_pkts[b],   
		  board_stats.del_tot_pkts[b],   avexp);
	  average(&board_stats.ave2_xmit_colls[b], 
		  board_stats.del_xmit_colls[b], avexp);
	  average(&board_stats.ave2_rec_colls[b],  
		  board_stats.del_rec_colls[b],  avexp);
	  
	  avexp = (double) calculate_ave_exponent(board_stats.cur_time 
					       - board_stats.pre_time[b],1500);
	  average(&board_stats.ave3_tot_pkts[b],   
		  board_stats.del_tot_pkts[b],   avexp);
	  average(&board_stats.ave3_xmit_colls[b], 
		  board_stats.del_xmit_colls[b], avexp);
	  average(&board_stats.ave3_rec_colls[b],  
		  board_stats.del_rec_colls[b],  avexp);

	  board_stats.pre_time[b] = board_stats.cur_time;
	  display_board_data(agent, b);

skip:	  
	  if(!knowit)
	    {
	      if(!(datt = make_snmp_next(agent, obj[0])))
		{
		  printf("no response from %s.. unable to continue.\n", 
			 agent->alias);
		  restore();
		  sleep(3);		  
		  return(-1);
		}
	    }
	  else
	    datt = (caddr_t) NULL;
	  ++b;
	}  

      knowit = 1;
      board_stats.n = b;

      if(!skip_sleep)
	{
	  display_board_footer(agent);
	  dpy_end();
restart:   
	  if(setjmp(more))
	    continue;
	  else
	    more_set = 1;

	  signal(SIGALRM, onintr);
	  interval.it_value.tv_sec = the_update;
	  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);

	  while(*c = getchar())
	    {
	      raw_mode();
	      if(*c == '\014')
		{
		  refresh_board_stats(agent);
		  continue;
		}

	      if(*c == '\020')
		{
		  up_board_marker(agent);
		  continue;
		}

	      if(*c == '\016')
		{
		  down_board_marker(agent);
		  continue;
		}

              if(*c == '\006')
                {
                  ++page;
                  if(page > (((board_stats.n - 1)/ (LI - margin)) + 1))
                    page = 1;
                  if(current_selection >= 0)
                    current_selection = -1;
                  refresh_board_stats(agent);
                  continue;
                }

              if(*c == '\002')
                {
                  --page;
                  if(page < 1)
                    page = ((board_stats.n - 1) / (LI - 12)) + 1;
                  if(current_selection >= 0)
                    current_selection = -1;
                  refresh_board_stats(agent);
                  continue;
                }

	      if(isdigit(*c))
		{
		  o = atoi(c);
		  if(o > 0)
		    for(i = 0; i < b; ++i)
		      if(o == board_stats.items[i])
			{
			  setitimer(ITIMER_REAL, &disable, 
				    (struct itimerval *) NULL);
			  if(display_ports(agent, o) == 1)
			    {
			      restore();
			      return(1);
			    }
			  raw_mode();
			  refresh_board_stats(agent);
			  goto restart;
			}
		}
	
	      if(((*c == '\n') || (*c == '\r')) && (current_selection >= 0))
		{
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  if(display_ports(agent, board_stats.items[current_selection]) == 1)
		    {
		      restore();
		      return(1);
		    }
		  
		  raw_mode();
		  refresh_board_stats(agent);
		  goto restart;  /* forgive me, Father.. for I have sinned. */
		}

	      if((*c == 'R') && !locked)
		restart_agent(agent);
	      else
		if(*c == 'R')
		  {
		    really_locked = 1;
		    dpy_home();
		    display_board_header(agent);
		    dpy_end();
		    continue;
		  }

	      if((*c == 'b') || (*c == 'q') || (*c == ' '))
		break;
	
	      if(*c == 'U')
		{
		  locked = 0;
		  dpy_home();
		  display_board_header(agent);
		  dpy_end();
		}

	      if((*c == 'l') || (*c == 'L'))
		{
		  locked = 1;
		  dpy_home();
		  display_board_header(agent);
		  dpy_end();
		}

	      if(*c == 't')
		{
		  ++mode;
		  if(mode > 3)
		    mode = 0;
		  refresh_board_stats(agent);
		}

	      if(*c == '?')
		{
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  clear_screen();
		  printf("KEY MAPPINGS \n\n");
		  printf("\t L       \t lock against agent writes\n");
		  printf("\t U       \t unlock to enable agent writes\n");
		  printf("\t R       \t reset agent\n");
		  printf("\t t       \t toggle display mode\n");
		  putchar('\n');
		  printf("\t ^L      \t refresh screen\n");
		  printf("\t ^F      \t forward page\n");
		  printf("\t ^B      \t back page\n");
		  printf("\t ^N      \t select next board\n");
		  printf("\t ^P      \t select previous board\n");
		  printf("\t <n>     \t display board n\n");
		  printf("\t <space> \t update screen\n");
		  printf("\t <return>\t goto selected board\n");
		  putchar('\n');
		  printf("\t b       \t return to previous level\n");
		  printf("\t q       \t quit display mode\n");
		  printf("\t ?       \t help screen\n");
		  printf("\nhit any key to continue... ");
		  getchar();
		  stuff();
		  refresh_board_stats(agent);
		  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
		  continue;
		} 
	    }

	  if(*c == 'b')
	    {
	      restore();
	      return(0);
	    }

	  if(*c == 'q')
	    {
	      restore();
	      return(1);
	    }

	  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
	}
      else
	{
	  skip_sleep = 0;
	  sleep(1);
	}
    }
}




display_board_header(agent)
     Agent *agent;
{
  char buf[64];
  
  sprintf(buf, "agent %s (%s)", agent->alias, agent->saddr);
  printf("%-40.40s%39.39s\n\n", buf, descr);
  sprintf(buf, " (board %2d)", board_stats.items[current_selection]);
  printf("BOARD DETAIL%-19s%-31s%17s\n\n", current_selection >= 0 ? buf :" ", 
	 mode_str[mode], really_locked ? "write PROTECT" :
	 locked ? "write protect" : "WRITE ENABLE");
  printf(" board  type        packets      transmit coll       receive coll \n");
  really_locked = 0;
}



display_board_data(agent, index)
     Agent *agent;
     int index;
{
  char     buf1[16];
  char     buf2[16];
  char     buf3[16];
  char     buf4[16];

  if((index < ((page - 1) * (LI - margin))) || 
     (index >= (page * (LI - margin))))
    return;

  if(board_stats.timeouts[index])
    {
      printf( "%s%-6d %-10s  %-10s   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     board_stats.items[index], 
	     get_category(board_stats.types[index],board_types[agent->vendor]),
	     "*", "*", "*", "*", "*");
      return;
    }
 
  if(mode == 0)
    {
      sprintf(buf1, "%-3.2f%%", board_stats.del_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.del_xmit_colls[index] 
	      / board_stats.del_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", board_stats.del_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.del_rec_colls[index]
	      / board_stats.del_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) board_stats.del_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) board_stats.del_rec_colls[index]/100);
      printf( "%s%-6d %-10s  %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     board_stats.items[index], 
	     get_category(board_stats.types[index],board_types[agent->vendor]),
	     board_stats.del_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 1)
    {
      sprintf(buf1, "%-3.2f%%", board_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.ave1_xmit_colls[index] 
	      / board_stats.ave1_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", board_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.ave1_rec_colls[index]
	      / board_stats.ave1_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) board_stats.ave1_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) board_stats.ave1_rec_colls[index]/100);
      printf( "%s%-6d %-10s  %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     board_stats.items[index], 
	     get_category(board_stats.types[index],board_types[agent->vendor]),
	     board_stats.ave1_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 2)
    {
      sprintf(buf1, "%-3.2f%%", board_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.ave2_xmit_colls[index] 
	      / board_stats.ave2_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", board_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.ave2_rec_colls[index]
	      / board_stats.ave2_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) board_stats.ave2_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) board_stats.ave2_rec_colls[index]/100);
      printf( "%s%-6d %-10s  %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     board_stats.items[index], 
	     get_category(board_stats.types[index],board_types[agent->vendor]),
	     board_stats.ave2_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
  
  if(mode == 3)
    {
      sprintf(buf1, "%-3.2f%%", board_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.ave3_xmit_colls[index] 
	      / board_stats.ave3_tot_pkts[index]);
      sprintf(buf2, "%-3.2f%%", board_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) board_stats.ave3_rec_colls[index]
	      / board_stats.ave3_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) board_stats.ave3_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) board_stats.ave3_rec_colls[index]/100);
      printf( "%s%-6d %-10s  %-10d   %-10s %-8s %-10s %-8s \n",
	     current_selection == index ? "*" : " ", 
	     board_stats.items[index], 
	     get_category(board_stats.types[index],board_types[agent->vendor]),
	     board_stats.ave3_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
}



display_board_footer(agent)
     Agent *agent;
{
  char buf[64];
  sprintf(buf, "uptime %s", uptime == -1 ? "*" : format_uptime(uptime));
  printf("\n%-39.24s %39s\n", ctime(&board_stats.cur_time), buf);
  sprintf(buf, "page %d of %d", page, board_stats.n/(LI - margin) + 1);
  printf("%42s\n", buf);
}


refresh_board_stats(agent)
     Agent *agent;
{
  int i;
  
  clear_screen();
  display_board_header(agent);
  for(i = 0; i < board_stats.n; i++)
    display_board_data(agent, i);
  display_board_footer(agent);
  dpy_end();
}


clear_board_stats()
{
  bzero(&board_stats, sizeof(board_stats));
  page = 1;
  current_selection = -1;
  descr = (char *) NULL;
}


up_board_marker(agent)
     Agent *agent;
{
  int i;

  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; ++i)
	downline();
      putchar(' ');
      current_selection--;
    }

  if(current_selection < 0)
    {
      current_selection = board_stats.n - 1;
      page =  ((board_stats.n - 1)/(LI - margin)) + 1;
      refresh_board_stats(agent);
      return;
    }

  if(current_selection < top)
    {
      page--;
      refresh_board_stats(agent);
      return;
    }

  move_cursor_to_data(); 
  for(i = top; i <= current_selection; i++)
    downline();

  putchar('*');
  dpy_home();
  display_board_header(agent);
  dpy_end();
}



down_board_marker(agent)
     Agent *agent;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; i++)
	downline();
      putchar(' ');
    }
  downline();

  current_selection++;
  if(current_selection >= board_stats.n)
    {
      current_selection = 0;
      page = 1;
      refresh_board_stats(agent);
      return;
    }

  if(current_selection >= bottom)
    {
      page++;
      if(page > ((board_stats.n - 1)/(LI - margin) + 1))
        page = 1;
      refresh_board_stats(agent);
      return;
    }

  putchar('*');
  dpy_home();
  display_board_header(agent);
  dpy_end();
}




display_ports(agent, board)
     Agent *agent;
     int board;
{
  objident *obj[SNMPMAXVARS];
  caddr_t  *dat           = (caddr_t *) NULL;
  caddr_t  datt           = (caddr_t ) NULL;
  int      len            = 0;
  int      i              = 0;
  int      p              = 0;
  int      o              = 0;
  int      b              = 0;
  int      knowit         = 0;
  int      skip_sleep     = 1;
  int      nslots;
  char     c;

  init_screen();
  clear_port_stats();
  bzero(&interval, sizeof(interval));
  bzero(&disable,  sizeof(disable));
  if(!siginit)
    {
      signal(SIGINT,  restore_intr);
      siginit = 1;
    }
  raw_mode();
  if(setjmp(ret))
    return(1);
  else
    ret_set = 1;

  while(1)
    {
      dpy_home();
      o = 0;
      
      if(!agent->vendor)
	{
	  if(!determine_vendor(agent))
	    {
	      descr = "*";
	      uptime = -1;
	    }
	}

      obj[o++] = &vSysUptime;
      obj[o++] = &vSysDescr;
      obj[o++] = &vDeviceOccSlots[agent->vendor];
      obj[o++] = (objident *) NULL;

      dat = make_lots_o_snmp_queries(agent, obj);
      if(dat)
	{
	  o = 0;
	  bcopy(dat[o++], &uptime, sizeof(uptime));
	  descr = dat[o++];
	  if(agent->vendor == CABLETRON)
	    bcopy(dat[o++], &nslots, sizeof(nslots));	
	  else
	    {
	      bcopy(dat[o++], &c, sizeof(c));
	      nslots = (int) c;
	    }
	  i = power(board - 1);
/*
	  if(!(i & nslots))
	    {
	      printf("There is no board in slot %d.\n", board);
	      restore();
	      sleep(3);
	      return(-1);
	    }
*/
	}
      else
	{
	  descr = "*";
	  uptime = -1;
	}
      uptime /= 100;
      port_stats.cur_time = time(0);
	
      display_port_header(agent, board);

      o = 0;      
      obj[o++] = &vPortMediaType[agent->vendor];
      obj[o++] = &vPortAdminStatus[agent->vendor];
      obj[o++] = &vPortLinkStatus[agent->vendor];
      obj[o++] = &vPortNetworkStatus[agent->vendor];
      obj[o++] = &vPortTotalPkts[agent->vendor];
      obj[o++] = &vPortXmitColls[agent->vendor];
      obj[o++] = &vPortRecColls[agent->vendor];
      obj[o++] = (objident *) NULL;
      
      if(!knowit)
	{
	  vPortMediaType[agent->vendor].ncmp     -= 2;
	  vPortAdminStatus[agent->vendor].ncmp   -= 2;
	  vPortLinkStatus[agent->vendor].ncmp    -= 2;
	  vPortNetworkStatus[agent->vendor].ncmp -= 2;
	  vPortTotalPkts[agent->vendor].ncmp     -= 2;
	  vPortXmitColls[agent->vendor].ncmp     -= 2;
	  vPortRecColls[agent->vendor].ncmp      -= 2;
	  
	  datt = make_snmp_next(agent, obj[0]);
	  
	  vPortMediaType[agent->vendor].ncmp     += 2;
	  vPortAdminStatus[agent->vendor].ncmp   += 2;
	  vPortLinkStatus[agent->vendor].ncmp    += 2;
	  vPortNetworkStatus[agent->vendor].ncmp += 2;
	  vPortTotalPkts[agent->vendor].ncmp     += 2;
	  vPortXmitColls[agent->vendor].ncmp     += 2;
	  vPortRecColls[agent->vendor].ncmp      += 2;
	  
	  if(!datt)
	    {
	      printf("no response from %s.. unable to continue.\n", 
		     agent->alias);
	      restore();
	      sleep(3);
	      return(-1);
	    }
	}

      p = 0;
      while(datt || (knowit && (p < port_stats.n)))
	{
	  if(!knowit)
	    {
	      if(oidncmp(obj[0], &(reply.varlist.elem[0].name),
			 vPortMediaType[agent->vendor].ncmp - 2) != 0)
		break;	  
	      b = reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-2];
	      port_stats.items[p] = 
		reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-1];

	      if(reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-2] != board)
		{
		  vPortMediaType[agent->vendor].cmp[vPortMediaType[agent->vendor].ncmp-2] = b;
		  vPortMediaType[agent->vendor].cmp[vPortMediaType[agent->vendor].ncmp-1] = port_stats.items[p];
		  datt = make_snmp_next(agent, obj[0]);
		  continue;
		}
	    }
	  else
	    b = board;

	  vPortMediaType[agent->vendor].cmp[vPortMediaType[agent->vendor].ncmp-2]         = b;
	  vPortAdminStatus[agent->vendor].cmp[vPortAdminStatus[agent->vendor].ncmp-2]     = b;
	  vPortLinkStatus[agent->vendor].cmp[vPortLinkStatus[agent->vendor].ncmp-2]       = b;
	  vPortNetworkStatus[agent->vendor].cmp[vPortNetworkStatus[agent->vendor].ncmp-2] = b;
	  vPortTotalPkts[agent->vendor].cmp[vPortTotalPkts[agent->vendor].ncmp-2]         = b;
	  vPortXmitColls[agent->vendor].cmp[vPortXmitColls[agent->vendor].ncmp-2]         = b;
	  vPortRecColls[agent->vendor].cmp[vPortRecColls[agent->vendor].ncmp-2]           = b;

	  vPortMediaType[agent->vendor].cmp[vPortMediaType[agent->vendor].ncmp-1]          
	    = port_stats.items[p];
	  vPortAdminStatus[agent->vendor].cmp[vPortAdminStatus[agent->vendor].ncmp-1]      
	    = port_stats.items[p];
	  vPortLinkStatus[agent->vendor].cmp[vPortLinkStatus[agent->vendor].ncmp-1]        
	    = port_stats.items[p];
	  vPortNetworkStatus[agent->vendor].cmp[vPortNetworkStatus[agent->vendor].ncmp-1]  
	    = port_stats.items[p];
	  vPortTotalPkts[agent->vendor].cmp[vPortTotalPkts[agent->vendor].ncmp-1]          
	    = port_stats.items[p];
	  vPortXmitColls[agent->vendor].cmp[vPortXmitColls[agent->vendor].ncmp-1]          
	    = port_stats.items[p];
	  vPortRecColls[agent->vendor].cmp[vPortRecColls[agent->vendor].ncmp-1]            
	    = port_stats.items[p];
	  	  
	  if(!(dat = make_lots_o_snmp_queries(agent, obj)))
	    {
	      if(!knowit)
		{
		  printf("no response from %s.. unable to continue.\n", 
			 agent->alias);
		  restore();
		  sleep(3);
		  return(-1);
		}
	      else
		{
		  display_port_data(agent, p);
		  ++p;
		  break;
		}
	    }
	  else
	    if(port_stats.timeouts[p] == 1)
	      port_stats.timeouts[p] = 2;
	    else
	      port_stats.timeouts[p] = 0;

	  o = 0;
	  bcopy(dat[o++], &port_stats.types[p],        
		sizeof(port_stats.types[p]));
	  bcopy(dat[o++], &astatus[p],         
		sizeof(astatus[p]));
	  bcopy(dat[o++], &lstatus[p],         
		sizeof(lstatus[p]));
	  bcopy(dat[o++], &ostatus[p],         
		sizeof(ostatus[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_pkts,    
		sizeof(port_stats.cur_tot_pkts));
	  bcopy(dat[o++], &port_stats.cur_xmit_colls,  
		sizeof(port_stats.cur_xmit_colls));
	  bcopy(dat[o++], &port_stats.cur_rec_colls,   
		sizeof(port_stats.cur_rec_colls));

	  if(port_stats.pre_time[p] && 
	     (port_stats.cur_time != port_stats.pre_time[p]))
	    {
	      port_stats.del_tot_pkts[p]   = 
		(port_stats.cur_tot_pkts   - port_stats.pre_tot_pkts[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);
	      port_stats.del_xmit_colls[p] = 100 * 
		(port_stats.cur_xmit_colls - port_stats.pre_xmit_colls[p]) 
		/ (port_stats.cur_time     - port_stats.pre_time[p]);
	      port_stats.del_rec_colls[p]  = 100 *
		(port_stats.cur_rec_colls  -  port_stats.pre_rec_colls[p])  
		/ (port_stats.cur_time     - port_stats.pre_time[p]);
	    }

	  port_stats.pre_tot_pkts[p]   = port_stats.cur_tot_pkts;
	  port_stats.pre_xmit_colls[p] = port_stats.cur_xmit_colls;
	  port_stats.pre_rec_colls[p]  = port_stats.cur_rec_colls;

	  if(!port_stats.pre_time[p] || 
	     (port_stats.cur_time == port_stats.pre_time[p]))
	    {
	      if(p == 0)
		printf("gathering data...\n");
	      port_stats.pre_time[p] = port_stats.cur_time;
	      ++p;
	      if(!knowit)
		datt = make_snmp_next(agent, obj[0]);
	      else
		datt = (caddr_t) NULL;
	      skip_sleep = 1;
	      continue;
	    }

	  avexp = (double) calculate_ave_exponent(port_stats.cur_time 
					       - port_stats.pre_time[p], 60);
	  average(&port_stats.ave1_tot_pkts[p],   
		  port_stats.del_tot_pkts[p],   avexp);
	  average(&port_stats.ave1_xmit_colls[p], 
		  port_stats.del_xmit_colls[p], avexp);
	  average(&port_stats.ave1_rec_colls[p],  
		  port_stats.del_rec_colls[p],  avexp);
	  
	  avexp = (double) calculate_ave_exponent(port_stats.cur_time 
					       - port_stats.pre_time[p], 300);
	  average(&port_stats.ave2_tot_pkts[p],   
		  port_stats.del_tot_pkts[p],   avexp);
	  average(&port_stats.ave2_xmit_colls[p], 
		  port_stats.del_xmit_colls[p], avexp);
	  average(&port_stats.ave2_rec_colls[p],  
		  port_stats.del_rec_colls[p],  avexp);
	  
	  avexp = (double) calculate_ave_exponent(port_stats.cur_time 
					       - port_stats.pre_time[p],1500);
	  average(&port_stats.ave3_tot_pkts[p],   
		  port_stats.del_tot_pkts[p],   avexp);
	  average(&port_stats.ave3_xmit_colls[p], 
		  port_stats.del_xmit_colls[p], avexp);
	  average(&port_stats.ave3_rec_colls[p],  
		  port_stats.del_rec_colls[p],  avexp);

	  port_stats.pre_time[p] = port_stats.cur_time;
	  display_port_data(agent, p);

	  if(!knowit)
	    {
	      if(!(datt = make_snmp_next(agent, obj[0])))
		{
		  printf("no response from %s.. unable to continue.\n", 
			 agent->alias);
		  restore();
		  sleep(3);
		  return(-1);
		}
	    }
	  else
	    datt = (caddr_t) NULL;
	  ++p;
	}  

      port_stats.n = p;
      knowit = 1;
      
      if(!skip_sleep)
	{
	  display_port_footer(agent);
	  dpy_end();

	  if(setjmp(more))
	    continue;
	  else
	    more_set = 1;

	  interval.it_value.tv_sec = the_update;
	  signal(SIGALRM, onintr);
	  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);

	  while(c = getchar())
	    {	     	
	      raw_mode();
	      if(c == '\014')
		{
		  refresh_port_stats(agent, board);
		  continue;
		}

	      if(c == '\020')
		{
		  up_port_marker(agent, board);
		  continue;
		}

	      if(c == '\016')
		{
		  down_port_marker(agent, board);
		  continue;
		}

	      if(c == '\006')
		{
		  ++page;
		  if(page > (((port_stats.n - 1)/ (LI - margin)) + 1))
		    page = 1;
		  if(current_selection >= 0)
		    current_selection = -1;
		  refresh_port_stats(agent, board);
		  continue;
		}

	      if(c == '\002')
		{
		  --page;
		  if(page < 1)
		    page = ((port_stats.n - 1) / (LI - 12)) + 1;
		  if(current_selection >= 0)
		    current_selection = -1;
		  refresh_port_stats(agent, board);
		  continue;
		}

	      if((c == 'q') || (c == 'b') || (c == ' '))
		break;

	      if((c == 'R') && !locked)
		restart_agent(agent);
	      else
		if(c == 'R')
		  {
		    really_locked = 1;
		    dpy_home();
		    display_port_header(agent, board);
		    dpy_end();
		    continue;
		   }
	    
	      if(c == 'U')
		{
		  locked = 0;
		  dpy_home();
		  display_port_header(agent, board);
		  dpy_end();
		}

	      if((c == 'l') || (c == 'L'))
		{
		  locked = 1;
		  dpy_home();
		  display_port_header(agent, board);
		  dpy_end();
		}

	      if((c == 'D') || (c == 'E'))
		{		  				 
		  if(locked)
		    {
		      really_locked = 1;
		      dpy_home();
		      display_port_header(agent, board);
		      dpy_end();
		      continue;
		    }
		  
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  signal(SIGALRM,  SIG_DFL);
		  if((current_selection >= 0) && (current_selection < 
						  port_stats.n))
		    {
		      if(toggle_port(agent, board, current_selection + 1, 
				     c == 'D' ? ADMIN_OFF[agent->vendor] : 
				     ADMIN_ON[agent->vendor])
			 == SUCCESS)
			astatus[current_selection] = 
			  c == 'D' ? ADMIN_OFF[agent->vendor] : 
			    ADMIN_ON[agent->vendor];
		      else
			astatus[current_selection] = ADMIN_ERR[agent->vendor];
		      refresh_port_stats(agent, board);
		    }
		  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
		  signal(SIGALRM,  onintr);
		  continue;
		}
		  
	      if(c == 't')
		{
		  ++mode;
		  if(mode > 3)
		    mode = 0;
		  refresh_port_stats(agent, board);
		}

	      if(c == '?')
		{
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  clear_screen();
		  printf("KEY MAPPINGS \n\n");
		  printf("\t L       \t lock against agent writes\n");
		  printf("\t U       \t unlock to enable agent writes\n");
		  printf("\t E       \t enable port\n");
		  printf("\t D       \t disable/detonate port\n");
		  printf("\t R       \t reset agent\n");
		  printf("\t t       \t toggle display mode\n");
		  putchar('\n');
		  printf("\t ^L      \t refresh screen\n");
		  printf("\t ^F      \t forward page\n");
		  printf("\t ^B      \t back page\n");
		  printf("\t ^N      \t select next port\n");
		  printf("\t ^P      \t select previous port\n");
		  printf("\t <space> \t update screen\n");
		  putchar('\n');
		  printf("\t b       \t return to previous level\n");
		  printf("\t q       \t quit display mode\n");		  
		  printf("\t ?       \t help screen\n");
		  printf("\nhit any key to continue... ");
		  getchar();
		  stuff();
		  refresh_port_stats(agent, board);
		  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
		  continue;
		}
	    }

	  if(c == 'q')
	    {
	      restore();
	      return(1);	  
	    }

	  if(c == 'b')
	    {
	      restore();
	      clear_screen();
	      return(0);	
	    }

	  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
	}
      else
	{
	  skip_sleep = 0;
	  sleep(1);
	}
    }
}



display_port_header(agent, board)
     Agent *agent;
     int board;
{
  char buf[64];

  sprintf(buf, "agent %s (%s)", agent->alias, agent->saddr);
  printf("%-40.40s%39.39s\n\n", buf,  descr);
  if(current_selection >= 0)
    sprintf(buf, "/port %2d)", port_stats.items[current_selection]);
  printf("PORT DETAIL (board %2d%-11s%-27s%20s\n\n", 
	 board, current_selection >= 0 ? buf : ")",  mode_str[mode], 
	 really_locked ? "write PROTECT" : 
	 locked ? "write protect" : "WRITE ENABLE");
  printf(" port  type       status (ALN)   packets    transmit coll      receive coll \n");
  really_locked = 0;
}



display_port_data(agent, index)
     Agent *agent;
     int index;
{
  char buf1[16];
  char buf2[16];
  char buf3[16];
  char buf4[16];

  if((index < ((page - 1) * (LI - margin))) || 
     (index >= (page * (LI - margin))))
    return;

  if(port_stats.timeouts[index])
    {
      printf("%s%-4d  %-10s %-3s %-3s %-5s  %-10s %-8s %-8s  %-8s %-8s%\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], media_types[agent->vendor]),
	     "*", "*", "*", 
	     "*", "*", "*", "*", "*");
      return;
    }

  if(mode == 0)
    {
      sprintf(buf1, "%3.2f%%", port_stats.del_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.del_xmit_colls[index]
	      / port_stats.del_tot_pkts[index]);
      sprintf(buf2, "%3.2f%%", port_stats.del_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.del_rec_colls[index]
	      / port_stats.del_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) port_stats.del_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) port_stats.del_rec_colls[index]/100);
      printf("%s%-4d  %-10s %-3s %-3s %-5s  %-10d %-8s %-8s  %-8s %-8s%\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], media_types[agent->vendor]),
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" : 
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     lstatus[index] == LINK_INACTIVE[agent->vendor] ? "no": 
	     lstatus[index] == LINK_ACTIVE[agent->vendor] ? "yes" : "na",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     port_stats.del_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 1)
    {
      sprintf(buf1, "%3.2f%%", port_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.ave1_xmit_colls[index]
	      / port_stats.ave1_tot_pkts[index]);
      sprintf(buf2, "%3.2f%%", port_stats.ave1_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.ave1_rec_colls[index]
	      / port_stats.ave1_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) port_stats.ave1_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) port_stats.ave1_rec_colls[index]/100);
      printf("%s%-4d  %-10s %-3s %-3s %-5s  %-10d %-8s %-8s  %-8s %-8s%\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], media_types[agent->vendor]),
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" :
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     lstatus[index] == LINK_INACTIVE[agent->vendor] ? "no": 
	     lstatus[index] == LINK_ACTIVE[agent->vendor] ? "yes" : "na",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     port_stats.ave1_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 2)
    {
      sprintf(buf1, "%3.2f%%", port_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.ave2_xmit_colls[index]
	      / port_stats.ave2_tot_pkts[index]);
      sprintf(buf2, "%3.2f%%", port_stats.ave2_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.ave2_rec_colls[index]
	      / port_stats.ave2_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) port_stats.ave2_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) port_stats.ave2_rec_colls[index]/100);
      printf("%s%-4d  %-10s %-3s %-3s %-5s  %-10d %-8s %-8s  %-8s %-8s%\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], media_types[agent->vendor]),
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" :
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     lstatus[index] == LINK_INACTIVE[agent->vendor] ? "no": 
	     lstatus[index] == LINK_ACTIVE[agent->vendor] ? "yes" : "na",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     port_stats.ave2_tot_pkts[index], buf3, buf1, buf4, buf2);
    }

  if(mode == 3)
    {
      sprintf(buf1, "%3.2f%%", port_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.ave3_xmit_colls[index]
	      / port_stats.ave3_tot_pkts[index]);
      sprintf(buf2, "%3.2f%%", port_stats.ave3_tot_pkts[index] == 0 ? 0 :
	      (double) port_stats.ave3_rec_colls[index]
	      / port_stats.ave3_tot_pkts[index]);
      sprintf(buf3, "%-8.2f", (double) port_stats.ave3_xmit_colls[index]/100);
      sprintf(buf4, "%-8.2f", (double) port_stats.ave3_rec_colls[index]/100);
      printf("%s%-4d  %-10s %-3s %-3s %-5s  %-10d %-8s %-8s  %-8s %-8s%\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], media_types[agent->vendor]),
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" :
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     lstatus[index] == LINK_INACTIVE[agent->vendor] ? "no": 
	     lstatus[index] == LINK_ACTIVE[agent->vendor] ? "yes" : "na",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     port_stats.ave3_tot_pkts[index], buf3, buf1, buf4, buf2);
    }
}



display_port_footer(agent)
     Agent *agent;
{
  char buf[64];
  sprintf(buf, "uptime %s", uptime == -1 ? "*" : format_uptime(uptime));
  printf("\n%-39.24s %39s\n", ctime(&port_stats.cur_time), buf);
  sprintf(buf, "page %d of %d", page, ((port_stats.n - 1)/(LI - margin)) + 1);
  printf("%42s\n", buf);
}


refresh_port_stats(agent, board)
     Agent *agent;
     int board;
{
  int i;

  clear_screen();
  display_port_header(agent, board);
  for(i = 0; i < port_stats.n; i++)
    display_port_data(agent, i);
  display_port_footer(agent);
  dpy_end();
}


clear_port_stats()
{
  bzero(&port_stats, sizeof(port_stats));
  current_selection = -1;
  page = 1;
  bzero(astatus, sizeof(astatus));
  bzero(lstatus, sizeof(lstatus));
  bzero(ostatus, sizeof(ostatus));
  descr = (char *) NULL;
}


up_port_marker(agent, board)
     Agent *agent;
     int board;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; i++)
	downline();
      putchar(' ');
      current_selection--;
    }

  if(current_selection < 0)
    {
      current_selection = port_stats.n - 1;
      page =  ((port_stats.n - 1)/(LI - margin)) + 1;
      refresh_port_stats(agent, board);
      return;
    }

  if(current_selection < top)
    {
      page--;
      refresh_port_stats(agent, board);
      return;
    }

  move_cursor_to_data();
  for(i = top; i <= current_selection; i++)
    downline();
  
  putchar('*');
  dpy_home();
  display_port_header(agent, board);
  dpy_end();
}



down_port_marker(agent, board)
     Agent *agent;
     int board;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; i++)
	downline();
      putchar(' ');
    }
  downline();
  
  current_selection++;
  if(current_selection >= port_stats.n)
    {
      current_selection = 0;
      page = 1;
      refresh_port_stats(agent, board);
      return;
    }
  
  if(current_selection >= bottom)
    {
      page++;
      if(page > ((port_stats.n - 1)/(LI - margin) + 1))
	page = 1;
      refresh_port_stats(agent, board);
      return;
    }

  putchar('*');
  dpy_home();
  display_port_header(agent, board);
  dpy_end();
}




display_interfaces(agent)
     Agent *agent;
{
  objident *obj[SNMPMAXVARS + 1];
  caddr_t  *dat           = (caddr_t *) NULL;
  caddr_t  datt           = (caddr_t ) NULL;
  int      len            = 0;
  int      i              = 0;
  int      p              = 0;
  int      o              = 0;
  int      b              = 0;
  int      knowit         = 0;
  int      skip_sleep     = 1;
  int      nslots;
  char     c;

  init_screen();
  clear_port_stats();
  bzero(&interval, sizeof(interval));
  bzero(&disable,  sizeof(disable));
  if(!siginit)
    {
      signal(SIGINT,  restore_intr);
      siginit = 1;
    }
  raw_mode();
  if(setjmp(ret))
    return(1);
  else
    ret_set = 1;

  while(1)
    {
      dpy_home();
      o = 0;

      obj[o++] = &vSysUptime;
      obj[o++] = &vSysDescr;
      obj[o++] = &vIfNumber;
      obj[o++] = (objident *) NULL;

      dat = make_lots_o_snmp_queries(agent, obj);
      if(dat)
	{
	  o = 0;
	  bcopy(dat[o++], &uptime, sizeof(uptime));
	  descr = dat[o++];
	  bcopy(dat[o], &i, sizeof(i));;
	}
      else
	{
	  descr = "*";
	  uptime = -1;
	}
      uptime /= 100;
      port_stats.cur_time = time(0);
	
      display_interface_header(agent);

      o = 0;      
      obj[o++] = &vIfDescr;
      obj[o++] = &vIfType;
      obj[o++] = &vIfMtu;
      obj[o++] = &vIfSpeed;
      obj[o++] = &vIfAdminStatus;
      obj[o++] = &vIfOperStatus;
      obj[o++] = &vIfInOctets;
      obj[o++] = &vIfOutOctets;
      obj[o++] = &vIfInUcastPkts;
      obj[o++] = &vIfOutUcastPkts;
      obj[o++] = &vIfInNUcastPkts;
      obj[o++] = &vIfOutNUcastPkts;
      obj[o++] = &vIfInDiscards;
      obj[o++] = &vIfOutDiscards;
      obj[o++] = &vIfInErrors;
      obj[o++] = &vIfOutErrors;
      obj[o++] = (objident *) NULL;
      
      if(!knowit)
	{
	  vIfDescr.ncmp--;
	  vIfType.ncmp--;
	  vIfMtu.ncmp--;
	  vIfSpeed.ncmp--;
	  vIfAdminStatus.ncmp--;
	  vIfOperStatus.ncmp--;
	  vIfAdminStatus.ncmp--;
	  vIfInOctets.ncmp--;
	  vIfOutOctets.ncmp--;
	  vIfInUcastPkts.ncmp--;
	  vIfOutUcastPkts.ncmp--;
	  vIfInNUcastPkts.ncmp--;
	  vIfOutNUcastPkts.ncmp--;
	  vIfInDiscards.ncmp--;
	  vIfOutDiscards.ncmp--;
	  vIfInErrors.ncmp--;
	  vIfOutErrors.ncmp--;
	  vIfOutQlen.ncmp--;
	  
	  datt = make_snmp_next(agent, obj[0]);
	  
	  vIfDescr.ncmp++;
	  vIfType.ncmp++;
	  vIfMtu.ncmp++;
	  vIfSpeed.ncmp++;
	  vIfAdminStatus.ncmp++;
	  vIfOperStatus.ncmp++;
	  vIfAdminStatus.ncmp++;
	  vIfInOctets.ncmp++;
	  vIfOutOctets.ncmp++;
	  vIfInUcastPkts.ncmp++;
	  vIfOutUcastPkts.ncmp++;
	  vIfInNUcastPkts.ncmp++;
	  vIfOutNUcastPkts.ncmp++;
	  vIfInDiscards.ncmp++;
	  vIfOutDiscards.ncmp++;
	  vIfInErrors.ncmp++;
	  vIfOutErrors.ncmp++;
	  vIfOutQlen.ncmp++;

	  if(!datt)
	    {
	      printf("no response from %s.. unable to continue.\n", 
		     agent->alias);
	      restore();
	      sleep(3);
	      return(-1);
	    }
	}

      p = 0;
      while(datt || (knowit && (p < port_stats.n)))
	{
	  if(!knowit)
	    {
	      if(oidncmp(obj[0], &(reply.varlist.elem[0].name),
			 vIfDescr.ncmp - 1) != 0)
		break;	  
	      port_stats.items[p] = 
		reply.varlist.elem[0].name.cmp[reply.varlist.elem[0].name.ncmp-1];
	    }

	  vIfDescr.cmp[vIfDescr.ncmp-1]                 = port_stats.items[p];
	  vIfType.cmp[vIfType.ncmp-1]                   = port_stats.items[p];
	  vIfMtu.cmp[vIfMtu.ncmp-1]                     = port_stats.items[p];
	  vIfSpeed.cmp[vIfSpeed.ncmp-1]                 = port_stats.items[p];
	  vIfAdminStatus.cmp[vIfAdminStatus.ncmp-1]     = port_stats.items[p];
	  vIfOperStatus.cmp[vIfOperStatus.ncmp-1]       = port_stats.items[p];
	  vIfInOctets.cmp[vIfInOctets.ncmp-1]           = port_stats.items[p];
	  vIfOutOctets.cmp[vIfOutOctets.ncmp-1]         = port_stats.items[p];
	  vIfInUcastPkts.cmp[vIfInUcastPkts.ncmp-1]     = port_stats.items[p];
	  vIfOutUcastPkts.cmp[vIfOutUcastPkts.ncmp-1]   = port_stats.items[p];
	  vIfInNUcastPkts.cmp[vIfInNUcastPkts.ncmp-1]   = port_stats.items[p];
	  vIfOutNUcastPkts.cmp[vIfOutNUcastPkts.ncmp-1] = port_stats.items[p];
	  vIfInDiscards.cmp[vIfInDiscards.ncmp-1]       = port_stats.items[p];
	  vIfOutDiscards.cmp[vIfOutDiscards.ncmp-1]     = port_stats.items[p];
	  vIfInErrors.cmp[vIfInErrors.ncmp-1]           = port_stats.items[p];
	  vIfOutErrors.cmp[vIfOutErrors.ncmp-1]         = port_stats.items[p];
/*	  vIfOutQlen.cmp[vIfOutQlen.ncmp-1]             = port_stats.items[p];*/

	  if(!(dat = make_lots_o_snmp_queries(agent, obj)))
	    {
	      if(!knowit)
		{
		  printf("no response from %s.. unable to continue.\n", 
			 agent->alias);
		  restore();
		  sleep(3);
		  return(-1);
		}
	      else
		{
		  display_interface_data(agent, p);
		  ++p;
		  break;
		}
	    }
	  else
	    if(port_stats.timeouts[p] == 1)
	      port_stats.timeouts[p] = 2;
	    else
	      port_stats.timeouts[p] = 0;

	  o = 0;
 	  port_stats.descs[p] = dat[o++];
	  bcopy(dat[o++], &port_stats.types[p],        
		sizeof(port_stats.types[p]));
	  bcopy(dat[o++], &port_stats.mtus[p],        
		sizeof(port_stats.mtus[p]));
	  bcopy(dat[o++], &port_stats.speeds[p],        
		sizeof(port_stats.speeds[p]));
	  bcopy(dat[o++], &astatus[p],         
		sizeof(astatus[p]));
	  bcopy(dat[o++], &ostatus[p],         
		sizeof(ostatus[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_inbytes[p],    
		sizeof(port_stats.cur_tot_inbytes[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_outbytes[p],    
		sizeof(port_stats.cur_tot_outbytes[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_inucasts[p],    
		sizeof(port_stats.cur_tot_inucasts[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_outucasts[p],    
		sizeof(port_stats.cur_tot_outucasts[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_innucasts[p],    
		sizeof(port_stats.cur_tot_innucasts[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_outnucasts[p],    
		sizeof(port_stats.cur_tot_outnucasts[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_indiscards[p],    
		sizeof(port_stats.cur_tot_indiscards[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_outdiscards[p],    
		sizeof(port_stats.cur_tot_outdiscards[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_inerrors[p],    
		sizeof(port_stats.cur_tot_inerrors[p]));
	  bcopy(dat[o++], &port_stats.cur_tot_outerrors[p],    
		sizeof(port_stats.cur_tot_outerrors[p]));
/*	  bcopy(dat[o++], &port_stats.cur_tot_outqlens[p],    
		sizeof(port_stats.cur_tot_outqlens[p])); */

	  if(port_stats.pre_time[p] && 
	     (port_stats.cur_time != port_stats.pre_time[p]))
	    {
	      port_stats.del_tot_inbytes[p]   = 
		(port_stats.cur_tot_inbytes[p]   - 
		port_stats.pre_tot_inbytes[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_outbytes[p]   = 
		(port_stats.cur_tot_outbytes[p]   - 
		port_stats.pre_tot_outbytes[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_inucasts[p]   = 
		(port_stats.cur_tot_inucasts[p]   - 
		port_stats.pre_tot_inucasts[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_outucasts[p]   = 
		(port_stats.cur_tot_outucasts[p]   - 
		port_stats.pre_tot_outucasts[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_innucasts[p]   = 
		(port_stats.cur_tot_innucasts[p]   - 
		port_stats.pre_tot_innucasts[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_outnucasts[p]   = 
		(port_stats.cur_tot_outnucasts[p]   - 
		port_stats.pre_tot_outnucasts[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_indiscards[p]   = 
		(port_stats.cur_tot_indiscards[p]   - 
		port_stats.pre_tot_indiscards[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_outdiscards[p]   = 
		(port_stats.cur_tot_outdiscards[p]   - 
		port_stats.pre_tot_outdiscards[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_inerrors[p]   = 
		(port_stats.cur_tot_inerrors[p]   - 
		port_stats.pre_tot_inerrors[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_outerrors[p]   = 
		(port_stats.cur_tot_outerrors[p]   - 
		port_stats.pre_tot_outerrors[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	      port_stats.del_tot_outqlens[p]   = 
		(port_stats.cur_tot_outqlens[p]  - 
		port_stats.pre_tot_outqlens[p])   
		/ (port_stats.cur_time     - port_stats.pre_time[p]);

	    }

	  port_stats.pre_tot_inbytes[p]     = port_stats.cur_tot_inbytes[p];
	  port_stats.pre_tot_outbytes[p]    = port_stats.cur_tot_outbytes[p];
	  port_stats.pre_tot_inucasts[p]    = port_stats.cur_tot_inucasts[p];
	  port_stats.pre_tot_outucasts[p]   = port_stats.cur_tot_outucasts[p];
	  port_stats.pre_tot_innucasts[p]   = port_stats.cur_tot_innucasts[p];
	  port_stats.pre_tot_outnucasts[p]  = port_stats.cur_tot_outnucasts[p];
	  port_stats.pre_tot_inerrors[p]    = port_stats.cur_tot_inerrors[p];
	  port_stats.pre_tot_outerrors[p]   = port_stats.cur_tot_outerrors[p];
	  port_stats.pre_tot_indiscards[p]  = port_stats.cur_tot_indiscards[p];
	  port_stats.pre_tot_outdiscards[p] = port_stats.cur_tot_outdiscards[p];
	  port_stats.pre_tot_outqlens[p]    = port_stats.cur_tot_outqlens[p];

	  if(!port_stats.pre_time[p] || 
	     (port_stats.cur_time == port_stats.pre_time[p]))
	    {
	      if(p == 0)
		printf("gathering data...\n");
	      port_stats.pre_time[p] = port_stats.cur_time;
	      ++p;
	      if(!knowit)
		datt = make_snmp_next(agent, obj[0]);
	      else
		datt = (caddr_t) NULL;
	      skip_sleep = 1;
	      continue;
	    }

	  avexp = (double) calculate_ave_exponent(port_stats.cur_time 
					       - port_stats.pre_time[p], 60);
	  average(&port_stats.ave1_tot_inbytes[p],   
		  port_stats.del_tot_inbytes[p],   avexp);
	  average(&port_stats.ave1_tot_outbytes[p],   
		  port_stats.del_tot_outbytes[p],   avexp);
	  average(&port_stats.ave1_tot_inucasts[p],   
		  port_stats.del_tot_inucasts[p],   avexp);
	  average(&port_stats.ave1_tot_outucasts[p],   
		  port_stats.del_tot_outucasts[p],   avexp);
	  average(&port_stats.ave1_tot_innucasts[p],   
		  port_stats.del_tot_innucasts[p],   avexp);
	  average(&port_stats.ave1_tot_outnucasts[p],   
		  port_stats.del_tot_outnucasts[p],   avexp);
	  average(&port_stats.ave1_tot_inerrors[p],   
		  port_stats.del_tot_inerrors[p],   avexp);
	  average(&port_stats.ave1_tot_outerrors[p],   
		  port_stats.del_tot_outerrors[p],   avexp);
	  average(&port_stats.ave1_tot_indiscards[p],   
		  port_stats.del_tot_indiscards[p],   avexp);
	  average(&port_stats.ave1_tot_outdiscards[p],   
		  port_stats.del_tot_outdiscards[p],   avexp);
	  average(&port_stats.ave1_tot_outqlens[p],   
		  port_stats.del_tot_outqlens[p],   avexp);
	  
	  avexp = (double) calculate_ave_exponent(port_stats.cur_time 
					       - port_stats.pre_time[p], 300);

	  average(&port_stats.ave2_tot_inbytes[p],   
		  port_stats.del_tot_inbytes[p],   avexp);
	  average(&port_stats.ave2_tot_outbytes[p],   
		  port_stats.del_tot_outbytes[p],   avexp);
	  average(&port_stats.ave2_tot_inucasts[p],   
		  port_stats.del_tot_inucasts[p],   avexp);
	  average(&port_stats.ave2_tot_outucasts[p],   
		  port_stats.del_tot_outucasts[p],   avexp);
	  average(&port_stats.ave2_tot_innucasts[p],   
		  port_stats.del_tot_innucasts[p],   avexp);
	  average(&port_stats.ave2_tot_outnucasts[p],   
		  port_stats.del_tot_outnucasts[p],   avexp);
	  average(&port_stats.ave2_tot_inerrors[p],   
		  port_stats.del_tot_inerrors[p],   avexp);
	  average(&port_stats.ave2_tot_outerrors[p],   
		  port_stats.del_tot_outerrors[p],   avexp);
	  average(&port_stats.ave2_tot_indiscards[p],   
		  port_stats.del_tot_indiscards[p],   avexp);
	  average(&port_stats.ave2_tot_outdiscards[p],   
		  port_stats.del_tot_outdiscards[p],   avexp);
	  average(&port_stats.ave2_tot_outqlens[p],   
		  port_stats.del_tot_outqlens[p],   avexp);
	  
	  avexp = (double) calculate_ave_exponent(port_stats.cur_time 
					       - port_stats.pre_time[p],1500);
	  average(&port_stats.ave3_tot_inbytes[p],   
		  port_stats.del_tot_inbytes[p],   avexp);
	  average(&port_stats.ave3_tot_outbytes[p],   
		  port_stats.del_tot_outbytes[p],   avexp);
	  average(&port_stats.ave3_tot_inucasts[p],   
		  port_stats.del_tot_inucasts[p],   avexp);
	  average(&port_stats.ave3_tot_outucasts[p],   
		  port_stats.del_tot_outucasts[p],   avexp);
	  average(&port_stats.ave3_tot_innucasts[p],   
		  port_stats.del_tot_innucasts[p],   avexp);
	  average(&port_stats.ave3_tot_outnucasts[p],   
		  port_stats.del_tot_outnucasts[p],   avexp);
	  average(&port_stats.ave3_tot_inerrors[p],   
		  port_stats.del_tot_inerrors[p],   avexp);
	  average(&port_stats.ave3_tot_outerrors[p],   
		  port_stats.del_tot_outerrors[p],   avexp);
	  average(&port_stats.ave3_tot_indiscards[p],   
		  port_stats.del_tot_indiscards[p],   avexp);
	  average(&port_stats.ave3_tot_outdiscards[p],   
		  port_stats.del_tot_outdiscards[p],   avexp);
	  average(&port_stats.ave3_tot_outqlens[p],   
		  port_stats.del_tot_outqlens[p],   avexp);

	  port_stats.pre_time[p] = port_stats.cur_time;
	  display_interface_data(agent, p);

	  if(!knowit)
	    {
	      if(!(datt = make_snmp_next(agent, obj[0])))
		{
		  printf("no response from %s.. unable to continue.\n", 
			 agent->alias);
		  restore();
		  sleep(3);
		  return(-1);
		}
	    }
	  else
	    datt = (caddr_t) NULL;
	  ++p;
	}  

      port_stats.n = p;
      knowit = 1;
      
      if(!skip_sleep)
	{
	  display_interface_footer(agent);
	  dpy_end();

	  if(setjmp(more))
	    continue;
	  else
	    more_set = 1;

	  interval.it_value.tv_sec = the_update;
	  signal(SIGALRM, onintr);
	  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);

	  while(c = getchar())
	    {	     	
	      raw_mode();
	      if(c == '\014')
		{
		  refresh_interface_stats(agent);
		  continue;
		}

	      if(c == '\020')
		{
		  up_interface_marker(agent);
		  continue;
		}

	      if(c == '\016')
		{
		  down_interface_marker(agent);
		  continue;
		}

	      if(c == '\006')
		{
		  ++page;
		  if(page > (((port_stats.n - 1)/ (LI - margin)) + 1))
		    page = 1;
		  if(current_selection >= 0)
		    current_selection = -1;
		  refresh_interface_stats(agent);
		  continue;
		}

	      if(c == '\002')
		{
		  --page;
		  if(page < 1)
		    page = ((port_stats.n - 1) / (LI - 12)) + 1;
		  if(current_selection >= 0)
		    current_selection = -1;
		  refresh_interface_stats(agent);
		  continue;
		}

	      if((c == 'q') || (c == 'b') || (c == ' '))
		break;

	      if((c == 'R') && !locked)
		restart_agent(agent);
	      else
		if(c == 'R')
		  {
		    really_locked = 1;
		    dpy_home();
		    display_interface_header(agent);
		    dpy_end();
		    continue;
		   }
	    
	      if(c == 'U')
		{
		  locked = 0;
		  dpy_home();
		  display_interface_header(agent);
		  dpy_end();
		}

	      if((c == 'l') || (c == 'L'))
		{
		  locked = 1;
		  dpy_home();
		  display_interface_header(agent);
		  dpy_end();
		}

	      if((c == 'D') || (c == 'E'))
		{		  				 
		  if(locked)
		    {
		      really_locked = 1;
		      dpy_home();
		      display_interface_header(agent);
		      dpy_end();
		      continue;
		    }
		  
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  signal(SIGALRM,  SIG_DFL);
		  if((current_selection >= 0) && (current_selection < 
						  port_stats.n))
		    {
		      if(toggle_interface(agent, current_selection + 1, 
				     c == 'D' ? ADMIN_OFF[agent->vendor] : 
				     ADMIN_ON[agent->vendor])
			 == SUCCESS)
			astatus[current_selection] = 
			  c == 'D' ? ADMIN_OFF[agent->vendor] : 
			    ADMIN_ON[agent->vendor];
		      else
			astatus[current_selection] = ADMIN_ERR[agent->vendor];
		      refresh_interface_stats(agent);
		    }
		  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
		  signal(SIGALRM,  onintr);
		  continue;
		}
		  
	      if(c == 't')
		{
		  ++mode;
		  if(mode > 3)
		    mode = 0;
		  refresh_interface_stats(agent);
		}

	      if(c == '?')
		{
		  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
		  clear_screen();
		  printf("KEY MAPPINGS \n\n");
		  printf("\t L       \t lock against agent writes\n");
		  printf("\t U       \t unlock to enable agent writes\n");
		  printf("\t E       \t enable port\n");
		  printf("\t D       \t disable/detonate port\n");
		  printf("\t R       \t reset agent\n");
		  printf("\t t       \t toggle display mode\n");
		  putchar('\n');
		  printf("\t ^L      \t refresh screen\n");
		  printf("\t ^F      \t forward page\n");
		  printf("\t ^B      \t back page\n");
		  printf("\t ^N      \t select next port\n");
		  printf("\t ^P      \t select previous port\n");
		  printf("\t <space> \t update screen\n");
		  putchar('\n');
		  printf("\t b       \t return to previous level\n");
		  printf("\t q       \t quit display mode\n");		  
		  printf("\t ?       \t help screen\n");
		  printf("\nhit any key to continue... ");
		  getchar();
		  stuff();
		  refresh_interface_stats(agent);
		  setitimer(ITIMER_REAL, &interval, (struct itimerval *) NULL);
		  continue;
		}
	    }

	  if(c == 'q')
	    {
	      restore();
	      return(1);	  
	    }

	  if(c == 'b')
	    {
	      restore();
	      clear_screen();
	      return(0);	
	    }

	  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
	}
      else
	{
	  skip_sleep = 0;
	  sleep(1);
	}
    }
}


display_interface_header(agent)
     Agent *agent;
{
  char buf[64];

  sprintf(buf, "agent %s (%s)", agent->alias, agent->saddr);
  printf("%-40.40s%39.39s\n\n", buf,  descr);
  if(current_selection >= 0)
    sprintf(buf, "port %2d)", port_stats.items[current_selection]);
  printf("INTERFACE DETAIL (%-22s%-19s%20s\n\n", 
	 current_selection >= 0 ? buf : "mib-2)",  mode_str[mode], 
	 really_locked ? "write PROTECT" : 
	 locked ? "write protect" : "WRITE ENABLE");
  printf(" port  type              status (AO)    util      pkts in    errors    discards \n");
  really_locked = 0;
}



display_interface_data(agent, index)
     Agent *agent;
     int index;
{
  char buf1[16];
  char buf2[16];
  char buf3[16];
  char buf4[16];

  if((index < ((page - 1) * (LI - margin))) || 
     (index >= (page * (LI - margin))))
    return;

  if(port_stats.timeouts[index])
    {
      printf("%s%-4d  %-18s %-3s %-3s %-5s  %-8s     %-8s    %-8s  %-8s%\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], interface_types),
	     "*", "*", "*", 
	     "*", "*", "*", "*");
      return;
    }

  if(mode == 0)
    {
      sprintf(buf1, "%3d%%", port_stats.speeds[index] == 0 ? 0 :
	      (800 * (port_stats.del_tot_inbytes[index] 
	      + port_stats.del_tot_outbytes[index]))
	      / port_stats.speeds[index]);

      printf("%s%-4d  %-18.18s  %-3s %-5s    %-8s    %-8d    %-8d  %-8d\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index],
	     port_stats.descs[index], 
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" : 
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     buf1, 
	     port_stats.del_tot_inucasts[index] + 
	     port_stats.del_tot_innucasts[index],
	     port_stats.del_tot_inerrors[index],
	     port_stats.del_tot_indiscards[index]);
    }

  if(mode == 1)
    {
      sprintf(buf1, "%3d%%",  port_stats.speeds[index] == 0 ? 0 :
	      (double) 800 * (port_stats.ave1_tot_inbytes[index] 
	      + port_stats.ave1_tot_outbytes[index])
	      / port_stats.speeds[index]);

      printf("%s%-4d  %-10s %-3s %-5s  %-8s    %-8d    %-8d  %-8d\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     port_stats.descs[index],
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" : 
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     buf1, 
	     port_stats.ave1_tot_inucasts[index] + 
	     port_stats.ave1_tot_innucasts[index],
	     port_stats.ave1_tot_inerrors[index],
	     port_stats.ave1_tot_indiscards[index]);
    }

  if(mode == 2)
    {
      sprintf(buf1, "%3d%%", port_stats.speeds[index] == 0 ? 0 :
	      (double) 800 * (port_stats.ave2_tot_inbytes[index] 
	      + port_stats.ave2_tot_outbytes[index])
	      / port_stats.speeds[index]);

      printf("%s%-4d  %-10s %-3s %-5s  %-8s    %-8d    %-8d  %-8d\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], interface_types),
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" : 
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     buf1, 
	     port_stats.ave2_tot_inucasts[index] + 
	     port_stats.ave2_tot_innucasts[index],
	     port_stats.ave2_tot_inerrors[index],
	     port_stats.ave2_tot_indiscards[index]);
    }

  if(mode == 3)
    {
      sprintf(buf1, "%3d%%", port_stats.speeds[index] == 0 ? 0 :
	      (double) 800 * (port_stats.ave2_tot_inbytes[index] 
	      + port_stats.ave3_tot_outbytes[index])
	      / port_stats.speeds[index]);

      printf("%s%-4d  %-10s %-3s %-5s  %-8s    %-8d    %-8d  %-8d\n", 
	     index == current_selection ? "*" : " ",
	     port_stats.items[index], 
	     get_category(port_stats.types[index], interface_types),
	     astatus[index] == ADMIN_ON[agent->vendor] ? "on" : 
	     astatus[index] == ADMIN_OFF[agent->vendor] ? "off" : "err",
	     ostatus[index] == NETWORK_ACTIVE[agent->vendor] ? "up":"down",
	     buf1, 
	     port_stats.ave3_tot_inucasts[index] +
	     port_stats.ave3_tot_innucasts[index],
	     port_stats.ave3_tot_inerrors[index],
	     port_stats.ave3_tot_indiscards[index]);

    }
}



display_interface_footer(agent)
     Agent *agent;
{
  char buf[64];
  sprintf(buf, "uptime %s", uptime == -1 ? "*" : format_uptime(uptime));
  printf("\n%-39.24s %39s\n", ctime(&port_stats.cur_time), buf);
  sprintf(buf, "page %d of %d", page, ((port_stats.n - 1)/(LI - margin)) + 1);
  printf("%42s\n", buf);
}


refresh_interface_stats(agent)
     Agent *agent;
{
  int i;

  clear_screen();
  display_interface_header(agent);
  for(i = 0; i < port_stats.n; i++)
    display_interface_data(agent, i);
  display_interface_footer(agent);
  dpy_end();
}


clear_interface_stats()
{
  bzero(&port_stats, sizeof(port_stats));
  current_selection = -1;
  page = 1;
  bzero(astatus, sizeof(astatus));
  bzero(lstatus, sizeof(lstatus));
  bzero(ostatus, sizeof(ostatus));
  descr = (char *) NULL;
}


up_interface_marker(agent)
     Agent *agent;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; i++)
	downline();
      putchar(' ');
      current_selection--;
    }

  if(current_selection < 0)
    {
      current_selection = port_stats.n - 1;
      page =  ((port_stats.n - 1)/(LI - margin)) + 1;
      refresh_interface_stats(agent);
      return;
    }

  if(current_selection < top)
    {
      page--;
      refresh_interface_stats(agent);
      return;
    }

  move_cursor_to_data();
  for(i = top; i <= current_selection; i++)
    downline();
  
  putchar('*');
  dpy_home();
  display_interface_header(agent);
  dpy_end();
}



down_interface_marker(agent)
     Agent *agent;
{
  int i;
  int top;
  int bottom;

  top = (page - 1) * (LI - margin);
  bottom = page * (LI - margin);

  move_cursor_to_data();
  if(current_selection >= 0)
    {
      for(i = top; i <= current_selection; i++)
	downline();
      putchar(' ');
    }
  downline();
  
  current_selection++;
  if(current_selection >= port_stats.n)
    {
      current_selection = 0;
      page = 1;
      refresh_interface_stats(agent);
      return;
    }
  
  if(current_selection >= bottom)
    {
      page++;
      if(page > ((port_stats.n - 1)/(LI - margin) + 1))
	page = 1;
      refresh_interface_stats(agent);
      return;
    }

  putchar('*');
  dpy_home();
  display_interface_header(agent);
  dpy_end();
}




init_screen()
{
  char *term;
  
  if(!cp)
    {
      if(!(term = (char *) getenv("TERM")))
	term = "dumb";      
      if(tgetent(cpbuf, term) < 0)	
	{
	  printf("terminal type is dumb. Things will not work properly.\n");
	  dumb_term = 1;
	}
      cp = cpbuf;
      BC = (char *) tgetstr ("pc", &termptr);
      PC = termptr ? *termptr : 0;
      CM = (char *) tgetstr ("cm", &termptr);
      CL = (char *) tgetstr ("cl", &termptr);
      DO = (char *) tgetstr ("do", &termptr);
      HC = (char *) tgetstr ("ho", &termptr);
      UO = (char *) tgetstr ("up", &termptr);
      LI =          tgetnum("li");
      printf("screen is %d lines.", LI);
      if(LI < margin)
	{
	  printf(" too small!\n");
	  exit(1);
	}      
      if(LI < 24)
	printf(" this isn't optimal.");
      printf(" type '?' for listing of more commands.\n");
      sleep(3);
    }
  if(dumb_term)
    system("clear");
  else
    puts(CL);
}
  


move_cursor_to_data()
{
  dpy_home();
  puts("\n\n\n");
}


clear_screen()
{
  puts(CL);
}


dpy_home()
{
  if(dumb_term)
    system("clear");
  else
    puts(HC);
}


dpy_end()
{
  int i;

  dpy_home();
  for(i = 0; i < LI - 2; i++)
    putchar('\n');
}


   
upline()
{
  putchar(*UO);
  fflush(stdout);
}


downline()
{
  putchar('\n');
  fflush(stdout);
}

/*
backspace(o)
     int o;
{
  upline();
  printf("\n%*s", o, " ");
  upline();
  printf("\n");
  fflush(stdout);
}

*/ 

static void
onintr()
{
  if(more_set)
    {
      more_set = 0;
      longjmp(more, 1);
    }
  else
    {
      printf("botching the long jump...\n");
      exit(1);
    }
  return;
}


static void
restore_intr()
{
  signal(SIGINT, previous_signal);
  siginit = 0;
  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
  signal(SIGALRM, SIG_DFL);
  cooked_mode();
  if(ret_set)
    {
      ret_set = 0;
      longjmp(ret, 1);
    }
  else
    printf("botched the long jump... try another event.\n");
  return;
}


restore()
{
  signal(SIGINT, previous_signal);
  siginit = 0;
  setitimer(ITIMER_REAL, &disable, (struct itimerval *) NULL);
  signal(SIGALRM, SIG_DFL);
  page = 1;
  cooked_mode();
}



stuff()
{
  static int r = 0;
  
  if(!r)
    r = srandom(uptime * (board_stats.cur_tot_pkts + 1));

  if((random() % 20) == 1)
    {
      printf("\n      ...harder! ");
      fflush(stdout);
      getchar();
    }
}

  
  
