1
0
Files
irix-657m-src/eoe/cmd/ppp/pppstat.c
2022-09-29 17:59:04 +03:00

1062 lines
22 KiB
C

/* dump PPP stuff
*/
#ident "$Revision: 1.21 $"
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdio.h>
#include <bstring.h>
#include <curses.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#undef TRUE /* uucp.h redefines TRUE & FALSE */
#undef FALSE
#include "pppinfo.h"
extern char pppinfo_err[];
static WINDOW *win;
static int y, x;
#define TOP 2
#define COL_WIDTH 26
#define COL1 0
#define COL2 26
#define COL3 52
#define BOS (LINES-1) /* bottom of screen */
#define LABEL_WIDTH 14
#define MAX_FIELD_WIDTH 11
#define NOMINAL_FIELD_WIDTH 3
#define NUM_VALUES 8 /* maximum values/field */
static struct termio tb;
#define INTRCHAR tb.c_cc[VINTR]
#define SUSPCHAR tb.c_cc[VSUSP]
static time_t mode_date;
char *pgmname;
static int interval = 1;
static int unit;
static int unit_delta;
static int fail_cnt = 0;
#define FATAL_FAIL 45
static int first = 2;
static int needfoot; /* need to repaint footing */
static char scrn_no = '5';
static enum {
D_MODE=0,
Z_MODE=1,
R_MODE=2
} mode;
static struct ppp_status base, cur;
#define C_BUNDLE cur.ps_pi.pi_bundle
#define C_KDEVS cur.ps_pi.pi_devs
#define C_DDEVS cur.ps_devs
#define B_BUNDLE base.ps_pi.pi_bundle
#define B_KDEVS base.ps_pi.pi_devs
#define B_DDEVS base.ps_devs
static int indeces[MAX_PPP_LINKS], old_indeces[MAX_PPP_LINKS];
static char lochost_name[4*3+3+1];
static char remhost_name[4*3+3+1];
static void quit(int);
static void sick(char *, ...);
#if 0
static void fail(char *, ...);
#endif
static void sig_winch(int);
static void usage(void);
static char* hms(int);
static void pval(int, char *, char *);
static char* vtos(char *, ...);
static void set_base(void);
static void clear_base(void);
static void dis_link(char *, int);
static void dis_io(char *);
static void dis_acct(char *);
static void dis_counts(char *);
static int input_wait(void);
static void paint(void);
static void banner(char *, time_t);
static void prnt(char *, ...);
void
main(int argc,
char **argv)
{
int i, c;
char *p;
pgmname = argv[0];
while ((i = getopt(argc, argv, "nu:i:m:")) != EOF)
switch (i) {
case 'u':
i = (int)strtoul(optarg,&p,0);
if (*p != '\0' || i < 0 || i > MAX_PPP_DEVS)
usage();
if (0 > pppinfo_next_unit(i,0,&cur)) {
fprintf(stderr, "%s: no such PPP unit %s\n",
pgmname, optarg);
exit(1);
}
break;
case 'i':
interval = (int)strtoul(optarg,&p,0);
if (*p != '\0' || interval == 0)
usage();
break;
case 'm':
if (strlen(optarg) != 1)
usage();
switch (*optarg) {
case 'd': mode = D_MODE; break;
case 'r': mode = R_MODE; break;
case 'z': mode = Z_MODE; break;
default: usage(); break;
}
break;
default:
usage();
break;
}
if (argc != optind)
usage();
(void) ioctl(0, TCGETA, &tb);
win = initscr();
signal(SIGINT, quit);
signal(SIGTERM, quit);
signal(SIGHUP, quit);
(void)signal(SIGWINCH, sig_winch);
cbreak();
noecho();
keypad(stdscr, TRUE);
leaveok(stdscr, FALSE);
nonl();
intrflush(stdscr,FALSE);
move(0, 0);
for (;;) {
if (first != 0) {
clear();
needfoot = 1;
fail_cnt = 0;
}
if (unit < 0
&& 0 > (unit = pppinfo_next_unit(0, unit_delta, &cur))) {
sick("no active PPP connnections");
} else if (0 > pppinfo_get(unit, &cur)) {
sick(pppinfo_err);
} else {
fail_cnt = 0;
paint();
}
if (!input_wait())
continue;
c = getch();
switch (c) {
case 'q':
case 'Q':
quit(0);
break;
case 'd':
case 'D':
first = 2;
mode = D_MODE;
break;
case 'z':
case 'Z':
first = 2;
mode = Z_MODE;
break;
case 'r':
case 'R':
first = 2;
mode = R_MODE;
break;
case '\f':
if (!first)
first = 1;
break;
case '+':
case '=': /* in case of typos */
unit = pppinfo_next_unit(unit, unit_delta = 1, &cur);
first = 2;
break;
case '-':
case '_': /* in case of typos */
unit = pppinfo_next_unit(unit, unit_delta = -1, &cur);
first = 2;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
scrn_no = c;
if (!first)
first = 1;
break;
default:
if (c == INTRCHAR)
quit(0);
if (c == SUSPCHAR) {
reset_shell_mode();
kill(getpid(), SIGTSTP);
reset_prog_mode();
}
/* repaint screen on unrecognized commands */
if (!first)
first = 1;
break;
}
}
}
/* wait for a second or until something is typed
*/
static int
input_wait(void)
{
int i;
struct timeval wait;
fd_set rmask;
/* Try to delay for exactly the right interval,
* adjusted for time spent displaying things.
* Display at the middle of the correct second.
*/
(void)gettimeofday(&wait, 0);
wait.tv_sec = interval;
wait.tv_usec += 250000;
if (wait.tv_usec > 1000000)
wait.tv_usec -= 1000000;
if (wait.tv_usec != 0) {
wait.tv_usec = 1000000 - wait.tv_usec;
if (wait.tv_usec >= 1000000/5)
wait.tv_sec--;
}
FD_ZERO(&rmask);
FD_SET(0, &rmask);
i = select(1, &rmask, 0, 0, &wait);
if (i < 0) {
if (errno != EAGAIN && errno != EINTR)
sick("select: %s", strerror(errno));
return 0;
}
return i;
}
/* paint the screen
*/
static void
paint(void)
{
char cmds[80];
int i, j, same_dev, active_dev;
/* If the interface is new, reset everything */
if (cur.ps_pid != base.ps_pid)
first = 2;
/* recompute map of link # to STREAMS mux device */
for (j = 0; j < MAX_PPP_LINKS; j++)
indeces[j] = -1;
same_dev = 0;
active_dev = 0;
for (i = 0; i < MAX_PPP_LINKS; i++) {
if (C_KDEVS[i].dev_link.pl_max_frag <= 0 )
continue;
j = C_KDEVS[i].dev_link.pl_link_num;
if (j >= 0 && j < MAX_PPP_LINKS)
indeces[j] = i;
active_dev++;
/* notice in passing links that have come or gone */
if ((B_KDEVS[i].dev_link.pl_index
!= C_KDEVS[i].dev_link.pl_index)
|| old_indeces[j] != i) {
bcopy(&C_KDEVS[i], &B_KDEVS[i], sizeof(B_KDEVS[i]));
bcopy(&C_DDEVS[j], &B_DDEVS[j], sizeof(B_DDEVS[j]));
if (first == 0)
first = 1;
needfoot = 1;
} else {
same_dev++;
}
}
if (active_dev > 0 && same_dev == 0)
bcopy(&cur.ps_pi.pi_vj_tx, &base.ps_pi.pi_vj_tx,
sizeof(base.ps_pi.pi_vj_tx));
/* if the map has changed, recompute the footing */
if (bcmp(&indeces[0], &old_indeces[0], sizeof(old_indeces))) {
bcopy(&indeces[0], &old_indeces[0], sizeof(old_indeces));
if (!first)
first = 1;
needfoot = 1;
}
if (needfoot || first != 0) {
for (i = 0, j = 0; j < MAX_PPP_LINKS; j++) {
if (indeces[j] < 0)
continue;
i += sprintf(&cmds[i], "%s%d", (i ? ",": ""), j+1);
}
strcpy(&cmds[i], i ? ":link" : "");
move(BOS, 0);
clrtoeol();
standout();
printw("%-8.8s %-50.50s %25.25s",
cmds, " 5:I/O 6:acct 7:counts",
"+/-:Interface DZRN:Mode");
standend();
needfoot = 0;
}
if (first > 1) {
strcpy(lochost_name, inet_ntoa(cur.ps_lochost));
strcpy(remhost_name, inet_ntoa(cur.ps_remhost));
switch (mode) {
case D_MODE:
set_base();
mode_date = cur.ps_initial_date;
break;
case Z_MODE:
set_base();
mode_date = time(0);
break;
case R_MODE:
clear_base();
mode_date = cur.ps_initial_date;
break;
}
}
switch (scrn_no) {
case '1':
dis_link("1:link 1", 0);
break;
case '2':
dis_link("2:link 2", 1);
break;
case '3':
dis_link("3:link 3", 2);
break;
case '4':
dis_link("4:link 4", 3);
break;
case '5':
dis_io("5:I/O");
break;
case '6':
dis_acct("6:acct");
break;
case '7':
dis_counts("7:counts");
break;
}
/* paint the screen, leaving the cursor at the top */
move(0, 0);
refresh();
first = 0;
if (mode == D_MODE)
set_base();
}
static void
banner(char *scrn_name,
time_t date)
{
char m;
char init_date_str[sizeof("mm/dd hh:mm:ss to ")+1];
char cur_time_str[sizeof("HH:MM:SS")+1];
switch (mode) {
case D_MODE:
m = 'D';
break;
case Z_MODE:
m = 'Z';
date = mode_date;
break;
case R_MODE:
m = 'R';
date = mode_date;
break;
}
if (date == 0) {
init_date_str[0] = '\0';
} else {
(void)cftime(init_date_str,"%m/%d %T to ",&date);
}
(void)cftime(cur_time_str,"%T",&cur.ps_cur_date);
x = 0;
y = 0;
prnt("%-8s ppp%-2d %15.15s %-18s %*s%c: %s%s",
scrn_name, unit, cur.ps_rem_sysname, remhost_name,
date ? 0 : sizeof(init_date_str)-2, "",
m, init_date_str, cur_time_str);
x = COL1;
y = TOP;
}
#define DELTA(nm) (cur.nm - base.nm)
#define PB_METER_DELTA(nm) DELTA(ps_pi.pi_bundle.pb_meters.nm)
#define PF_METER_DELTA(n,nm) DELTA(ps_pi.pi_devs[n].dev_meters.nm)
#define PL_DELTA(n,nm) DELTA(ps_pi.pi_devs[n].dev_link.nm)
#define PS_DEV_DELTA(nm) (C_DDEVS[link].nm - B_DDEVS[link].nm)
#define SNUM(v) vtos("%3d", v)
#define SSEC(v) (v <= (5*60) ? vtos("%3d sec", v) : hms(v))
#define SBYTE(v) vtos("%3d", v)
#define SRATIO(n,d) ((d)!=0 ? vtos("%3.1f:1", (n)*1.0/(d)) : "")
#define SKBPS(v) ((v)!=0 ? vtos("%3.1f kbps", (v)/1000.0) : "")
static void
pr_vj_tx(int sw)
{
if (cur.ps_pi.pi_vj_tx.tx_states == 0)
sw = -1;
pval(sw, "VJ TX total", SNUM(DELTA(ps_pi.pi_vj_tx.cnt_packets)));
pval(sw, " compressed", SNUM(DELTA(ps_pi.pi_vj_tx.cnt_compressed)));
pval(sw, " searches", SNUM(DELTA(ps_pi.pi_vj_tx.cnt_searches)));
pval(sw, " misses", SNUM(DELTA(ps_pi.pi_vj_tx.cnt_misses)));
}
static void
pr_vj_rx(int sw,
int link)
{
#define V(n) ps_pi.pi_devs[n].dev_vj_rx
int i = indeces[link];
if (i < 0 || cur.V(i).rx_states == 0)
sw = -1;
pval(sw," RX compressed",SNUM(DELTA(V(i).cnt_compressed)));
pval(sw," incomp", SNUM(DELTA(V(i).cnt_uncompressed)));
pval(sw," tossed", SNUM(DELTA(V(i).cnt_tossed)));
#undef V
}
static void
pr_bsd_db(int sw,
int tx, /* 1=TX, 0=RX */
int link,
int indx)
{
#define BSD_DELTA(nm) (cur_db->nm - base_db->nm)
struct bsd_db *cur_db, *base_db;
int max_bits, comp, raw;
if (tx) {
cur_db = &C_KDEVS[indx].dev_tx_db.bsd;
base_db = &B_KDEVS[indx].dev_tx_db.bsd;
} else {
cur_db = &C_KDEVS[indx].dev_rx_db.bsd;
base_db = &B_KDEVS[indx].dev_rx_db.bsd;
}
/* figure out the size of the code word */
for (max_bits = MIN_BSD_BITS;
(1<<max_bits) <= cur_db->maxmaxcode && max_bits < MAX_BSD_BITS;
max_bits++)
continue;
pval(sw, tx ? "TX BSD bits" : "RX BSD bits", SNUM(max_bits));
pval(sw, " cur bits", SNUM(cur_db->n_bits));
pval(sw, " max code", SNUM(cur_db->max_ent));
comp = BSD_DELTA(bytes_out)+BSD_DELTA(prev_bytes_out);
raw = BSD_DELTA(in_count)+BSD_DELTA(prev_in_count);
pval(sw, " ratio", SRATIO(raw,comp));
pval(sw, " ckpoint", SNUM(cur_db->checkpoint));
pval(sw, " seq #", SNUM(cur_db->seqno));
pval(sw, " cleared", SNUM(cur_db->clear_count));
pval(sw, " incomp pkts", SNUM(BSD_DELTA(incomp_count)));
if (tx) {
pval(sw," reset peer", SNUM(PS_DEV_DELTA(ccp_rreq_rcvd)));
} else {
pval(sw," reset peer", SNUM(PS_DEV_DELTA(ccp_rack_rcvd)));
pval(sw," buf over", SNUM(BSD_DELTA(overshoot)));
pval(sw," undershoot",SNUM(BSD_DELTA(undershoot)));
}
#undef BSD_DELTA
}
static void
pr_pred_db(int sw,
int tx, /* 1=TX, 0=RX */
int link,
int indx)
{
#define PRED_DELTA(nm) (cur_db->nm - base_db->nm)
struct pred_db_info *cur_db, *base_db;
int comp, raw;
if (tx) {
cur_db = &C_KDEVS[indx].dev_tx_db.pred,
base_db = &B_KDEVS[indx].dev_tx_db.pred;
} else {
cur_db = &C_KDEVS[indx].dev_rx_db.pred,
base_db = &B_KDEVS[indx].dev_rx_db.pred;
}
comp = PRED_DELTA(comp);
raw = PRED_DELTA(uncomp);
pval(sw, tx ? "TX Pred ratio" : "RX Pred ratio", SRATIO(raw,comp));
pval(sw, " incomp pkts",SNUM(PRED_DELTA(incomp)));
if (tx) {
pval(sw," reset peer", SNUM(PS_DEV_DELTA(ccp_rreq_rcvd)));
} else {
pval(sw," reset peer", SNUM(PS_DEV_DELTA(ccp_rreq_rcvd)));
pval(sw," padding", SNUM(PRED_DELTA(padding)));
}
#undef PRED_DELTA
}
static void
pr_comp(int sw,
int link) /* -1 for bundle */
{
int indx;
int save_x, save_y, ret_y;
if (link < 0) {
link = 0;
if (!(C_BUNDLE.pb_state & PB_ST_MP)
&& cur.ps_maxdevs > 1) {
indx = -1;
} else {
indx = indeces[0];
}
} else {
if ((C_BUNDLE.pb_state & PB_ST_MP)
|| cur.ps_maxdevs == 1)
indx = 0;
else
indx = indeces[link];
}
if (indx < 0) {
indx = 0;
sw = -1;
}
if (sw < 0)
return;
save_x = x;
save_y = y;
if ((C_BUNDLE.pb_state & PB_ST_TX_BSD)
|| (C_KDEVS[indx].dev_link.pl_state & PL_ST_TX_BSD)) {
pr_bsd_db(sw,1,link,indx);
} else if ((C_BUNDLE.pb_state & PB_ST_TX_PRED)
|| (C_KDEVS[indx].dev_link.pl_state&PL_ST_TX_PRED)) {
pr_pred_db(sw,1,link,indx);
}
ret_y = y;
x += COL_WIDTH;
y = save_y;
if ((C_BUNDLE.pb_state & PB_ST_RX_BSD)
|| (C_KDEVS[indx].dev_pf_state & PF_ST_RX_BSD)) {
pr_bsd_db(sw,0,link,indx);
} else if ((C_BUNDLE.pb_state & PB_ST_RX_PRED)
|| (C_KDEVS[indx].dev_pf_state & PF_ST_RX_PRED)) {
pr_pred_db(sw,0,link,indx);
}
if (ret_y < y)
ret_y = y;
x += COL_WIDTH;
y = save_y;
pr_vj_tx(sw);
pr_vj_rx(sw, link);
x = save_x;
y = ret_y;
}
static void
dis_link(char *name, int link)
{
# define ID_PAT "%-72.72s"
# define ID_LEN 72
int indx, sw;
banner(name,0);
indx = indeces[link];
if (indx < 0) {
y++;
prnt(ID_PAT, "");
standout();
prnt("link %d inactive", link+1);
standend();
return;
}
/* the ID string is directly indexed */
prnt("peer: "ID_PAT, &C_DDEVS[link].ident.msg[0]); y++;
prnt(" "ID_PAT, (C_DDEVS[link].ident_len <= ID_LEN ? ""
: (char*)&C_DDEVS[link].ident.msg[ID_LEN]));
y = TOP+2;
pval(1,"link type", ((C_KDEVS[indx].dev_link.pl_state & PL_ST_SYNC)
? "sync" : "async"));
pval(1,"", C_DDEVS[link].callee ? "originated" : "answered");
pval(1,"raw input", SBYTE(PF_METER_DELTA(indx,raw_ibytes)));
pval(1," output", SBYTE(PL_DELTA(indx,pl_raw_obytes)));
pval(1,"link rate", SKBPS(C_DDEVS[link].bps));
pval((C_DDEVS[link].lcp_echo_rtt != 0.0) ? 1 : 0, "RTT",
vtos("%3.0f ms", C_DDEVS[link].lcp_echo_rtt*1000.0));
y += 2;
pr_comp(1,link); /* 3 columns of compression */
y = TOP+2;
x = COL2;
pval(1,"active for", SSEC(C_DDEVS[link].ps_active));
pval(1,"MRU", SNUM(C_DDEVS[link].lcp_neg_mru));
pval(1,"MTU", SNUM(C_DDEVS[link].lcp_neg_mtu));
sw = (C_BUNDLE.pb_state & PB_ST_MP) ? 1 : -1;
pval(sw,"MRRU", SNUM(C_DDEVS[link].lcp_neg_mrru));
pval(sw,"MTRU", SNUM(C_DDEVS[link].lcp_neg_mtru));
y = TOP+2;
x = COL3;
pval(1,"bad FCS", SNUM(PF_METER_DELTA(indx,bad_fcs)));
pval(1,"no buf", SNUM(PF_METER_DELTA(indx,nobuf)));
pval(1,"null frames", SNUM(PF_METER_DELTA(indx,null)));
pval(1,"~~~~~~~tiny", SNUM(PF_METER_DELTA(indx,tiny)));
pval(1,"~~~~aborted", SNUM(PF_METER_DELTA(indx,abort)));
pval(1,"~~~~~~~long", SNUM(PF_METER_DELTA(indx,long_frame)));
pval(1,"~~~~~babble", SNUM(PF_METER_DELTA(indx,babble)));
}
static void
dis_io(char *name)
{
# define IO_PAT "%8s %11s %11s %11s %11s %6s"
u_int n, m;
banner(name,0);
prnt(IO_PAT, "", " raw", " IP", "ratio", "recent", ""); y++;
n = PB_METER_DELTA(raw_ibytes);
m= PB_METER_DELTA(ibytes);
prnt(IO_PAT, " input", SBYTE(n), SBYTE(m), SRATIO(m,n),
SKBPS(cur.ps_cur_ibps),
((cur.ps_beep_st & BEEP_ST_RX_BUSY) ? "hi"
: (cur.ps_beep_st & BEEP_ST_RX_ACT) ? "medium"
: ""));
y++;
n = PB_METER_DELTA(raw_obytes);
m= PB_METER_DELTA(obytes);
prnt(IO_PAT, " output", SBYTE(n), SBYTE(m), SRATIO(m,n),
SKBPS(cur.ps_cur_obps),
((cur.ps_beep_st & BEEP_ST_TX_BUSY) ? "hi"
: (cur.ps_beep_st & BEEP_ST_TX_ACT) ? "medium"
: ""));
y += 2;
/* top of first column */
y = TOP+4;
pval(1,"current devs", SNUM(cur.ps_numdevs));
/* Compression--leave it for the per-link screens if more than
* one compressor. If present here, it uses the bottom of
* all three columns.
*/
y = TOP+10;
pr_comp(1,-1);
/* top of second column */
y = TOP+4;
x = COL2;
/* top of third column */
y = TOP+4;
x = COL3;
pval(1, "avail", SKBPS(cur.ps_avail_bps));
pval(1, "previous", SKBPS(cur.ps_prev_avail_bps));
}
static void
dis_acct(char *name)
{
u_int link, m;
int t1, sw;
banner(name, cur.ps_acct.last_date);
/* The accounting base is reset periodically by the daemon.
* Nothing happens in only second, to take D_MODE as R_MODE.
*/
# define DA(nm) (cur.ps_acct.nm - ((mode == D_MODE \
|| mode_date<=cur.ps_acct.last_date)\
? 0 : base.ps_acct.nm))
pval(1, "calls answered~~", SNUM(DA(answered)));
y++;
pval(1, "links originated", SNUM(DA(calls)));
pval(1, "~~~~~~~~~~dialed", SNUM(DA(attempts)));
pval(1, "~~~~gave up link", SNUM(DA(failures)));
y++;
sw = (cur.ps_acct.calls != 0);
pval(sw,"min call setup", SSEC(cur.ps_acct.min_setup));
pval(sw,"~~~~~~~~~~~avg", SSEC(cur.ps_acct.setup
/ (sw ? cur.ps_acct.calls : 1)));
pval(sw,"~~~~~~~~~~~max", SSEC(cur.ps_acct.max_setup));
y++;
pval(cur.ps_acct.calls, "calling~~~~~~",hms(DA(orig_conn)));
pval(cur.ps_acct.calls, "~~~~~~~~~idle",hms(DA(orig_idle)));
pval(cur.ps_acct.calls, "~~~~~~~active",hms(DA(orig_conn)
- DA(orig_idle)));
y++;
pval(cur.ps_acct.answered, "answering~~~~",hms(DA(ans_conn)));
pval(cur.ps_acct.answered, "~~~~~~~~~idle",hms(DA(ans_idle)));
pval(cur.ps_acct.answered, "~~~~~~~active",hms(DA(ans_conn)
- DA(ans_idle)));
y++;
pval(1, "not connected",
hms(cur.ps_acct.sconn
- ((mode == Z_MODE) ? MAX(cur.ps_acct.last_secs,
base.ps_acct.sconn)
: cur.ps_acct.last_secs)
- DA(orig_conn) - DA(ans_conn)));
/* second column */
y = TOP;
x = COL2;
pval(1,"maxdevs", SNUM(cur.ps_maxdevs));
pval(1,"mindevs", SNUM(cur.ps_mindevs));
pval(1,"outdevs", SNUM(cur.ps_outdevs));
y++;
y++;
# define NEVER (60*60)
pval(cur.ps_numdevs != 0 && cur.ps_atime < NEVER,
"activity timer", SSEC(cur.ps_atime));
pval(cur.ps_idle_time < NEVER && cur.ps_idle_time != 0,
"MP idle timer~", SSEC(cur.ps_idle_time));
pval(cur.ps_numdevs != 0 && cur.ps_busy_time < NEVER,
"MP busy timer~", SSEC(cur.ps_busy_time));
t1 = cur.ps_add_time;
if (cur.ps_numdevs == 0 && cur.ps_atime < NEVER)
t1 = MAX(cur.ps_atime, t1);
pval(t1 != 0,
"no addition~~~", SSEC(cur.ps_add_time));
pval(cur.ps_add_backoff > 5,
"~~~~~backoff~~", SSEC(cur.ps_add_backoff));
/* third column */
y = TOP;
x = COL3;
pval(1,"current devs", SNUM(cur.ps_numdevs));
for (link = 0, m = 0; link < MAX_PPP_LINKS; link++) {
if (indeces[link] >= 0 && C_DDEVS[link].callee)
m++;
}
pval(1," originated", SNUM(cur.ps_numdevs-m));
pval(1," answered", SNUM(m));
pval(1,"active TCP", SNUM(cur.ps_pi.pi_vj_tx.actconn));
y++;
pval(1, "main PID", SNUM(cur.ps_pid));
pval(cur.ps_add_pid > 0," new PID", SNUM(cur.ps_add_pid));
# undef DA
}
static void
dis_counts(char *name)
{
int sw;
banner(name,0);
y++;
pval(1,"pullups", SNUM(PB_METER_DELTA(rput_pullup)));
sw = (C_BUNDLE.pb_state & PB_ST_MP) ? 1 : -1;
pval(sw,"MP pullups", SNUM(PB_METER_DELTA(mp_pullup)));
pval(sw," frags", SNUM(PB_METER_DELTA(mp_frags)));
pval(sw," nulls", SNUM(PB_METER_DELTA(mp_null)));
pval(sw," stale", SNUM(PB_METER_DELTA(mp_stale)));
pval(sw," no E bit", SNUM(PB_METER_DELTA(mp_no_end)));
pval(sw," orphan", SNUM(PB_METER_DELTA(mp_no_bits)));
pval(sw," stray", SNUM(PB_METER_DELTA(mp_stray)));
pval(sw," no mem", SNUM(PB_METER_DELTA(mp_alloc_fails)));
pval(sw," nested", SNUM(PB_METER_DELTA(mp_nested)));
pval(sw," frag queue", SNUM(C_BUNDLE.pb_mp.num_frags));
pval(sw," next sn", SNUM(C_BUNDLE.pb_mp.sn_in));
y = TOP;
x = COL2;
pval(1,"TOS queuing", SNUM(PB_METER_DELTA(move2f)));
pval(1,"TOS skipped", SNUM(PB_METER_DELTA(move2f_leak)));
y++;
pval(1,"debugging", SNUM(cur.ps_debug));
}
static void
prnt(char *fmt, ...)
{
va_list args;
move(y,x);
va_start(args, fmt);
if (win->_cury < BOS)
vwprintw(win, fmt, args);
va_end(args);
}
static void
clear_base(void)
{
bzero(&base, sizeof(base));
}
static void
set_base(void)
{
bcopy(&cur, &base, sizeof(cur));
}
static char*
hms(int secs)
{
static int n;
static struct {
char c[16]; /* hhhhhhhhh:mm:ss */
} bufs[NUM_VALUES];
char *p;
p = bufs[n].c;
n = (n+1) % NUM_VALUES;
if (secs < 0)
secs = 0;
sprintf(p, "%2d:%02d:%02d",
(secs/(60*60)) % 10000, (secs/60) % 60, secs % 60);
return p;
}
static char*
vtos(char *fmt, ...)
{
static int n;
static struct {
char c[COL_WIDTH+1];
} bufs[NUM_VALUES];
char *p;
va_list args;
va_start(args, fmt);
p = bufs[n].c;
n = (n+1) % NUM_VALUES;
(void)vsprintf(p, fmt, args);
va_end(args);
return p;
}
static void
pval(int sw, char *lab, char *v)
{
int lab_len, v_len, pad;
char buf[COL_WIDTH+1];
if (sw < 0) {
lab = "";
v = "";
} else if (sw == 0) {
v = "";
}
for (lab_len = 0; *lab != '\0'; lab++, lab_len++)
buf[lab_len] = (*lab == '~') ? ' ' : *lab;
buf[lab_len] = '\0';
move(y,x);
v_len = strlen(v);
pad = LABEL_WIDTH - lab_len;
if (v_len > NOMINAL_FIELD_WIDTH)
pad -= v_len - NOMINAL_FIELD_WIDTH;
if (pad < 0)
pad = 0;
printw("%s %*s%-*s ", buf,
pad, "",
(LABEL_WIDTH-lab_len-pad)+MAX_FIELD_WIDTH, v);
y++;
}
static void
usage(void)
{
fflush(stdout);
fflush(stderr);
(void)fprintf(stderr, "%s: usage: [-u unit] [-i interval]"
" [-m d|r|z]\n",
pgmname);
exit(1);
}
static void
sick(char *fmt, ...)
{
va_list args;
move(BOS, 0);
clrtoeol();
va_start(args, fmt);
if (++fail_cnt >= FATAL_FAIL) {
refresh();
endwin();
(void)vprintf(fmt,args);
putc('\n',stdout);
exit(1);
}
(void)vwprintw(win, fmt, args);
refresh();
needfoot = 1;
va_end(args);
}
#if 0
static void
fail(char *fmt, ...)
{
va_list args;
move(BOS, 0);
clrtoeol();
va_start(args, fmt);
refresh();
endwin();
(void)vprintf(fmt,args);
putc('\n',stdout);
exit(1);
va_end(args);
}
#endif
static void
quit(int s)
{
move(BOS, 0);
clrtoeol();
refresh();
endwin();
exit(s);
}
static void
sig_winch(int s)
{
(void)endwin();
win = initscr();
if (first < 1)
first = 1;
(void)signal(s, sig_winch);
}