date and time created 83/10/02 17:09:12 by sam
[unix-history] / usr / src / usr.bin / systat / main.c
CommitLineData
0ca7a29c 1#ifndef lint
852c7064 2static char sccsid[] = "@(#)main.c 1.3 (Lucasfilm) %G%";
0ca7a29c
SL
3#endif
4
5#include "systat.h"
6
7struct nlist nlst[] = {
8#define X_PROC 0
9 { "_proc" },
10#define X_NPROC 1
11 { "_nproc" },
12#define X_CCPU 2
13 { "_ccpu" },
14#define X_AVENRUN 3
15 { "_avenrun" },
16#define X_USRPTMAP 4
17 { "_Usrptmap" },
18#define X_USRPT 5
19 { "_usrpt" },
20#define X_NSWAP 6
21 { "_nswap" },
22#define X_SWAPMAP 7
23 { "_swapmap" },
24#define X_NSWAPMAP 8
25 { "_nswapmap" },
26#define X_DMMIN 9
27 { "_dmmin" },
28#define X_DMMAX 10
29 { "_dmmax" },
30#define X_NSWDEV 11
31 { "_nswdev" },
f58d0ba1
SL
32#define X_SWDEVT 12
33 { "_swdevt" },
852c7064
SL
34#define X_NTEXT 13
35 { "_ntext" },
36#define X_TEXT 14
37 { "_text" },
38#define X_DMTEXT 15
39 { "_dmtext" },
40#define X_MBSTAT 16
41 { "_mbstat" },
0ca7a29c
SL
42 { "" }
43};
44
45int kmem = -1;
46int mem = -1;
47int swap = -1;
f58d0ba1 48int naptime = 5;
0ca7a29c
SL
49
50int die();
51int display();
52int suspend();
53
852c7064
SL
54int showpigs(), openpigs(), fetchpigs(), labelpigs(), initpigs();
55int showswap(), fetchswap(), labelswap(), initswap();
56int showmbufs(), fetchmbufs(), labelmbufs(), initmbufs();
57#ifdef notdef
58int showuser(), openuser(), fetchuser(), labeluser(), inituser();
59int shownet(), opennet(), fetchnet(), labelnet(), initnet();
60#endif
0ca7a29c
SL
61
62struct cmdtab {
63 char *c_name;
64 int (*c_refresh)();
65 int (*c_open)();
66 int (*c_fetch)();
67 int (*c_label)();
852c7064
SL
68 int (*c_init)();
69 char c_flags;
0ca7a29c
SL
70} cmdtab[] = {
71 { "pigs", showpigs, openpigs, fetchpigs,
852c7064 72 labelpigs, initpigs },
0ca7a29c 73 { "swap", showswap, openpigs, fetchswap,
852c7064
SL
74 labelswap, initswap },
75 { "mbufs", showmbufs, openpigs, fetchmbufs,
76 labelmbufs, initmbufs },
0ca7a29c
SL
77#ifdef notdef
78 { "user", showuser, openuser, fetchuser,
852c7064 79 labeluser, inituser },
0ca7a29c 80 { "net", shownet, opennet, fetchnet,
852c7064 81 labelnet, initnet },
0ca7a29c
SL
82#endif
83 { "" }
84};
85struct cmdtab *curcmd = &cmdtab[0];
86
87main(argc, argv)
88 int argc;
89 char **argv;
90{
91 char ch, line[80];
92
f58d0ba1
SL
93 argc--, argv++;
94 while (argc > 0) {
95 if (argv[0][0] == '-') {
96 struct cmdtab *p;
97
98 for (p = cmdtab; *p->c_name; p++)
99 if (strcmp(p->c_name, &argv[0][1]) == 0)
100 break;
101 if (*p->c_name == 0) {
102 fprintf(stderr, "%s: unknown request\n",
103 &argv[0][1]);
104 exit(1);
105 }
106 curcmd = p;
107 } else {
108 naptime = atoi(argv[1]);
109 if (naptime < 5)
110 naptime = 5;
111 }
112 argc--, argv++;
113 }
0ca7a29c
SL
114 nlist("/vmunix", nlst);
115 (*curcmd->c_open)();
0ca7a29c
SL
116 signal(SIGINT, die);
117 signal(SIGQUIT, die);
118 signal(SIGTERM, die);
119
120 /* Initialize curses. */
121 initscr();
122 wnd = newwin(20, 70, 3, 5);
123
f58d0ba1
SL
124#ifdef notdef
125 gethostname(hostname, sizeof (hostname));
126#endif
0ca7a29c
SL
127 lseek(kmem, nlst[X_CCPU].n_value, 0);
128 read(kmem, &ccpu, sizeof (ccpu));
129 lccpu = log(ccpu);
0ca7a29c
SL
130 labels();
131
132 known[0].k_uid = -1;
133 strcpy(known[0].k_name, "<idle>");
134 numknown = 1;
135 dellave = 0.0;
136
137 signal(SIGALRM, display);
138 signal(SIGTSTP, suspend);
139 display();
140 noecho();
141 crmode();
142 for (;;) {
143 col = 0;
144 move(22, 0);
145 do {
146 refresh();
147 ch = getch() & 0177;
148 if (ch == 0177 && ferror(stdin)) {
149 clearerr(stdin);
150 continue;
151 }
152 if (ch >= 'A' && ch <= 'Z')
153 ch += 'a' - 'A';
154 if (col == 0) {
852c7064 155#define mask(s) (1 << ((s) - 1))
0ca7a29c 156 if (ch == CTRL(l)) {
852c7064
SL
157 int oldmask = sigblock(mask(SIGALRM));
158
159 wrefresh(curscr);
160 sigsetmask(oldmask);
0ca7a29c
SL
161 continue;
162 }
163 if (ch != ':')
164 continue;
165 move(22, 0);
166 clrtoeol();
167 }
168 if (ch == _tty.sg_erase && col > 0) {
169 if (col == 1 && line[0] == ':')
170 continue;
171 col--;
172 goto doerase;
173 }
174 if (ch == CTRL(w) && col > 0) {
175 while (--col >= 0 && isspace(line[col]))
176 ;
177 col++;
178 while (--col >= 0 && !isspace(line[col]))
179 if (col == 0 && line[0] == ':')
180 break;
181 col++;
182 goto doerase;
183 }
184 if (ch == _tty.sg_kill && col > 0) {
185 col = 0;
186 if (line[0] == ':')
187 col++;
188 doerase:
189 move(22, col);
190 clrtoeol();
191 continue;
192 }
193 if (isprint(ch)) {
194 line[col] = ch;
195 mvaddch(22, col, ch);
196 col++;
197 }
198 } while (col == 0 || (ch != '\r' && ch != '\n'));
199 line[col] = '\0';
200 command(line + 1);
201 }
202}
203
204command(cmd)
205 char *cmd;
206{
207 register char *cp;
208 register struct cmdtab *p;
209 char *arg;
210
211 for (cp = cmd; *cp && !isspace(*cp); cp++)
212 ;
213 if (*cp)
214 *cp++ = '\0';
215 if (strcmp(cmd, "quit") == 0)
216 die();
217 if (strcmp(cmd, "status") == 0 || strcmp(cmd, "help") == 0) {
218 status();
219 return;
220 }
f58d0ba1
SL
221 if (strcmp(cmd, "load") == 0) {
222 lseek(kmem, nlst[X_AVENRUN].n_value, L_SET);
223 read(kmem, &lave, sizeof (lave));
224 mvprintw(22, 0, "%4.1f", lave);
225 clrtoeol();
226 return;
227 }
0ca7a29c
SL
228 for (p = cmdtab; *p->c_name; p++)
229 if (strcmp(cmd, p->c_name) == 0)
230 break;
231 if (*p->c_name) {
232 if (curcmd == p)
233 return;
234 alarm(0);
235 curcmd = p;
f58d0ba1
SL
236 clear(); wclear(wnd);
237 labels();
0ca7a29c
SL
238 display();
239 status();
240 return;
241 }
242 if (strcmp(cmd, "stop") == 0) {
243 alarm(0);
244 mvaddstr(22, 0, "Refresh disabled.");
245 clrtoeol();
246 return;
247 }
248 /* commands with arguments */
249 for (; *cp && isspace(*cp); cp++)
250 ;
251 if (strcmp(cmd, "start") == 0) {
252 int x;
253
254 if (*cp == '\0')
255 x = naptime;
256 else
257 x = atoi(cp);
258 if (x <= 0) {
259 mvprintw(22, 0, "%d: bad interval.", x);
260 clrtoeol();
261 return;
262 }
263 alarm(0);
264 naptime = x;
265 display();
266 status();
267 return;
268 }
f58d0ba1
SL
269 if (*cmd) {
270 mvprintw(22, 0, "%s: Unknown command.", cmd);
271 clrtoeol();
272 }
0ca7a29c
SL
273}
274
275status()
276{
277
278 mvprintw(22, 0, "Showing %s, refresh every %d seconds.",
279 curcmd->c_name, naptime);
280 clrtoeol();
281}
282
283suspend()
284{
285 int oldmask;
286
f58d0ba1 287 alarm(0);
0ca7a29c
SL
288 move(22, 0);
289 refresh();
290 echo();
291 nocrmode();
292 signal(SIGTSTP, SIG_DFL);
293 oldmask = sigsetmask(0);
294 kill(getpid(), SIGTSTP);
295 sigsetmask(oldmask);
296 signal(SIGTSTP, suspend);
297 crmode();
298 noecho();
299 move(22, col);
300 wrefresh(curscr);
f58d0ba1 301 alarm(naptime);
0ca7a29c
SL
302}
303
304labels()
305{
306
307 mvaddstr(2, 20,
308 "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10");
309 mvwaddstr(wnd, 0, 0, "Load Average");
310 (*curcmd->c_label)();
311#ifdef notdef
312 mvprintw(21, 25, "CPU usage on %s", hostname);
313#endif
314 refresh();
315}
316
317display()
318{
319 register int i, j;
320
321 /* Get the load average over the last minute. */
322 lseek(kmem, nlst[X_AVENRUN].n_value, L_SET);
323 read(kmem, &lave, sizeof (lave));
852c7064
SL
324 if (curcmd->c_flags == 0) {
325 (*curcmd->c_init)();
326 curcmd->c_flags = 1;
327 }
0ca7a29c
SL
328 (*curcmd->c_fetch)();
329 j = 5.0*lave + 0.5;
330 dellave -= lave;
331 if (dellave >= 0.0)
332 c = '<';
333 else {
334 c = '>';
335 dellave = -dellave;
336 }
337 if (dellave < 0.1)
338 c = '|';
339 dellave = lave;
340 wmove(wnd, 0, 15);
341 wclrtoeol(wnd);
342 for (i = (j > 50)? 50 : j; i > 0; i--)
343 waddch(wnd, c);
344 if (j > 50)
345 wprintw(wnd, " %4.1f", lave);
346 (*curcmd->c_refresh)();
347 wrefresh(wnd);
348 move(22, col);
349 refresh();
350 alarm(naptime);
351}
352
353die()
354{
355
356 endwin();
357 exit(0);
358}
852c7064
SL
359
360error(fmt, a1, a2, a3)
361{
362
363 mvprintw(22, 0, fmt, a1, a2, a3);
364 clrtoeol();
365 refresh();
366}