/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* perf720 src/perf/perfagent/usr/samples/perfagent/server/lchmon.c 1.11  */
/*                                                                        */
/*                                                                        */
/*                                                                        */
/* OBJECT CODE ONLY SOURCE MATERIALS                                      */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 1992,1993              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)22   1.9  src/perf/perfagent/usr/samples/perfagent/server/lchmon.c, perfagent, perf411, 9434B411a 8/22/94 17:40:46 */

/*
 * COMPONENT_NAME: (PERFAGENT) - Performance Agent
 *
 * FUNCTIONS:  Sample program
 *
 * ORIGINS:  30
 *
 *                  -- (                            when
 * combined with the aggregated modules for this product)
 * OBJECT CODE ONLY SOURCE MATERIALS
 * (C) COPYRIGHT International Business Machines Corp. 1992, 1996
 * All Rights Reserved
 * Licensed Material - Property of IBM
 *
 * US Government Users Restricted Rights - Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 *       NOTICE TO USERS OF THE SOURCE CODE EXAMPLES
 *
 * THE SOURCE CODE EXAMPLES PROVIDED BY IBM ARE ONLY INTENDED TO ASSIST IN THE
 * DEVELOPMENT OF A WORKING SOFTWARE PROGRAM.  THE SOURCE CODE EXAMPLES DO NOT
 * FUNCTION AS WRITTEN:  ADDITIONAL CODE IS REQUIRED.  IN ADDITION, THE SOURCE
 * CODE EXAMPLES MAY NOT COMPILE AND/OR BIND SUCCESSFULLY AS WRITTEN.
 *
 * INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THE SOURCE CODE
 * EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, "AS IS" WITHOUT
 * WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
 * OF THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS,
 * IS WITH YOU.  SHOULD ANY PART OF THE SOURCE CODE EXAMPLES PROVE
 * DEFECTIVE, YOU (AND NOT IBM OR AN AUTHORIZED RISC System/6000* WORKSTATION
 * DEALER) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR
 * CORRECTION.
 *
 * IBM does not warrant that the contents of the source code examples, whether
 * individually or as one or more groups, will meet your requirements or that
 * the source code examples are error-free.
 *
 * IBM may make improvements and/or changes in the source code examples at
 * any time.
 *
 * Changes may be made periodically to the information in the source code
 * examples; these changes may be reported, for the sample device drivers
 * included herein, in new editions of the examples.
 *
 * References in the source code examples to IBM products, programs, or
 * services do not imply that IBM intends to make these available in all
 * countries in which IBM operates.  Any reference to an IBM licensed
 * program in the source code examples is not intended to state or imply
 * that only IBM's licensed program may be used.  Any functionally equivalent
 * program may be used.
 *
 * RISC System/6000 is a trademark of International Business Machines
 * Corporation.
 *
 **********************************************************************/

#include <sys/utsname.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <curses.h>
#include <sys/Spmidef.h>
#ifdef _SOLARIS
#include <sys/filio.h>
#endif /* _SOLARIS */

extern char          SpmiErrmsg[];
extern int           SpmiErrno;

typedef struct
{
	int	line;
	int	col;
#ifdef _NO_PROTO
	void	(*fun)();
#else
	void (*fun)(long, int, int);
#endif
	float	mul;
} where;

struct itimerval  t_value;    /* time to set                      */
struct itimerval  o_value;    /* time to expiration               */

#ifdef _NO_PROTO
void p3(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%3d", val/256);
}

void p31(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%3d.%d", val/10, val%10);
}

void p41(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%4d.%d", val/10, val%10);
}

void p4d4k(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%4d", val/256);
}

void p6d4k1(val, line, row)
long val;
int line;
int row;
{
	int	v;

	move(line, row);
	v = val / 25.6;
	printw("%4d.%d", v/10, v%10);
}

void p5(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%5d", val);
}

void p6(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%6d", val);
}

void p7(val, line, row)
long val;
int line;
int row;
{
	move(line, row);
	printw("%7d", val);
}

void p7100(val, line, row)
long val;
int line;
int row;
{
	double v = val / 1024.0;

	move(line, row);
	printw("%9.1f", v);
}

#else

void p3(long val, int line, int row)
{
	move(line, row);
	printw("%3d", val/256);
}

void p31(long val, int line, int row)
{
	move(line, row);
	printw("%3d.%d", val/10, val%10);
}

void p41(long val, int line, int row)
{
	move(line, row);
	printw("%4d.%d", val/10, val%10);
}

void p4d4k(long val, int line, int row)
{
	move(line, row);
	printw("%4d", val/256);
}

void p6d4k1(long val, int line, int row)
{
	int	v;

	move(line, row);
	v = val / 25.6;
	printw("%4d.%d", v/10, v%10);
}

void p5(long val, int line, int row)
{
	move(line, row);
	printw("%5d", val);
}

void p6(long val, int line, int row)
{
	move(line, row);
	printw("%6d", val);
}

void p7(long val, int line, int row)
{
	move(line, row);
	printw("%7d", val);
}

void p7100(long val, int line, int row)
{
	double v = val / 1024.0;

	move(line, row);
	printw("%9.1f", v);
}
#endif /* _NO_PROTO */

char     gr[]="############################                            ";
char						host[64];
char						apath[256];
char						ppath[256];
char						wrk[256];
struct utsname 		uname_struct;
struct SpmiStatSet	*ssp;
struct SpmiStatVals	*svp[512];
char						head1[24][32];
char						head2[24][32];
int						lct = 99;
int						ix2 = 0;
int						ix3 = 0;
int						bot = 19;
int						interval = 5000;
int						loopcnt = 2000;
int						hot = 0;
struct timeval			tv;

char	*legend[] = {
"Spmi Data User API       Local Monitor for host",
"LCHMON Sample Program       ***          ***           Interval:        seconds",
"",
#ifdef _AIX
"% CPU                                           EVENTS/QUEUES    FILE/TTY",
"Kernel          |                            |  Pswitch          Readch",
"User            |                            |  Syscall          Writech",
"Wait            |                            |  Reads            Rawin",
"Idle            |                            |  Writes           Ttyout",
"                                                Forks            Igets",
"PAGING counts   PAGING SPACE   REAL MEM    MB   Execs            Namei",
"Faults          % Used         % Comp           Runqueue         Dirblk",
"Steals          % Free         % Noncomp        Swapqueue",
"Reclaim         Size,MB        % Client",
"",
"PAGING page/s   DISK      Read   Write     %    NETWORK    Read   Write",
"Pgspin          ACTIVITY KB/sec  KB/sec  Busy   ACTIVITY  KB/sec  KB/sec",
"Pgspout",
"Pagein",
#endif /* _AIX */
#ifdef _INCLUDE_HPUX_SOURCE
"Kern cpu%       |                            |  EVENTS/QUEUES    FILE/TTY",
"User cpu%       |                            |  Pswitch          Lreads",
"Nice cpu%       |                            |  Syscall          Lwrites",
"Wait cpu%       |                            |  Reads            Rawin",
"Idle cpu%       |                            |  Writes           Ttyout",
"                                                Forks            Igets",
"PAGING counts   PAGING SPACE   REAL MEMORY      Execs            Namei",
"Faults          % Used         Physical         Runqueue         Dirblk",
"Steals          % Free         Active           Swapqueue",
"Reclaim         Size,MB        Free",
"",
"PAGE-SWAP/sec   DISK     Transfers     KBytes   NETWORK     Read     Write",
"Swapin          ACTIVITY      /sec       /sec   ACTIVITY  Pack/sec  Pack/sec",
"Swapout",
"Pagein",
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
"% CPU                                           EVENTS/QUEUES    FILE/TTY",
"Kernel          |                            |  Pswitch          Readch",
"User            |                            |  Syscall          Writech",
"Nice            |                            |  Reads            Rawin",
"Idle            |                            |  Writes           Ttyout",
"                                                Forks            Igets",
"PAGING counts   Available memory           MB   Execs            Namei",
"Faults          Active memory              MB   Runqueue         Dirblk",
"Steals          Free memory                MB   Swapqueue",
"Reclaim         Free, % of available       %",
"",
"PAGE-SWAP/sec   DISK     Transfers     KBytes   NETWORK     Read     Write",
"Swapin          ACTIVITY      /sec       /sec   ACTIVITY  Pack/sec  Pack/sec",
"Swapout",
"Pagein",
#endif /* _SunOs */
#ifdef _SOLARIS
"% CPU                                           EVENTS/QUEUES    FILE/TTY",
"Kernel          |                            |  Pswitch          Readch",
"User            |                            |  Syscall          Writech",
"Wait            |                            |  Reads            Rawin",
"Idle            |                            |  Writes           Ttyout",
"                                                Forks            Igets",
"PAGING counts   PAGING SPACE   REAL MEM    MB   Execs            Namei",
"Faults          % Used         % Free           Runqueue         Dirblk",
"Zerofill        % Free         % Pinned         Swapqueue",
"Reclaim         Size,MB        Avl(Kb)",
"",
"PAGING page/s   DISK      Read   Write   Disk   NETWORK     Read     Write",
"Pgspin          ACTIVITY KB/sec  KB/sec IO/sec  ACTIVITY  pkg/sec   pkg/sec",
"Pgspout",
"Pagein",
#endif /* _SOLARIS */
"Pageout",
#ifdef _SOLARIS
"Cycles",
#else /* _SOLARIS */
"Sios",
#endif /* _SOLARIS */
};

char *val1[] = {
"CPU/glkern",
"CPU/gluser",
#ifdef _INCLUDE_HPUX_SOURCE
"CPU/glnice",
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
"CPU/glnice",
#else
"CPU/glwait",
#endif /* _SunOs */
"CPU/glidle",
"Mem/Virt/pagexct",
#ifdef _SOLARIS
"Mem/Virt/zerofill",
#else /* _SOLARIS */
"Mem/Virt/steal",
#endif /* _SOLARIS */
"Mem/Virt/pgrclm",
#if defined(_AIX) || defined(_SOLARIS)
"Mem/Virt/pgspgin",
"Mem/Virt/pgspgout",
#endif /* _AIX  or _SOLARIS */
#ifdef _INCLUDE_HPUX_SOURCE
"Mem/Virt/swapins",
"Mem/Virt/swapouts",
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
"Mem/Virt/swapins",
"Mem/Virt/swapouts",
#endif /* _SunOs */
"Mem/Virt/pagein",
"Mem/Virt/pageout",
#ifdef _SOLARIS
"Mem/Virt/cycle",
#else /* _SOLARIS */
"Mem/Virt/sio",
#endif /* _SOLARIS */
#ifdef _AIX
"PagSp/%totalused",
"PagSp/%totalfree",
"PagSp/totalsize",
"Mem/Real/size",
"Mem/Real/%comp",
"Mem/Real/%noncomp",
"Mem/Real/%clnt",
#endif /* _AIX */
#ifdef _INCLUDE_HPUX_SOURCE
"PagSp/%totalused",
"PagSp/%totalfree",
"PagSp/totalsize",
"Mem/Real/size",
"Mem/Real/actreal",
"Mem/Real/%free",
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
"Mem/Real/availreal",
"Mem/Real/actreal",
"Mem/Real/numfrb",
"Mem/Real/%free",
#endif /* _SunOs */
#ifdef _SOLARIS
"PagSp/%totalused",
"PagSp/%totalfree",
"PagSp/totalsize",
"Mem/Real/size",
"Mem/Real/%free",
"Mem/Real/%pinned",
"Mem/Real/avareal",
#endif /* _SOLARIS */
"Proc/pswitch",
"Syscall/total",
"Syscall/read",
"Syscall/write",
"Syscall/fork",
"Syscall/exec",
"Proc/runque",
"Proc/swpque",
#ifdef _INCLUDE_HPUX_SOURCE
"SysIO/lbread",
"SysIO/lbwrite",
#else
"SysIO/readch",
"SysIO/writech",
#endif /* _INCLUDE_HPUX_SOURCE */
"SysIO/ttyraw",
"SysIO/ttyout",
"FS/iget",
"FS/namei",
"FS/dirblk",
/*
"SysIO/readcall",
"SysIO/writecall",
*/
};

where prt1[] = {
#ifdef _INCLUDE_HPUX_SOURCE
{3, 10, p31, 10.0},
{4, 10, p31, 10.0},
{5, 10, p31, 10.0},
{6, 10, p31, 10.0},
{7, 10, p31, 10.0},
#else
{4, 8, p31, 10.0},
{5, 8, p31, 10.0},
{6, 8, p31, 10.0},
{7, 8, p31, 10.0},
#endif /* _INCLUDE_HPUX_SOURCE */
{10, 8, p5, 1.0},
{11, 8, p5, 1.0},
{12, 8, p5, 1.0},
{15, 8, p5, 1.0},
{16, 8, p5, 1.0},
{17, 8, p5, 1.0},
{18, 8, p5, 1.0},
{19, 8, p5, 1.0},
#ifdef _AIX
{10, 23, p31, 10.0},
{11, 23, p31, 10.0},
{12, 24, p4d4k, 1.0},
{9, 40, p3, 1.0},
{10, 40, p31, 10.0},
{11, 40, p31, 10.0},
{12, 40, p31, 10.0},
#endif /* _AIX */
#ifdef _INCLUDE_HPUX_SOURCE
{10, 23, p31, 10.0},
{11, 23, p31, 10.0},
{12, 24, p4d4k, 1.0},
{10, 39, p6d4k1, 1.0},
{11, 39, p6d4k1, 1.0},
{12, 40, p31, 10.0},
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
{9, 36, p6d4k1, 1.0},
{10, 36, p6d4k1, 1.0},
{11, 36, p6d4k1, 1.0},
{12, 37, p31, 10.0},
#endif /* _SunOs */
#ifdef _SOLARIS
{10, 23, p31, 10.0},
{11, 23, p31, 10.0},
{12, 24, p4d4k, 1.0},
{9, 40, p3, 1.0},
{10, 40, p31, 10.0},
{11, 40, p31, 10.0},
{12, 39, p6, 1.0},
#endif /* _SOLARIS */
{4, 56, p6, 1.0},
{5, 56, p6, 1.0},
{6, 56, p6, 1.0},
{7, 56, p6, 1.0},
{8, 56, p6, 1.0},
{9, 56, p6, 1.0},
{10, 57, p31, 10.0},
{11, 57, p31, 10.0},
{4, 72, p7, 1.0},
{5, 72, p7, 1.0},
{6, 72, p7, 1.0},
{7, 72, p7, 1.0},
{8, 72, p7, 1.0},
{9, 72, p7, 1.0},
{10, 72, p7, 1.0},
/*
{11, 72, p7, 1.0},
{12, 72, p7, 1.0},
*/
};

#ifdef _AIX
int tabsize = 34;
#endif /* _AIX */
#ifdef _INCLUDE_HPUX_SOURCE
int tabsize = 34;
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
int tabsize = 31;
#endif /* _SunOs */
#ifdef _SOLARIS
int tabsize = 34;
#endif /* _SOLARIS */

void begone()
{
   nocbreak();
	echo();
#ifndef _SunOs
	nodelay(stdscr, FALSE);
#endif /* ! _SunOs */
   endwin();
}

#if defined(_AIX) || defined(_SunOs) || defined(_SOLARIS)
boolean should_quit()
{
	int	bytes;
	char	inbuf[1024];

	ioctl(fileno(stdin), FIONREAD, &bytes);
	if (bytes > 0) 
	{
		read(fileno(stdin), inbuf, bytes);
		if ((inbuf[0] == 'q') || (inbuf[0] == 'Q'))
			return(TRUE);
	}
	return(FALSE);
}
#endif /* _AIX or _SunOs or _SOLARIS */

void dolegend()
{
	int					i;

	clear();
	for (i = 0; i < 20; i++)
	{
		move(i,0);
		addstr(legend[i]);
	}
	gettimeofday(&tv, NULL);
   move(0,55);
   addstr(ctime((time_t *)&tv));
	i = strlen(host);
	i = 36 - i / 2;
	move(1, i);
	addstr(host);
	move(1, 67);
	printw("%3d", interval/1000);
	move(20,0);
	refresh();
}

#ifdef _NO_PROTO
int addstat(ix, six, path)
int ix;
int six;
char *path;
#else
int addstat(int ix, int six, char *path)
#endif
{
   SpmiCxHdl            cxh;
	struct SpmiStat		*stp;
	int 	               i = ix;
	char						tmp[128];
   struct SpmiStatLink  *statlink;

   if (!(cxh = SpmiPathGetCx(path, NULL)))
   {
      fprintf(stderr, "SpmiPathGetCx can\'t access host %s (path %s)\n",
         host, path);
		return(i);
   }

   if ((statlink = SpmiFirstStat(cxh)))
   {
      while (statlink)
      {
			if (!(stp = SpmiGetStat(statlink->stat)))
				break;
#ifdef _AIX
			if ((six == 2) && ((!strcmp(stp->name, "busy")) ||
									 (!strcmp(stp->name, "rblk")) ||
				 					 (!strcmp(stp->name, "wblk"))))
#endif /* _AIX */
#ifdef _INCLUDE_HPUX_SOURCE
			if ((six == 2) && ((!strcmp(stp->name, "xfer")) ||
				 					 (!strcmp(stp->name, "xferbytes"))))
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
			if ((six == 2) && ((!strcmp(stp->name, "xfer")) ||
				 					 (!strcmp(stp->name, "xferbytes"))))
#endif /* _SunOs */
#ifdef _SOLARIS
			if ((six == 2) && ((!strcmp(stp->name, "xfer")) ||
									 (!strcmp(stp->name, "nread")) ||
				 					 (!strcmp(stp->name, "nwritten"))))
#endif /* _SOLARIS */
			{
				strcpy(tmp, path);
				strcat(tmp, "/");
				strcat(tmp, stp->name);
				svp[i] = SpmiPathAddSetStat(ssp, tmp, NULL);
				i++;
			}
#ifdef _AIX
			if ((six == 3) && ((!strcmp(stp->name, "ioctet")) ||
				 					 (!strcmp(stp->name, "ooctet"))))
#endif /* _AIX */
#ifdef _INCLUDE_HPUX_SOURCE
			if ((six == 3) && ((!strcmp(stp->name, "ipacket")) ||
				 					 (!strcmp(stp->name, "opacket"))))
#endif /* _INCLUDE_HPUX_SOURCE */
#ifdef _SunOs
			if ((six == 3) && ((!strcmp(stp->name, "ipacket")) ||
				 					 (!strcmp(stp->name, "opacket"))))
#endif /* _SunOs */
#ifdef _SOLARIS
			if ((six == 3) && ((!strcmp(stp->name, "framesin")) ||
				 					 (!strcmp(stp->name, "framesout"))))
#endif /* _SOLARIS */
			{
				strcpy(tmp, path);
				strcat(tmp, "/");
				strcat(tmp, stp->name);
				svp[i] = SpmiPathAddSetStat(ssp, tmp, NULL);
				i++;
			}
         statlink = SpmiNextStat(statlink);
      }
   }
	return(i);
}

#ifdef _NO_PROTO
int addcont(ix, six, path)
int ix;
int six;
char *path;
#else
int addcont(int ix, int six, char *path)
#endif
{
	int 	               i = ix, n = 0;
	char						tmp[128];
	char						*s;
   SpmiCxHdl				cxh;
	struct SpmiCx			*cxp;
   struct SpmiStatLink  *statlink;
   struct SpmiCxLink    *cxlink;

   cxh = SpmiPathGetCx(path, NULL);
   if (!cxh)
   {
		if (strlen(SpmiErrmsg))
			fprintf(stderr, "%s", SpmiErrmsg);
      fprintf(stderr, "SpmiPathGetCx can\'t access path %s\n",
         path);
		return(i);
   }

   if ((cxlink = SpmiFirstCx(cxh)))
   {
      while (cxlink)
      {
			if (!(cxp = SpmiGetCx(cxlink->context)))
				break;
			if (six == 2)
				s = head1[n];
			else
				s = head2[n];
			strcpy(s, cxp->name);
			s[9] = '\0';
			if (six == 2)
				mvaddstr(16 + n, 16, s);
			else
				mvaddstr(16 + n, 48, s);
			if (bot < (n + 16))
				bot = n + 16;
			n++;
        	strcpy(tmp, path);
         if (strlen(tmp))
				strcat(tmp, "/");
        	if (cxp->name)
        		strcat(tmp, cxp->name);
			if ((i = addstat(i, six, tmp)) == -1)
			{
				if (strlen(SpmiErrmsg))
					fprintf(stderr, "%s", SpmiErrmsg);
				begone();
      		exit(63);
			}
         cxlink = SpmiNextCx(cxlink);
      }
   }
	return(i);
}

#ifdef _NO_PROTO
void getproc(path)
char *path;
#else
void getproc(char *path)
#endif
{
	int 	               n = bot + 2, cont = hot;
	char						tmp[128];
	char						*s;
   SpmiCxHdl				cxh;
	struct SpmiCx			*cxp;
   struct SpmiStatLink  *statlink;
   struct SpmiCxLink    *cxlink;

   cxh = SpmiPathGetCx(path, NULL);
  	if (!cxh)
   {
		return;
   }
   if ((cxlink = SpmiFirstCx(cxh)))
   {
      while ((cxlink) && (cont))
      {
			if (!(cxp = SpmiGetCx(cxlink->context)))
				break;
			mvaddstr(n, 8, cxp->description);
			n++;
			cont--;
         cxlink = SpmiNextCx(cxlink);
      }
   }
}

/*============================= lststats() ==============================*/

#ifdef _NO_PROTO
void lststats(basepath)
char *basepath;
#else
void lststats(char *basepath)
#endif
{
	int						m, i, c, n;
	char						tmp[128];

	strcpy(ppath, basepath);
	strcat(ppath, "Proc");

	if (!(ssp = SpmiCreateStatSet()))
	{
     	fprintf(stderr, "SpmiCreateStatSet can\'t create StatSet\n");
		begone();
     	exit(62);
	}

	for (m = 0; m < tabsize; m++)
	{
		strcpy(tmp, basepath);
		strcat(tmp, val1[m]);
		svp[m] = SpmiPathAddSetStat(ssp, tmp, NULL);
	}

	strcpy(tmp, basepath);
	strcat(tmp, "Disk");
	if ((i = addcont(tabsize, 2, tmp)) == -1)
	{
		if (strlen(SpmiErrmsg))
			fprintf(stderr, "%s", SpmiErrmsg);
		begone();
      exit(65);
	}
	ix2 = i - m;
	m = i;

	strcpy(tmp, basepath);
#ifdef _SOLARIS
	strcat(tmp, "LAN");
#else /* _SOLARIS */
	strcat(tmp, "IP/NetIF");
#endif /* _SOLARIS */
	if ((i = addcont(m, 3, tmp)) == -1)
	{
		if (strlen(SpmiErrmsg))
			fprintf(stderr, "%s", SpmiErrmsg);
		begone();
      exit(65);
	}
	ix3 = i - m;
	m = i;
}

void must_exit()
{
	SpmiExit();
	exit(-9);
}

#ifdef _NO_PROTO
void sig_proc(code)
int code;
#else
void sig_proc(int code)
#endif /* _NO_PROTO */
{
   begone();
	printf("Signal %d received\n", code);
	must_exit();
}

void feeding()
{
	int 		i, m, l, c;
	float		f;
	long		v;

	signal(SIGALRM, SIG_IGN);
	gettimeofday(&tv, NULL);
   move(0,55);
   addstr(ctime((time_t *)&tv));

	if (SpmiGetStatSet(ssp, TRUE))
	{
		if (SpmiErrno == SiLocked)
		{
#if defined(_AIX) || defined(_SunOs) || defined(_SOLARIS)
				if (should_quit())
#else
				if (((c = getch()) == 'q') || (c == 'Q'))
#endif /* _AIX or _SunOs or _SOLARIS */
			{
   			begone();
				must_exit();
			}
#ifdef _NO_PROTO
  				signal(SIGALRM, (void(*)())feeding);
#else
  				signal(SIGALRM, (void(*)(int))feeding);
#endif /* _NO_PROTO */
			return;
		}
   	begone();
		printf("Unable to read statistics: Error code %d\n   [%s]\n",
			SpmiErrno, SpmiErrmsg);
		must_exit();
	}
	loopcnt--;
	for (i = 0; i < tabsize; i++)
	{
		v = SpmiGetValue(ssp, svp[i]) * prt1[i].mul;
		if (v >= 0)
		{
			prt1[i].fun(v, prt1[i].line, prt1[i].col);
#if defined(_INCLUDE_HPUX_SOURCE) || defined(_SunOs)
#ifdef _SunOs
			if (i < 4)
			{
				m = 1000 - v + 15;
				m = (m * 28) / 1000;
				strncpy(wrk, gr + m, 28);
				wrk[28] = '\0';
				mvaddstr(4 + i, 17, wrk);
#else
			if (i < 5)
			{
				m = 1000 - v + 15;
				m = (m * 28) / 1000;
				strncpy(wrk, gr + m, 28);
				wrk[28] = '\0';
				mvaddstr(3 + i, 17, wrk);
#endif /* _SunOs */
			}
		}
	}

	l = ix2 / 2;
	for (i = 0; i < l; i++)
	{
		v = SpmiGetValue(ssp, svp[tabsize + i*2]);
		if (v >= 0)
			p7(v, 16 + i, 27);
		v = SpmiGetValue(ssp, svp[tabsize + 1 + i*2]);
		if (v >= 0)
			p7100(v, 16 + i, 36);
	}
#else
			if (i < 4)
			{
				m = 1000 - v + 15;
				m = (m * 28) / 1000;
				strncpy(wrk, gr + m, 28);
				wrk[28] = '\0';
				mvaddstr(4 + i, 17, wrk);
			}
		}
	}

	l = ix2 / 3;
	for (i = 0; i < l; i++)
	{
		v = SpmiGetValue(ssp, svp[tabsize + i*3]) * 10.0;
		if (v >= 0)
			p31(v, 16 + i, 40);
		v = SpmiGetValue(ssp, svp[tabsize + 1 + i*3]) * 5.0;
		if (v >= 0)
			p41(v, 16 + i, 25);
		v = SpmiGetValue(ssp, svp[tabsize + 2 + i*3]) * 5.0;
		if (v >= 0)
			p41(v, 16 + i, 33);
	}
#endif /* _INCLUDE_HPUX_SOURCE or _SunOs */

	m = tabsize + ix2;
	l = ix3 >> 1;
	for (i = 0; i < l; i++)
	{
#ifdef _AIX
		v = SpmiGetValue(ssp, svp[m + i*2]) / 102.4;
		if (v >= 0)
			p31(v, 16 + i, 58);
		v = SpmiGetValue(ssp, svp[m + 1 + i*2]) / 102.4;
		if (v >= 0)
			p41(v, 16 + i, 66);
#endif /* _AIX */
#if defined(_INCLUDE_HPUX_SOURCE) || defined(_SunOs)
		v = SpmiGetValue(ssp, svp[m + i*2]);
		if (v >= 0)
			p6(v, 16 + i, 59);
		v = SpmiGetValue(ssp, svp[m + 1 + i*2]);
		if (v >= 0)
			p6(v, 16 + i, 69);
#endif /* _INCLUDE_HPUX_SOURCE or _SunOs */
#if defined(_SOLARIS)
		v = SpmiGetValue(ssp, svp[m + i*2]);
		if (v >= 0)
			p6(v, 16 + i, 69);
		v = SpmiGetValue(ssp, svp[m + 1 + i*2]);
		if (v >= 0)
			p6(v, 16 + i, 59);
#endif /* _SOLARIS */
	}

	if (hot)
		getproc(ppath);

	move(bot, 79);
	refresh();
	if (!loopcnt)
	{
		SpmiExit();
   	begone();
		exit(0);
	}
#if defined(_AIX) || defined(_SunOs) || defined(_SOLARIS)
	if (should_quit())
#else
	if (((c = getch()) == 'q') || (c == 'Q'))
#endif /* _AIX or _SunOs or _SOLARIS */
	{
   	begone();
		must_exit();
	}
#ifdef _NO_PROTO
	signal(SIGALRM, (void(*)())feeding);
#else
	signal(SIGALRM, (void(*)(int))feeding);
#endif /* _NO_PROTO */
}

/*================================  main()  ============================*/

#ifdef _NO_PROTO
int main(argc, argv)
int argc;
char **argv;
#else
int main(int argc, char **argv)
#endif
{
	int				i, c, args = 0;
   extern int     optind, opterr;
   extern char    *optarg;

   uname(&uname_struct);
	strcpy(host, uname_struct.nodename);

   while ((c = getopt(argc, argv, "i:p:")) != EOF)
   {
      switch (c)
      {
         case 'i':
            i = atoi(optarg);
				if ((i < 0) || (1 > 60))
					i = 5;
				interval = i * 1000;
            args++;
            break;
         case 'p':
            i = atoi(optarg);
            args++;
				if (i >= 0)
				{
					hot = i;
					break;
				}
				/* fall through */
			default:
				fprintf(stderr,
					"usage: %s [-i seconds_interval] [-p processes]\n\n",
					argv[0]);
				exit(-1);
				break;
		}
	}

	/*
		connect to the Spmi interface
	*/
   if (SpmiInit(30))
   {
      fprintf(stderr, "%s: Unable to initialize Spmi interface\n",
            argv[0]);
      if (SpmiErrmsg[0])
      {
         fprintf(stderr, "%s\n", SpmiErrmsg);
      }
      exit(8);
   }

#ifdef _NO_PROTO
	signal(SIGINT,  (void(*)())sig_proc);
	signal(SIGTERM, (void(*)())sig_proc);
	signal(SIGSEGV, (void(*)())sig_proc);
	signal(SIGQUIT, (void(*)())sig_proc);
#else
	signal(SIGINT,  (void(*)(int))sig_proc);
	signal(SIGTERM, (void(*)(int))sig_proc);
	signal(SIGQUIT, (void(*)(int))sig_proc);
#endif

	initscr();
   cbreak();
	noecho();
#ifndef _SunOs
	nodelay(stdscr, TRUE);
#endif /* ! _SunOs */
	dolegend();

	/*
		Do actual processing
	*/
	apath[0] = '\0';
	lststats(apath);
	t_value.it_interval.tv_sec =  interval/1000;
   if (t_value.it_interval.tv_sec < 1)
      t_value.it_interval.tv_sec =  1;
   t_value.it_interval.tv_usec = 0;
   t_value.it_value.tv_sec =  t_value.it_interval.tv_sec;
   t_value.it_value.tv_usec = 0;
   if (setitimer(ITIMER_REAL, &t_value, &o_value) < 0)
   {
   	begone();
      printf("error no %d while setting interval timer\n", errno);
      must_exit();
   }
#ifdef _NO_PROTO
   signal(SIGALRM, (void(*)())feeding);
#else
   signal(SIGALRM, (void(*)(int))feeding);
#endif /* _NO_PROTO */

   while (TRUE)
   {
      pause();
   }

	SpmiExit();
	begone();
	exit(0);
}
