Annotation of src/usr.bin/systat/main.c, Revision 1.1.1.1
1.1 deraadt 1: /* $NetBSD: main.c,v 1.6 1995/05/06 06:25:07 jtc Exp $ */
2:
3: /*-
4: * Copyright (c) 1980, 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #ifndef lint
37: static char copyright[] =
38: "@(#) Copyright (c) 1980, 1992, 1993\n\
39: The Regents of the University of California. All rights reserved.\n";
40: #endif /* not lint */
41:
42: #ifndef lint
43: #if 0
44: static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
45: #endif
46: static char rcsid[] = "$NetBSD: main.c,v 1.6 1995/05/06 06:25:07 jtc Exp $";
47: #endif /* not lint */
48:
49: #include <sys/param.h>
50:
51: #include <err.h>
52: #include <nlist.h>
53: #include <signal.h>
54: #include <stdio.h>
55: #include <string.h>
56:
57: #include "systat.h"
58: #include "extern.h"
59:
60: static struct nlist namelist[] = {
61: #define X_FIRST 0
62: #define X_HZ 0
63: { "_hz" },
64: #define X_STATHZ 1
65: { "_stathz" },
66: { "" }
67: };
68: static int dellave;
69:
70: kvm_t *kd;
71: sig_t sigtstpdfl;
72: double avenrun[3];
73: int col;
74: int naptime = 5;
75: int verbose = 1; /* to report kvm read errs */
76: int hz, stathz;
77: char c;
78: char *namp;
79: char hostname[MAXHOSTNAMELEN];
80: WINDOW *wnd;
81: int CMDLINE;
82:
83: static WINDOW *wload; /* one line window for load average */
84:
85: void
86: main(argc, argv)
87: int argc;
88: char **argv;
89: {
90: char errbuf[80];
91:
92: argc--, argv++;
93: while (argc > 0) {
94: if (argv[0][0] == '-') {
95: struct cmdtab *p;
96:
97: p = lookup(&argv[0][1]);
98: if (p == (struct cmdtab *)-1)
99: errx(1, "ambiguous request: %s", &argv[0][1]);
100: if (p == 0)
101: errx(1, "unknown request: %s", &argv[0][1]);
102: curcmd = p;
103: } else {
104: naptime = atoi(argv[0]);
105: if (naptime <= 0)
106: naptime = 5;
107: }
108: argc--, argv++;
109: }
110: kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
111: if (kd == NULL) {
112: error("%s", errbuf);
113: exit(1);
114: }
115: if (kvm_nlist(kd, namelist)) {
116: nlisterr(namelist);
117: exit(1);
118: }
119: if (namelist[X_FIRST].n_type == 0)
120: errx(1, "couldn't read namelist");
121: signal(SIGINT, die);
122: signal(SIGQUIT, die);
123: signal(SIGTERM, die);
124:
125: /*
126: * Initialize display. Load average appears in a one line
127: * window of its own. Current command's display appears in
128: * an overlapping sub-window of stdscr configured by the display
129: * routines to minimize update work by curses.
130: */
131: if (initscr() == NULL)
132: {
133: warnx("couldn't initialize screen");
134: exit(0);
135: }
136:
137: CMDLINE = LINES - 1;
138: wnd = (*curcmd->c_open)();
139: if (wnd == NULL) {
140: warnx("couldn't initialize display");
141: die(0);
142: }
143: wload = newwin(1, 0, 3, 20);
144: if (wload == NULL) {
145: warnx("couldn't set up load average window");
146: die(0);
147: }
148: gethostname(hostname, sizeof (hostname));
149: NREAD(X_HZ, &hz, LONG);
150: NREAD(X_STATHZ, &stathz, LONG);
151: (*curcmd->c_init)();
152: curcmd->c_flags |= CF_INIT;
153: labels();
154:
155: dellave = 0.0;
156:
157: signal(SIGALRM, display);
158: display(0);
159: noecho();
160: crmode();
161: keyboard();
162: /*NOTREACHED*/
163: }
164:
165: void
166: labels()
167: {
168: if (curcmd->c_flags & CF_LOADAV) {
169: mvaddstr(2, 20,
170: "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10");
171: mvaddstr(3, 5, "Load Average");
172: }
173: (*curcmd->c_label)();
174: #ifdef notdef
175: mvprintw(21, 25, "CPU usage on %s", hostname);
176: #endif
177: refresh();
178: }
179:
180: void
181: display(signo)
182: int signo;
183: {
184: register int i, j;
185:
186: /* Get the load average over the last minute. */
187: (void) getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0]));
188: (*curcmd->c_fetch)();
189: if (curcmd->c_flags & CF_LOADAV) {
190: j = 5.0*avenrun[0] + 0.5;
191: dellave -= avenrun[0];
192: if (dellave >= 0.0)
193: c = '<';
194: else {
195: c = '>';
196: dellave = -dellave;
197: }
198: if (dellave < 0.1)
199: c = '|';
200: dellave = avenrun[0];
201: wmove(wload, 0, 0); wclrtoeol(wload);
202: for (i = (j > 50) ? 50 : j; i > 0; i--)
203: waddch(wload, c);
204: if (j > 50)
205: wprintw(wload, " %4.1f", avenrun[0]);
206: }
207: (*curcmd->c_refresh)();
208: if (curcmd->c_flags & CF_LOADAV)
209: wrefresh(wload);
210: wrefresh(wnd);
211: move(CMDLINE, col);
212: refresh();
213: alarm(naptime);
214: }
215:
216: void
217: load()
218: {
219:
220: (void) getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0]));
221: mvprintw(CMDLINE, 0, "%4.1f %4.1f %4.1f",
222: avenrun[0], avenrun[1], avenrun[2]);
223: clrtoeol();
224: }
225:
226: void
227: die(signo)
228: int signo;
229: {
230: move(CMDLINE, 0);
231: clrtoeol();
232: refresh();
233: endwin();
234: exit(0);
235: }
236:
237: #if __STDC__
238: #include <stdarg.h>
239: #else
240: #include <varargs.h>
241: #endif
242:
243: #if __STDC__
244: void
245: error(const char *fmt, ...)
246: #else
247: void
248: error(fmt, va_alist)
249: char *fmt;
250: va_dcl
251: #endif
252: {
253: va_list ap;
254: char buf[255];
255: int oy, ox;
256: #if __STDC__
257: va_start(ap, fmt);
258: #else
259: va_start(ap);
260: #endif
261:
262: if (wnd) {
263: getyx(stdscr, oy, ox);
264: (void) vsprintf(buf, fmt, ap);
265: clrtoeol();
266: standout();
267: mvaddstr(CMDLINE, 0, buf);
268: standend();
269: move(oy, ox);
270: refresh();
271: } else {
272: (void) vfprintf(stderr, fmt, ap);
273: fprintf(stderr, "\n");
274: }
275: va_end(ap);
276: }
277:
278: void
279: nlisterr(namelist)
280: struct nlist namelist[];
281: {
282: int i, n;
283:
284: n = 0;
285: clear();
286: mvprintw(2, 10, "systat: nlist: can't find following symbols:");
287: for (i = 0;
288: namelist[i].n_name != NULL && *namelist[i].n_name != '\0'; i++)
289: if (namelist[i].n_value == 0)
290: mvprintw(2 + ++n, 10, "%s", namelist[i].n_name);
291: move(CMDLINE, 0);
292: clrtoeol();
293: refresh();
294: endwin();
295: exit(1);
296: }