home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright (c) 1991 Bolt Beranek and Newman, Inc.
- ** All rights reserved.
- **
- ** Redistribution and use in source and binary forms are permitted
- ** provided that: (1) source distributions retain this entire copyright
- ** notice and comment, and (2) distributions including binaries display
- ** the following acknowledgement: ``This product includes software
- ** developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the
- ** documentation or other materials provided with the distribution and in
- ** all advertising materials mentioning features or use of this software.
- ** Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used
- ** to endorse or promote products derived from this software without
- ** specific prior written permission.
- **
- ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- ** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <curses.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <sys/dk.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <sys/param.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <net/if_du.h>
- #include "dialmon.h"
-
- /* Shut up, lint */
- #define Refresh (void)refresh
- #define Wrefresh (void)wrefresh
- #define Wclear (void)wclear
- #define Wclrtoeol (void)wclrtoeol
- #define Wprintw (void)wprintw
- #define Wmove (void)wmove
-
- /* Configuration data. */
- #define MAXRECS 40 /* Max # of types of log records */
- #define MAXPLOTS 49 /* # of plots per log record graph */
- #define MAXWINDOWS 4 /* # of available windows */
- #define HOSTNAMESIZE 25 /* Size of a host name */
- #define MAXINTERVALS 1 /* intervals/average */
- #define HOSTNAMELEN 128
-
- /* Window numbers */
- #define W_GLOBAL 0 /* Site-wide statistics */
- #define W_LINE 1 /* Active line statistics */
- #define W_TOTAL 2 /* Active line totals */
- #define W_HELP 3 /* Help function */
-
- #define NOTSET -1 /* When a yloc is not in use */
- #define LINE_NOTCONF 'N' /* When a serial line is not configured */
- #define MAXREQUEST 25 /* Maximum size of a request */
-
-
- /* Fields in status structures, and statistics computed from them. */
- #define R_CIPUP 0
- #define R_CIPLN 1
- #define R_COPUP 2
- #define R_COPLN 3
- #define R_CPSIP 4
- #define R_CPRIP 5
- #define R_CTPBUSY 6
- #define R_CTPIDLE 7
- #define R_CCHS 8
- #define R_CCHR 9
- #define R_gCHS 10 /* Global chars sent */
- #define R_gCHR 11 /* Global chars received */
- #define R_aCHS 12 /* Average chars sent */
- #define R_aPKTS 13 /* Average pkts sent */
- #define R_aCHPKTS 14 /* Average chars/pkt sent */
- #define R_aCHR 15 /* Average chars received */
- #define R_aPKTR 16 /* Average pkts received */
- #define R_aCHPKTR 17 /* Average chars/pkt received */
- #define R_aPCTESC 18 /* Average percent of esc chars sent */
- #define R_STATE 19 /* State of the du_softc interface */
- #define R_ESCR 20 /* number of esc chars received */
- #define R_ESCS 21 /* number of esc chars sent */
- #define R_IERROR 22
- #define R_OERROR 23
- #define R_gIERROR 24 /* Global */
- #define R_gOERROR 25 /* Global */
-
-
- /* A dial log record. */
- typedef struct _DIALLOGREC {
- int yloc; /* Where to graph packet counts with the
- * corresponding attributes */
- int Count; /* new packet count */
- int Old; /* old count, so can update plots without
- * redrawing entire plot */
- float fCount; /* New count packets as a float */
- int Line; /* line number, 0 for global stats */
- int Window; /* window to display this record in */
- } DIALLOGREC;
-
- /* Averages */
- typedef struct _AVERAGES {
- int chs; /* Characters sent */
- int pkts; /* Packets sent */
- int chr; /* Characters received */
- int pktr; /* Packets received */
- int sescs; /* Escape chars sent */
- int rescs; /* Escape chars received */
- int ierror; /* Input errors */
- int oerror; /* Output errors */
- int sec; /* Seconds between getting new data */
- } AVERAGES;
-
-
- static AVERAGES Averages[MAX_NDU][MAXINTERVALS];
- static char HostName[HOSTNAMELEN];
- static char OtherHost[MAX_NDU][HOSTNAMESIZE];
- static DIALSTATS StatsCur;
- static DIALSTATS StatsOld;
- static DIALSTATS StatsReset;
- static int fd; /* Descriptor connected to server */
- static int CurrLine; /* Current serial line */
- static int freset; /* Using reset totals? */
- static int CurrWind; /* Current window */
- static int maxyloc; /* largest y-local in graph window */
- static int newdata; /* Index into Averages */
- static int cursed; /* Curses set up? */
- static WINDOW *Wgraph;
- static WINDOW *Whelp;
- static WINDOW *Wprompt;
- static WINDOW *Wtitle;
- static WINDOW *Wtypes;
-
- /* Pointers to log records which hold 5 sec data, logical line number this
- * log record applies to and the y-position where this data is printed. */
- static DIALLOGREC *Records[MAXRECS];
-
- /* State of du_softc interface. One message/bit. */
- static char *DUStateMessages[] = {
- "ESCAPED",
- "OACTIVE",
- "",
- "",
- "LWAITING",
- "LACTIVE",
- "LDOWN",
- "FAILCALL",
- "MONITORON"
- };
-
- /* Type descriptions. */
- static char *TypeDescriptions[] = {
- "Pkts received from IP",
- "Pkts from remote site",
- "Pkts passed to IP",
- "Pkts sent to remote site",
- "Pkts passed to IP",
- "Pkts received from IP",
- "Status of line",
- "Tty busy",
- "Percent tty idle",
- "Characters sent",
- "Characters received",
- "Characters sent",
- "Characters received",
- "Avg chars sent/sec",
- "Avg pkts sent/sec",
- "Avg chars/pkt sent",
- "Avg chars received/sec",
- "Avg pkts received/sec",
- "Avg chars/pkt received",
- "Avg chars received/interrupt",
- "Avg chars escaped",
- "Escape chars received",
- "State of interface",
- "Escape chars sent",
- "Line Input Errors",
- "Line Output Errors",
- "Global Input Errors",
- "Global Output Errors"
- };
-
-
- extern char *progname;
- extern char *dip_release();
-
- extern int errno;
- extern int h_errno;
- extern int optind;
- extern char *ctime();
- extern char *malloc();
- extern char *optarg;
- extern char *strchr();
- extern char *strcpy();
- extern char *strerror();
- extern char *strncpy();
- extern time_t time();
- extern unsigned int sleep();
- extern void bcopy();
- extern void exit();
-
-
-
- /*
- ** Normal exit.
- */
- static void
- ext()
- {
- (void)close(fd);
- if (cursed)
- endwin();
- (void)printf("\n");
- exit(0);
- }
-
- /*
- ** Print error and exit.
- */
- static void
- fatal(text)
- char *text;
- {
- int oerrno;
-
- oerrno = errno;
- (void)close(fd);
- if (cursed) {
- Wmove(stdscr, COLS - 1, LINES - 1);
- Refresh();
- endwin();
- }
- (void)fprintf(stderr, "\n\n%s, %s\n", text, strerror(oerrno));
- exit(1);
- }
-
-
-
-
- /*
- ** Compute the average stats for a line.
- */
- static void
- computeavgs(i)
- int i;
- {
- int j;
- float *fp1;
- float *fp2;
- float time;
- AVERAGES *aptr;
-
- /* Get the pointer to the new data. */
- aptr = &Averages[i][newdata];
- aptr->chs = Records[R_CCHS][i].Count;
- aptr->pkts = Records[R_CPSIP][i].Count;
- aptr->chr = Records[R_CCHR][i].Count;
- aptr->pktr = Records[R_CPRIP][i].Count;
- aptr->rescs = Records[R_ESCR][i].Count;
- aptr->sescs = Records[R_ESCS][i].Count;
- aptr->sec = StatsCur.when - StatsOld.when;
- aptr->ierror = Records[R_IERROR][i].Count;
- aptr->oerror = Records[R_OERROR][i].Count;
-
- /* Total over MAXINTERVALS intervals. */
- Records[R_aCHS][i].fCount = 0.0;
- Records[R_aPKTS][i].fCount = 0.0;
- Records[R_aCHR][i].fCount = 0.0;
- Records[R_aPKTR][i].fCount = 0.0;
- Records[R_aPCTESC][i].fCount = 0.0;
- for (time = 0.0, j = 0; j < MAXINTERVALS; j++) {
- aptr = &Averages[i][j];
- Records[R_aCHS][i].fCount += aptr->chs;
- Records[R_aPKTS][i].fCount += aptr->pkts;
- Records[R_aCHR][i].fCount += aptr->chr;
- Records[R_aPKTR][i].fCount += aptr->pktr;
- Records[R_aPCTESC][i].fCount += aptr->rescs;
- time += aptr->sec;
- }
-
- /* Compute average chars sent/packet. */
- fp1 = &Records[R_aCHS][i].fCount;
- fp2 = &Records[R_aPKTS][i].fCount;
- Records[R_aCHPKTS][i].fCount = *fp2 ? *fp1 / *fp2 : 0.0;
-
- if (time)
- *fp2 /= time;
-
- /* Factor in escape characters sent. */
- fp2 = &Records[R_aPCTESC][i].fCount;
- *fp2 = *fp1 ? (*fp2 / *fp1 ) * 100. : 0.0;
-
- if (time)
- *fp1 /= time;
-
-
- /* Computer average chars received/packet. */
- fp1 = &Records[R_aCHR][i].fCount;
- fp2 = &Records[R_aPKTR][i].fCount;
- Records[R_aCHPKTR][i].fCount = *fp2 ? *fp1 / *fp2 : 0.0;
- if (time) {
- *fp1 /= time;
- *fp2 /= time;
- }
- }
-
- /*
- ** Compute the differences between the old and new values of the stats
- ** structures and save the results in a log record. Since not all
- ** lines need have been configured on a host, set it to NOTCONF if
- ** necessary. The StatsReset variable holds all totals since the last
- ** reset command.
- */
- static void
- computediffs()
- {
- LINESTATS *old;
- LINESTATS *cur;
- LINESTATS *res;
- int i;
- struct hostent *hp;
- unsigned long *paddr;
-
- /* global stats */
- StatsReset.ipup +=
- Records[R_CIPUP]->Count = StatsCur.ipup - StatsOld.ipup;
- StatsOld.ipup = StatsCur.ipup;
-
- StatsReset.ipln +=
- Records[R_CIPLN]->Count = StatsCur.ipln - StatsOld.ipln;
- StatsOld.ipln = StatsCur.ipln;
-
- StatsReset.opup +=
- Records[R_COPUP]->Count = StatsCur.opup - StatsOld.opup;
- StatsOld.opup = StatsCur.opup;
-
- StatsReset.opln +=
- Records[R_COPLN]->Count = StatsCur.opln - StatsOld.opln;
- StatsOld.opln = StatsCur.opln;
-
- /* line stats */
- old = StatsOld.ln;
- cur = StatsCur.ln;
- res = StatsReset.ln;
- for (i = 0; i < StatsCur.ndu; i++, old++, res++) {
- if (cur->ln == i) {
- /* line i is configured and new data was sent */
- Records[R_STATE][i].Count = cur->flags;
- res->cchr += Records[R_CCHR][i].Count = cur->cchr - old->cchr;
- old->cchr = cur->cchr;
-
- /* sum up characters received for global stats */
- Records[R_gCHR]->Count += Records[R_CCHR][i].Count;
- res->cchs += Records[R_CCHS][i].Count = cur->cchs - old->cchs;
- old->cchs = cur->cchs;
-
- /* sum up characters sent for global stats */
- Records[R_gCHS]->Count += Records[R_CCHS][i].Count;
- res->cpsip += Records[R_CPSIP][i].Count = cur->cpsip - old->cpsip;
- old->cpsip = cur->cpsip;
- res->cprip += Records[R_CPRIP][i].Count = cur->cprip - old->cprip;
- old->cprip = cur->cprip;
-
- res->ierror +=
- Records[R_IERROR][i].Count = cur->ierror - old->ierror;
- old->ierror = cur->ierror;
- Records[R_gIERROR]->Count += Records[R_IERROR][i].Count;
-
- res->oerror +=
- Records[R_OERROR][i].Count = cur->oerror - old->oerror;
- old->oerror = cur->oerror;
- Records[R_gOERROR]->Count += Records[R_OERROR][i].Count;
-
- /* Handle wrap-around */
- Records[R_CTPBUSY][i].fCount = cur->ctpbusy < old->ctpbusy
- ? (float)((unsigned int)cur->ctpbusy - (unsigned int)old->ctpbusy)
- : (float)(cur->ctpbusy - old->ctpbusy);
- res->ctpbusy += (int)Records[R_CTPBUSY][i].fCount;
- old->ctpbusy = cur->ctpbusy;
-
- /* Counter wrapped around. */
- Records[R_CTPIDLE][i].fCount = cur->ctpidle < old->ctpidle
- ? (unsigned int)cur->ctpidle - (unsigned int)old->ctpidle
- : cur->ctpidle - old->ctpidle;
-
- res->ctpidle += (int)Records[R_CTPIDLE][i].fCount;
- old->ctpidle = cur->ctpidle;
-
- res->resc += Records[R_ESCR][i].Count = cur->resc - old->resc;
- old->resc = cur->resc;
- res->sesc += Records[R_ESCS][i].Count = cur->sesc - old->sesc;
- old->sesc = cur->sesc;
-
- /* Get the nost on the other end of the line, if different. */
- cur->dest.s_addr = ntohl(cur->dest.s_addr);
- if (old->dest.s_addr != cur->dest.s_addr) {
- paddr = &cur->dest.s_addr;
- if (*paddr) {
- if (hp = gethostbyaddr(paddr, sizeof *paddr, AF_INET)) {
- (void)strncpy(OtherHost[i], hp->h_name,
- sizeof OtherHost[i] - 1);
- OtherHost[i][HOSTNAMESIZE - 1] = '\0';
- }
- else
- (void)strcpy(OtherHost[i], inet_ntoa(*paddr));
- }
- else
- (void)strcpy(OtherHost[i], "UNINITIALIZED");
- res->dest.s_addr = old->dest.s_addr = cur->dest.s_addr;
- }
-
- res->ln = old->ln = cur->ln;
- cur->ln = LINE_NOTCONF;
- cur++;
- computeavgs(i);
- }
- else {
- /* line i not configured, no new data was sent */
- res->ln = old->ln = LINE_NOTCONF;
- if ((CurrWind == W_LINE || CurrWind == W_TOTAL) && CurrLine == i)
- LineNotConf(i);
- }
- }
-
- /* finished storing this set of data, increment for the next set */
- if (++newdata >= MAXINTERVALS)
- newdata = 0;
-
- /* save current time value */
- StatsOld.when = StatsCur.when;
- }
-
-
- /*
- ** Convert fields in struct to host order
- */
- FromNetworkOrder(sp)
- DIALSTATS *sp;
- {
- int i;
- LINESTATS *lsp;
-
- sp->when = ntohl((unsigned long)sp->when);
- for (i = 0; i < 3; i++)
- sp->avenrun[i] = ntohl(sp->avenrun[i]);
- for (i = 0; i < CPUSTATES; i++)
- sp->cputime[i] = ntohl(sp->cputime[i]);
- sp->ipup = ntohl(sp->ipup);
- sp->ipln = ntohl(sp->ipln);
- sp->opln = ntohl(sp->opln);
- sp->opup = ntohl(sp->opup);
- sp->ndu = ntohl(sp->ndu);
- for (lsp = sp->ln; lsp < &sp->ln[sp->ndu]; lsp++) {
- lsp->cchr = ntohl(lsp->cchr);
- lsp->cchs = ntohl(lsp->cchs);
- lsp->cpsip = ntohl(lsp->cpsip);
- lsp->cprip = ntohl(lsp->cprip);
- lsp->flags = ntohl(lsp->flags);
- lsp->ctpbusy = ntohl(lsp->ctpbusy);
- lsp->ctpidle = ntohl(lsp->ctpidle);
- lsp->sesc = ntohl(lsp->sesc);
- lsp->resc = ntohl(lsp->resc);
- lsp->dest.s_addr = ntohl(lsp->dest.s_addr);
- lsp->ierror = ntohl(lsp->ierror);
- lsp->oerror = ntohl(lsp->oerror);
- lsp->ln = ntohl(lsp->ln);
- }
- }
-
-
- /*
- ** Compute tty percents per line.
- */
- static void
- computettypercent()
- {
- float ttysum;
- float percent;
- int i;
- DIALLOGREC *busyp;
- DIALLOGREC *idlep;
-
- busyp = Records[R_CTPBUSY];
- idlep = Records[R_CTPIDLE];
- for (i = 0; i < MAX_NDU; i++, busyp++, idlep++) {
- ttysum = busyp->fCount + idlep->fCount;
- if (ttysum == 0.0)
- continue;
- percent = (busyp->fCount / ttysum) * 100.0;
- busyp->fCount = percent;
- percent = (idlep->fCount / ttysum) * 100.0;
- idlep->fCount = percent;
- }
- }
-
-
- /*
- ** Read data from the socket.
- */
- static void
- readsocket(fd)
- int fd;
- {
- char *timep;
- char *p;
- int n;
- int ntot;
- unsigned long size;
-
- /* Find out how much to read. */
- if (read(fd, (caddr_t)&size, sizeof size) != sizeof size)
- fatal("Can't read size of stats");
- size = ntohl(size);
-
- /* Read in all the data. */
- for (ntot = 0, p = (char *)&StatsCur; ntot < size; ntot += n, p += n)
- if ((n = read(fd, p, size - ntot)) <= 0)
- fatal("Read from server failed");
- FromNetworkOrder(&StatsCur);
-
- /* Update the time. */
- timep = ctime(&StatsCur.when);
- if (p = strchr(timep, '\n'))
- *p = '\0';
- Wmove(Wtitle, 1, 36);
- Wprintw(Wtitle, "%s", timep);
-
- /* Update the status fields. */
- UpdateStatus();
- Wrefresh(Wtitle);
-
- /* Compute differences, update the records. */
- computediffs();
- computettypercent();
-
- /* Update the graphs for the displayed window */
- if (CurrWind == W_GLOBAL || CurrWind == W_LINE)
- UpdateGraphs();
- else if (CurrWind == W_TOTAL)
- UpdateTotals();
- Wrefresh(Wprompt);
- }
-
-
-
- /*
- ** Process the request read from the terminal.
- */
- static void
- processrequest(buff)
- char *buff;
- {
- char *p;
- int arg;
- int c;
-
- for (arg = NOTSET, p = buff; *p && isspace(*p); p++)
- ;
-
- for (c = *p; *++p && isspace(*p); )
- ;
-
- switch (c) {
-
- case 'g':
- globalstats();
- return;
-
- case 'q':
- ext();
- /* NOTREACHED */
-
- case 'l':
- if (isdigit(*p) && (arg = atoi(p)) < MAX_NDU) {
- linestats(arg);
- return;
- }
-
- case 't':
- if (*p == 'g') {
- totalstats(NOTSET);
- return;
- }
- if (isdigit(*p) && (arg = atoi(p)) < MAX_NDU) {
- totalstats(arg);
- return;
- }
- break;
-
- case 'r':
- switch (*p) {
- case 'n':
- reset(FALSE);
- return;
- case 'y':
- reset(TRUE);
- return;
- }
- break;
- }
-
- helpwindow();
- }
-
-
- /*
- ** Read input from the user.
- */
- readterminal()
- {
- static char buff[MAXREQUEST];
- static int curpos;
- int count;
- int done;
- int i;
- char *p;
-
- /* Refresh the screen, read if there is any input. */
- Wrefresh(Wprompt);
- if (ioctl(0, FIONREAD, (caddr_t)&count) >= 0 && count <= 0)
- return;
-
- p = &buff[curpos];
- for (done = FALSE, i = 0; i < count && !done; i++) {
- switch (*p = wgetch(Wprompt)) {
- default:
- if (p < &buff[sizeof buff - 1])
- p++;
- break;
- case '\n':
- case '\r':
- *p = '\0';
- done = TRUE;
- break;
- case '\177':
- case '\b':
- if (p > buff)
- p--;
- break;
- case '\f':
- Wrefresh(curscr);
- break;
- }
- }
-
- /* Redraw the line. */
- curpos = p - buff;
- Wclear(Wprompt);
- Wprintw(Wprompt, " ? ");
- for (p = buff, i = 0; i < curpos; i++, p++)
- Wprintw(Wprompt, "%c", *p);
- Wrefresh(Wprompt);
-
- /* If we got a full line, execute it. */
- if (done) {
- curpos = 0;
- processrequest(buff);
- Wclear(Wprompt);
- Wprintw(Wprompt, " ? ");
- Wrefresh(Wprompt);
- }
- }
-
-
-
- /*
- ** Allocate storage for global log records
- */
- static void
- AllocGStor(i, yloc)
- int i;
- int yloc;
- {
- DIALLOGREC *drp;
-
- if (yloc >= maxyloc)
- fatal("Screen too small (global stats)");
- if ((drp = (DIALLOGREC *)malloc(sizeof *drp)) == NULL)
- fatal("Can't malloc storage for global log record");
- drp->yloc = yloc;
- drp->Old = 0;
- drp->Count = 0;
- drp->fCount = 0.0;
- drp->Line = 0;
- drp->Window = W_GLOBAL;
- Records[i] = drp;
- }
-
-
- /*
- ** Allocate storage for line log records
- */
- static void
- AllocLStor(i, yloc)
- int i;
- int yloc;
- {
- DIALLOGREC *drp;
- int j;
-
- if (yloc >= maxyloc)
- fatal("Screen too small (line stats)");
- if ((drp = (DIALLOGREC *)malloc(MAX_NDU * sizeof *drp)) == NULL)
- fatal("Can't malloc storage for line log record");
-
- for (Records[i] = drp, j = 0; j < MAX_NDU; j++, drp++) {
- drp->yloc = yloc;
- drp->Old = 0;
- drp->Count = 0;
- drp->fCount = 0.0;
- drp->Line = j;
- drp->Window = W_LINE;
- }
- }
-
-
- /*
- ** Initialize data structures.
- */
- static void
- initdata()
- {
- int i;
- int j;
- LINESTATS *old;
- LINESTATS *cur;
- LINESTATS *res;
- struct timeval tv;
- AVERAGES *aptr;
-
- CurrWind = NOTSET;
- CurrLine = NOTSET;
- freset = FALSE;
- newdata = 0;
- maxyloc = LINES - 5; /* 4 lines at top, one for prompt at bottom */
-
- StatsCur.when = gettimeofday(&tv, (struct timezone *)NULL) < 0
- ? 0 : tv.tv_sec;
- StatsCur.avenrun[0] = 0;
- StatsCur.avenrun[1] = 0;
- StatsCur.avenrun[2] = 0;
-
- for (i = 0; i < CPUSTATES; i++)
- StatsCur.cputime[i] = 0;
-
- StatsReset.ipup = StatsCur.ipup = StatsOld.ipup = 0;
- StatsReset.ipln = StatsCur.ipln = StatsOld.ipln = 0;
- StatsReset.opln = StatsCur.opln = StatsOld.opln = 0;
- StatsReset.opup = StatsCur.opup = StatsOld.opup = 0;
-
- old = StatsOld.ln;
- cur = StatsCur.ln;
- res = StatsReset.ln;
- for (i = 0; i < StatsCur.ndu; i++, cur++, old++, res++) {
- /* Assume all lines configured, if we found out it's not, then
- * we will save the correct value in StatsOld. */
- cur->ln = LINE_NOTCONF;
- res->ln = old->ln = i;
- res->dest.s_addr = cur->dest.s_addr = old->dest.s_addr = 0L;
- res->cchr = cur->cchr = old->cchr = 0;
- res->cchs = cur->cchs = old->cchs = 0;
- res->cpsip = cur->cpsip = old->cpsip = 0;
- res->cprip = cur->cprip = old->cprip = 0;
- res->ierror = cur->ierror = old->ierror = 0;
- res->oerror = cur->oerror = old->oerror = 0;
- res->flags = cur->flags = old->flags = 0;
- res->ctpbusy = cur->ctpbusy = old->ctpbusy = 0;
- res->ctpidle = cur->ctpidle = old->ctpidle = 0;
- res->resc = cur->resc = old->resc = 0;
- res->sesc = cur->sesc = old->sesc = 0;
-
- /* Set up the averages table. */
- for (j = 0; j < MAXINTERVALS; j++) {
- aptr = &Averages[i][j];
- aptr->chs = 0;
- aptr->pkts = 0;
- aptr->chr = 0;
- aptr->pktr = 0;
- aptr->rescs = 0;
- aptr->sescs = 0;
- aptr->sec = 0;
- }
-
- (void)strcpy(OtherHost[i], "UNINITIALIZED");
- }
-
- /* Get storage for loc records, assign y locations. */
- i = 1;
- AllocGStor(R_CIPUP, i++);
- AllocGStor(R_CIPLN, i++);
- AllocGStor(R_COPUP, i++);
- AllocGStor(R_COPLN, i++);
- AllocGStor(R_gIERROR, i++);
- AllocGStor(R_gOERROR, i++);
- AllocGStor(R_gCHS, i);
- AllocGStor(R_gCHR, i++);
-
- /* Local storage. Note that some share the same location. */
- i = 1;
- AllocLStor(R_CPSIP, i++);
- AllocLStor(R_CPRIP, i++);
- AllocLStor(R_CTPBUSY, i);
- AllocLStor(R_CTPIDLE, NOTSET);
- AllocLStor(R_aPCTESC, i++);
- AllocLStor(R_ESCS, NOTSET);
- AllocLStor(R_ESCR, NOTSET);
- AllocLStor(R_CCHS, i);
- AllocLStor(R_CCHR, i++);
- AllocLStor(R_aCHPKTS, i);
- AllocLStor(R_aCHPKTR, i++);
- AllocLStor(R_aCHS, i);
- AllocLStor(R_aCHR, i++);
- AllocLStor(R_aPKTS, i);
- AllocLStor(R_aPKTR, i++);
- AllocLStor(R_IERROR, i++);
- AllocLStor(R_OERROR, i++);
- AllocLStor(R_STATE, i++);
- }
-
-
-
- /*
- ** Blank out a row of stars.
- */
- removeplot(oldx, newx, yloc)
- int oldx;
- int newx;
- int yloc;
- {
- for (; oldx > newx; oldx--)
- mvwaddch(Wgraph, yloc, oldx - 1, ' ');
- }
-
-
- /*
- ** Add a row of stars.
- */
- addplot(oldx, newx, yloc)
- int oldx;
- int newx;
- int yloc;
- {
- while (++oldx <= newx)
- mvwaddch(Wgraph, yloc, oldx - 1, '*');
- }
-
-
- /*
- * globalstats -- set-up global statistics window for monitoring
- */
- globalstats()
- {
- int line;
-
- /* window already global, don't change it */
- if (CurrWind == W_GLOBAL)
- return;
-
- CurrWind = W_GLOBAL;
- Wclear(Whelp);
- Wclear(Wtypes);
- Wclear(Wgraph);
- Wrefresh(Whelp);
-
- /* print title and scale */
- line = 0;
- Wmove(Wtypes, line, 0);
- Wprintw(Wtypes, "GLOBAL STATISTICS:");
- Wmove(Wgraph, line++, 0);
- Wprintw(Wgraph, "1 10 20 30 40");
-
- InitDisplay(R_CIPUP, 0);
- InitDisplay(R_CIPLN, 0);
- InitDisplay(R_COPUP, 0);
- InitDisplay(R_COPLN, 0);
- InitDisplay(R_gCHS, 0);
- InitDisplay(R_gCHR, 0);
- InitDisplay(R_gIERROR,0);
- InitDisplay(R_gOERROR,0);
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
- UpdateGraphs();
- }
-
-
- /*
- ** Set-up line statistics window for monitoring.
- */
- linestats(ln)
- int ln;
- {
- int line;
-
- if (CurrWind == W_LINE && CurrLine == ln)
- return;
-
- if (StatsOld.ln[ln].ln == LINE_NOTCONF) {
- LineNotConf(ln);
- return;
- }
-
- CurrWind = W_LINE;
- CurrLine = ln;
- Wclear(Whelp);
- Wclear(Wtypes);
- Wclear(Wgraph);
- Wrefresh(Whelp);
-
- line = 0;
- Wmove(Wtypes, line, 0);
- Wprintw(Wtypes, "LINE TO %.20s:", OtherHost[ln]);
- Wmove(Wgraph, line++, 0);
- Wprintw(Wgraph, "1 10 20 30 40");
-
- InitDisplay(R_CPSIP, ln);
- InitDisplay(R_CPRIP, ln);
- InitDisplay(R_CTPBUSY, ln);
- InitDisplay(R_aPCTESC, ln);
- InitDisplay(R_CCHS, ln);
- InitDisplay(R_CCHR, ln);
- InitDisplay(R_aCHPKTS, ln);
- InitDisplay(R_aCHPKTR, ln);
- InitDisplay(R_aCHS, ln);
- InitDisplay(R_aCHR, ln);
- InitDisplay(R_aPKTS, ln);
- InitDisplay(R_aPKTR, ln);
- InitDisplay(R_STATE, ln);
- InitDisplay(R_IERROR, ln);
- InitDisplay(R_OERROR, ln);
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
- UpdateGraphs();
- }
-
-
- /*
- ** Set-up total statistics window for monitoring.
- */
- totalstats(ln)
- int ln;
- {
- int line;
-
- if (CurrWind == W_TOTAL && CurrLine == ln)
- return;
-
- if (ln != NOTSET && StatsOld.ln[ln].ln == LINE_NOTCONF) {
- LineNotConf(ln);
- return;
- }
-
- CurrWind = W_TOTAL;
- CurrLine = ln;
- Wclear(Whelp);
- Wclear(Wtypes);
- Wclear(Wgraph);
- Wrefresh(Whelp);
-
- /* Pint title and scale. */
- line = 0;
- Wmove(Wtypes, line, 0);
-
- if (ln == NOTSET)
- Wprintw(Wtypes, "GLOBAL TOTALS:");
- else
- Wprintw(Wtypes, "LINE TOTALS TO %.20s:", OtherHost[ln]);
- Wmove(Wgraph, line++, 0);
- Wprintw(Wgraph, " TOTAL COUNTS");
-
- if (CurrLine == NOTSET) {
- /* Global records. */
- InitDisplay(R_CIPUP, 0);
- InitDisplay(R_CIPLN, 0);
- InitDisplay(R_COPUP, 0);
- InitDisplay(R_COPLN, 0);
- InitDisplay(R_gCHS, 0);
- InitDisplay(R_gCHR, 0);
- InitDisplay(R_gIERROR,0);
- InitDisplay(R_gOERROR,0);
- }
- else {
- /* Line records. */
- InitDisplay(R_CPSIP, ln);
- InitDisplay(R_CPRIP, ln);
- InitDisplay(R_CTPBUSY, ln);
- InitDisplay(R_aPCTESC, ln);
- InitDisplay(R_CCHS, ln);
- InitDisplay(R_CCHR, ln);
- InitDisplay(R_aCHPKTS, ln);
- InitDisplay(R_aCHPKTR, ln);
- InitDisplay(R_IERROR, ln);
- InitDisplay(R_OERROR, ln);
- }
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
- UpdateTotals();
- }
-
-
- /*
- ** If flag is TRUE, reset totals to 0 and start accumulating, else use
- ** real totals as sent from monitored site.
- */
- reset(flag)
- int flag;
- {
- int i;
- LINESTATS *res;
-
- freset = flag;
- if (freset) {
- StatsReset.ipup = 0;
- StatsReset.ipln = 0;
- StatsReset.opup = 0;
- StatsReset.opln = 0;
- for (res = StatsReset.ln, i = 0; i < StatsCur.ndu; i++, res++) {
- res->cchr = 0;
- res->cchs = 0;
- res->cpsip = 0;
- res->cprip = 0;
- res->ierror = 0;
- res->oerror = 0;
- res->ctpbusy = 0;
- res->ctpidle = 0;
- res->resc = 0;
- res->sesc = 0;
- }
- }
- if (CurrWind == W_TOTAL)
- UpdateTotals();
- }
-
-
- /*
- ** Help function, displays the windows that are available.
- */
-
- helpwindow()
- {
- int line;
-
- CurrWind = W_HELP;
- Wclear(Whelp);
- Wclear(Wtypes);
- Wclear(Wgraph);
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
-
- /* Print title. */
- line = 0;
- Wmove(Whelp, line++, 0);
- Wprintw(Whelp, "COMMANDS:\n");
- Wprintw(Whelp, " l#\t\tSerial line statistics for line #\n");
- Wprintw(Whelp, " t# | tg\tTotal statistics for line # or g for global\n");
- Wprintw(Whelp, " h or ?\tHelp\n");
- Wprintw(Whelp, " ^L\t\tRedraw\n");
- Wprintw(Whelp, " ry\t\tUse the reset totals\n");
- Wprintw(Whelp, " rn\t\tUse totals since last reboot\n");
- Wprintw(Whelp, " q\t\tQuit\n");
- Wrefresh(Whelp);
- }
-
-
- /*
- ** Clear screen and print message if the line to be monitored is not
- ** configured.
- */
- LineNotConf(ln)
- int ln;
- {
- Wclear(Whelp);
- Wclear(Wgraph);
- Wclear(Wtypes);
- Wrefresh(Whelp);
- Wmove(Wtypes, 0, 0);
- Wprintw(Wtypes, "SERIAL LINE %d NOT CONFIGURED", ln);
- CurrWind = W_HELP;
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
- }
-
-
- /*
- ** Initialize one type of log record's data structure for the line to be
- ** displayed and display the title.
- */
- InitDisplay(t, l)
- int t;
- int l;
- {
- DIALLOGREC *drp;
-
- drp = &Records[t][l];
- drp->Old = 0;
-
- switch (t) {
- default:
- Wmove(Wtypes, drp->yloc, 0);
- Wprintw(Wtypes, "%s", TypeDescriptions[t]);
- mvwaddch(Wtypes, drp->yloc, 29, ':');
- break;
- case R_CTPBUSY:
- case R_CCHS:
- case R_gCHS:
- case R_aCHS:
- case R_aPKTS:
- case R_aCHPKTS:
- Wmove(Wtypes, drp->yloc, 0);
- Wprintw(Wtypes, "%s", TypeDescriptions[t]);
- break;
- case R_aPCTESC:
- case R_CCHR:
- case R_gCHR:
- case R_aCHR:
- case R_aPKTR:
- case R_aCHPKTR:
- Wmove(Wgraph, drp->yloc, 0);
- Wprintw(Wgraph, "%s", TypeDescriptions[t]);
- break;
- }
- }
-
-
- /*
- ** Update the system status lines.
- */
- UpdateStatus()
- {
- float pct[CPUSTATES];
- int i;
- int w;
-
- /* sum up the time spent in each cpu state and initialize pct */
- for (w = 0, i = 0; i < CPUSTATES; i++) {
- pct[i] = 0.0;
- w += StatsCur.cputime[i];
- }
-
- /* compute the percent of time spent in each cpu state */
- if (w)
- for (i = 0; i < CPUSTATES; i++)
- pct[i] = ((float)StatsCur.cputime[i] / (float)w) * 100.0;
-
- Wmove(Wtitle, 2, 26);
- Wprintw(Wtitle, "%6.2f", pct[0]);
- Wmove(Wtitle, 2, 42);
- Wprintw(Wtitle, "%6.2f", pct[2]);
- Wmove(Wtitle, 2, 56);
- Wprintw(Wtitle, "%6.2f", pct[1]);
- Wmove(Wtitle, 2, 70);
- Wprintw(Wtitle, "%6.2f", pct[3]);
- Wmove(Wtitle, 3, 37);
- Wprintw(Wtitle, "%5.2f", ((float)StatsCur.avenrun[0]) / 100.);
- Wmove(Wtitle, 3, 44);
- Wprintw(Wtitle, "%5.2f", ((float)StatsCur.avenrun[1]) / 100.);
- Wmove(Wtitle, 3, 51);
- Wprintw(Wtitle, "%5.2f", ((float)StatsCur.avenrun[2]) / 100.);
- }
-
-
- /*
- ** Update the plots in the active window. Does not update the Old of
- ** any log record not being displayed or that prints a floating point
- ** number.
- */
- UpdateGraphs()
- {
- DIALLOGREC *drp;
-
- if (CurrWind == W_GLOBAL) {
- /* Update all global plots */
- UpdatePlot(Records[R_CIPUP]);
- UpdatePlot(Records[R_CIPLN]);
- UpdatePlot(Records[R_COPUP]);
- UpdatePlot(Records[R_COPLN]);
- drp = Records[R_gCHS];
- PrintNum(Wtypes, (unsigned long)drp->Count, drp->yloc, 17);
- drp->Old = drp->Count;
- drp = Records[R_gCHR];
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 21);
- drp->Old = drp->Count;
- drp = Records[R_gIERROR];
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 0);
- drp->Old = drp->Count;
- drp = Records[R_gOERROR];
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 0);
- drp->Old = drp->Count;
- }
- else if (CurrWind == W_LINE) {
- /* Update the displayed line's stats */
- Wmove(Wtypes, 0, 8);
- Wclrtoeol(Wtypes);
- Wmove(Wtypes, 0, 8);
- Wprintw(Wtypes, "%-.20s", OtherHost[CurrLine]);
- mvwaddch(Wtypes, 0, 29, ':');
- UpdatePlot(&Records[R_CPSIP][CurrLine]);
- UpdatePlot(&Records[R_CPRIP][CurrLine]);
- drp = &Records[R_CTPBUSY][CurrLine];
- PrintPct(Wtypes, drp->fCount, drp->yloc, 19);
- drp = &Records[R_CCHS][CurrLine];
- PrintNum(Wtypes, (unsigned long)drp->Count, drp->yloc, 17);
- drp->Old = drp->Count;
- drp = &Records[R_aCHPKTS][CurrLine];
- PrintNumf(Wtypes, drp->fCount, drp->yloc, 19);
- drp = &Records[R_aCHS][CurrLine];
- PrintNumf(Wtypes, drp->fCount, drp->yloc, 19);
- drp = &Records[R_aPKTS][CurrLine];
- PrintNumf(Wtypes, drp->fCount, drp->yloc, 19);
- drp = &Records[R_aPCTESC][CurrLine];
- PrintPct(Wgraph, drp->fCount, drp->yloc, 28);
- drp = &Records[R_CCHR][CurrLine];
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 26);
- drp->Old = drp->Count;
- drp = &Records[R_aCHPKTR][CurrLine];
- PrintNumf(Wgraph, drp->fCount, drp->yloc, 28);
- drp = &Records[R_aCHR][CurrLine];
- PrintNumf(Wgraph, drp->fCount, drp->yloc, 28);
- drp = &Records[R_aPKTR][CurrLine];
- PrintNumf(Wgraph, drp->fCount, drp->yloc, 28);
- drp = &Records[R_STATE][CurrLine];
- PrintState(Wgraph, drp->Count, drp->yloc, 5);
- drp = &Records[R_IERROR][CurrLine];
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 0);
- drp = &Records[R_OERROR][CurrLine];
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 0);
- }
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
- }
-
- /*
- ** Update the total counts being displayed
- */
- UpdateTotals()
- {
- int i;
- int yloc;
- LINESTATS *lsp;
- DIALSTATS *sp;
- float ttysum;
- unsigned long totchr;
- unsigned long totchs;
- unsigned long totierror;
- unsigned long totoerror;
-
- sp = freset ? &StatsReset : &StatsOld;
-
- if (CurrLine == NOTSET) {
- /* Global totals */
- PrintNum(Wgraph, sp->ipup, Records[R_CIPUP]->yloc, 0);
- PrintNum(Wgraph, sp->ipln, Records[R_CIPLN]->yloc, 0);
- PrintNum(Wgraph, sp->opup, Records[R_COPUP]->yloc, 0);
- PrintNum(Wgraph, sp->opln, Records[R_COPLN]->yloc, 0);
-
- /* total chars received and sent and total silo overflows */
- totchs = 0;
- totchr = 0;
- totierror = 0;
- totoerror = 0;
- for (i = 0; i < StatsCur.ndu; i++) {
- totchs += sp->ln[i].cchs;
- totchr += sp->ln[i].cchr;
- totierror += sp->ln[i].ierror;
- totoerror += sp->ln[i].oerror;
- }
- PrintNum(Wtypes, totchs, Records[R_gCHS]->yloc, 17);
- PrintNum(Wgraph, totchr, Records[R_gCHR]->yloc, 21);
- PrintNum(Wgraph, totierror, Records[R_gIERROR]->yloc, 17);
- PrintNum(Wgraph, totoerror, Records[R_gOERROR]->yloc, 17);
- }
- else {
- /* Displayed line totals */
- Wmove(Wtypes, 0, 15);
- Wclrtoeol(Wtypes);
- Wmove(Wtypes, 0, 15);
- Wprintw(Wtypes, "%-.14s", OtherHost[CurrLine]);
- mvwaddch(Wtypes, 0, 29, ':');
- lsp = &sp->ln[CurrLine];
- PrintNum(Wgraph, lsp->cpsip, Records[R_CPSIP][CurrLine].yloc, 0);
- PrintNum(Wgraph, lsp->cprip, Records[R_CPRIP][CurrLine].yloc, 0);
- PrintNum(Wgraph, lsp->ierror, Records[R_IERROR][CurrLine].yloc, 0);
- PrintNum(Wgraph, lsp->oerror, Records[R_OERROR][CurrLine].yloc, 0);
- if (ttysum = (float)(lsp->ctpbusy + lsp->ctpidle))
- PrintPct(Wtypes,
- ((float)lsp->ctpbusy / (float)ttysum) * 100.0,
- Records[R_CTPBUSY][CurrLine].yloc, 19);
- else
- PrintPct(Wtypes, 0.0, Records[R_CTPBUSY][CurrLine].yloc, 19);
-
- yloc = Records[R_aPCTESC][CurrLine].yloc;
- Wmove(Wgraph, yloc, 0);
- Wclrtoeol(Wgraph);
- Wmove(Wgraph, yloc, 0);
- if (lsp->cchs)
- Wprintw(Wgraph, "%10.5f%%s %10.5f%%r",
- ((float)lsp->sesc / (float)lsp->cchs) * 100.0,
- ((float)lsp->resc / (float)lsp->cchr) * 100.0);
- else
- Wprintw(Wgraph, "%10.5f%%", (float)lsp->cchs);
-
- PrintNum(Wtypes, lsp->cchs, Records[R_CCHS][CurrLine].yloc, 17);
- PrintNum(Wgraph, lsp->cchr, Records[R_CCHR][CurrLine].yloc, 26);
- }
- Wrefresh(Wtypes);
- Wrefresh(Wgraph);
- }
-
-
- /*
- ** Print the number in the specified window at the specified location.
- */
- PrintNum(wn, num, yloc, xloc)
- WINDOW *wn;
- unsigned long num;
- int yloc;
- int xloc;
- {
- Wmove(wn, yloc, xloc);
- Wclrtoeol(wn);
- Wmove(wn, yloc, xloc);
- Wprintw(wn, "%10d", num);
- }
-
-
- /*
- ** Print the float in the specified window at the specified location.
- */
- PrintNumf(wn, num, yloc, xloc)
- WINDOW *wn;
- float num;
- int yloc;
- int xloc;
- {
- Wmove(wn, yloc, xloc);
- Wclrtoeol(wn);
- Wmove(wn, yloc, xloc);
- Wprintw(wn, "%8.2f ", num);
- }
-
-
- /*
- ** Print the percent of time a tty is busy.
- */
- PrintPct(wn, num, yloc, xloc)
- WINDOW *wn;
- float num;
- int yloc;
- int xloc;
- {
- Wmove(wn, yloc, xloc);
- Wclrtoeol(wn);
- Wmove(wn, yloc, xloc);
- Wprintw(wn, "%8.2f %%", num);
- }
-
- PrintState(wn, state, yloc, xloc)
- WINDOW *wn;
- int state;
- int yloc;
- int xloc;
- {
- int i;
- int j;
-
- Wmove(wn, yloc, xloc);
- Wclrtoeol(wn);
- Wmove(wn,yloc,xloc);
- for (i = 0, j = 1; i < 32 ; i++, j <<= 1)
- if (state & j)
- Wprintw(wn, "%s ", DUStateMessages[i]);
- }
-
-
- /*
- ** Update the plot for the log record passed in.
- */
- UpdatePlot(drp)
- DIALLOGREC *drp;
- {
- if (drp->Count == drp->Old)
- return;
-
- if (drp->Count < 0) {
- Wmove(Wgraph, drp->yloc, 0);
- Wclrtoeol(Wgraph);
- drp->Count = 0;
- drp->Old = 0;
- }
- else if (drp->Count > MAXPLOTS && drp->Old > MAXPLOTS) {
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 0);
- drp->Old = drp->Count;
- }
- else if (drp->Count > MAXPLOTS && drp->Old <= MAXPLOTS) {
- PrintNum(Wgraph, (unsigned long)drp->Count, drp->yloc, 0);
- drp->Old = drp->Count;
- }
- else if (drp->Count <= MAXPLOTS && drp->Old > MAXPLOTS) {
- Wmove(Wgraph, drp->yloc, 0);
- Wclrtoeol(Wgraph);
- addplot(0, drp->Count, drp->yloc);
- drp->Old = drp->Count;
- }
- else if (drp->Count > drp->Old) {
- /* add to old graph */
- addplot(drp->Old, drp->Count, drp->yloc);
- drp->Old = drp->Count;
- }
- else if (drp->Count < drp->Old) {
- /* remove from old graph */
- removeplot(drp->Old, drp->Count, drp->yloc);
- drp->Old = drp->Count;
- }
- }
-
-
- /*
- ** Look up a hostname, fill in the socket. Return -1 on error.
- */
- static int
- hosttosocket(p, psin)
- char *p;
- struct sockaddr_in *psin;
- {
- struct hostent *hp;
- unsigned long w;
-
- bzero((caddr_t)psin, sizeof *psin);
- if (isdigit(*p)) {
- if ((w = inet_addr(p)) == (unsigned long)-1)
- return -1;
- psin->sin_addr.s_addr = w;
- psin->sin_family = AF_INET;
- return 0;
- }
-
- if ((hp = gethostbyname(p)) == NULL) {
- (void)fprintf(stderr, "Can't get address of \"%s\": ", p);
- #ifndef HOST_NOT_FOUND
- (void)fprintf(stderr, "Host not found\n");
- #else
- switch (h_errno) {
- default:
- (void)fprintf(stderr, "Unknown error: %d\n", h_errno);
- break;
- case HOST_NOT_FOUND:
- (void)fprintf(stderr, "Host not found\n");
- break;
- case TRY_AGAIN:
- (void)fprintf(stderr, "Try again later\n");
- break;
- case NO_RECOVERY:
- (void)fprintf(stderr, "No recovery possible\n");
- break;
- case NO_ADDRESS:
- (void)fprintf(stderr, "No IP address\n");
- break;
- }
- #endif /* NOT_NOT_FOUND */
- return -1;
- }
-
- psin->sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, (char *)&psin->sin_addr, hp->h_length);
- return 0;
- }
-
- /*
- ** Print usage message and exit.
- */
- static void
- usage(p)
- char *p;
- {
- (void)fprintf(stderr, "Usage error: %s\n", p);
- (void)fprintf(stderr, "Usage: %s [-g] [-l line] [-t g|line] [site]\n",
- progname);
- exit(1);
- }
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *p;
- struct servent *sp;
- struct sockaddr_in sin;
- int i;
- int fildes[2];
- char *timep;
- char buff[90];
- fd_set readers;
- int win;
- int arg;
- int localpipe;
-
- /* Set defaults. */
- win = W_GLOBAL;
- arg = NOTSET;
- localpipe = 0;
-
- /* Get options. */
- while ((i = getopt(argc, argv, "gl:pt:")) != EOF)
- switch (i) {
- default:
- usage("Bad flag");
- /* NOTREACHED */
- case 'g': /* global stats, no arg */
- win = W_GLOBAL;
- arg = NOTSET;
- break;
- case 'l': /* line stats, next arg must be ln # */
- if (!isdigit(*optarg) || (arg = atoi(optarg)) > MAX_NDU)
- usage("Bad number for -l");
- win = W_LINE;
- break;
- case 'p':
- localpipe = 1;
- break;
- case 't': /* total stats, next arg must be */
- if (*optarg == 'g') {
- win = W_TOTAL;
- arg = NOTSET;
- }
- else if (!isdigit(*optarg) || (arg = atoi(optarg)) >= MAX_NDU)
- usage("Bad number for -t");
- win = W_TOTAL;
- break;
- }
- argc -= optind;
- argv += optind;
-
- if (!localpipe) {
- switch (argc) {
- default:
- usage("Wrong number of arguments");
- /* NOTREACHED */
- case 0:
- (void)gethostname(HostName, sizeof HostName);
- break;
- case 1:
- (void)strcpy(HostName, *argv);
- break;
- }
-
- if ((sp = getservbyname(DIALMON_SERVICE, "tcp")) == NULL) {
- (void)fprintf(stderr,
- "Warning: %s/tcp unknown service; using port %d\n",
- DIALMON_SERVICE, DIALMON_DEFAULT_PORT);
- (void)sleep(2);
- }
- }
- else {
- if (argc)
- usage("Wrong number of arguments");
- (void)gethostname(HostName, sizeof HostName);
- }
-
- /* Initialize screen */
- (void)initscr();
- (void)noecho();
- (void)nonl();
- (void)crmode();
- cursed++;
- if (LINES < 24 || COLS < 80)
- fatal("Screen too small");
- (void)signal(SIGINT, ext);
- Wtitle = newwin(4, 0, 0, 0); /* 4 lines at top */
- Wgraph = newwin(maxyloc, COLS - 30, 4, 30); /* 14 lines at center left*/
- Wtypes = newwin(maxyloc, 30, 4, 0); /* 14 lines at center right */
- Wprompt = newwin(1, 0, LINES - 1, 0);
- Whelp = newwin(maxyloc, 0, 5, 0);
- Wmove(Wtitle, 0, 14);
- Wprintw(Wtitle, "%s Monitor: ", dip_release());
- Wmove(Wtitle, 1, 11);
- Wprintw(Wtitle, "Time of the last update: ");
- Wmove(Wtitle, 2, 5);
- Wprintw(Wtitle, "Cpu utilization USER: %%, SYSTEM: %%, ");
- Wprintw(Wtitle, "NICE: %%, IDLE: %%");
- Wmove(Wtitle, 3, 23);
- Wprintw(Wtitle, "Load average: , , ");
- Wrefresh(Wtitle);
-
- /* This must be AFTER curses has been called, sigh. */
- initdata();
-
- switch (win) {
- default:
- helpwindow();
- break;
- case W_GLOBAL:
- globalstats();
- break;
- case W_LINE:
- linestats(arg);
- break;
- case W_TOTAL:
- totalstats(arg);
- break;
- }
-
- /* Connect to server */
- if (localpipe) {
- if (pipe(fildes) < 0)
- fatal("Can't make pipe");
- switch (fork()) {
- case -1:
- fatal("Can't fork");
- /* NOTREACHED */
- case 0:
- (void)close(fildes[0]);
- (void)close(0);
- (void)dup(fildes[1]);
- (void)close(fildes[1]);
- (void)execl(DIALMOND_PATH, "dialmond", (char *)NULL);
- fatal(DIALMOND_PATH);
- /* NOTREACHED */
- }
- (void)close(fildes[1]);
- fd = fildes[0];
- }
- else {
- if (hosttosocket(HostName, &sin) < 0) {
- (void)sprintf(buff, "Unknown host %s", HostName);
- fatal(buff);
- }
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- fatal("Socket failed");
- sin.sin_port = sp ? sp->s_port : DIALMON_DEFAULT_PORT;
- if (connect(fd, (caddr_t)&sin, sizeof sin) < 0) {
- (void)sprintf(buff, "Can't connect to port %d at %s",
- ntohs(sin.sin_port), HostName);
- fatal(buff);
- }
- }
- Wmove(Wtitle, 0, 36);
- Wprintw(Wtitle, "connected to %s", HostName);
-
- /* Print the current time. */
- timep = ctime(&StatsCur.when);
- if (p = strchr(timep, '\n'))
- *p = '\0';
- Wmove(Wtitle, 1, 36);
- Wprintw(Wtitle, "%s", timep);
- UpdateStatus();
- Wrefresh(Wtitle);
-
- /* Set up the prompt. */
- Wclear(Wprompt);
- Wprintw(Wprompt, " ? ");
- Wrefresh(Wprompt);
-
- /* read and plot responses */
- for ( ; ; ) {
- FD_ZERO(&readers);
- FD_SET(fd, &readers);
- FD_SET(0, &readers);
- if (select(fd + 1, &readers,
- (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) > 0) {
- if (FD_ISSET(fd, &readers))
- readsocket(fd);
- if (FD_ISSET(0, &readers))
- readterminal();
- }
- }
- }
-