main.c revision 1.7 1 /* $NetBSD: main.c,v 1.7 1996/03/21 18:04:25 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.7 1996/03/21 18:04:25 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 int
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 }
297