Commit | Line | Data |
---|---|---|
0ca7a29c | 1 | #ifndef lint |
852c7064 | 2 | static char sccsid[] = "@(#)main.c 1.3 (Lucasfilm) %G%"; |
0ca7a29c SL |
3 | #endif |
4 | ||
5 | #include "systat.h" | |
6 | ||
7 | struct 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 | ||
45 | int kmem = -1; | |
46 | int mem = -1; | |
47 | int swap = -1; | |
f58d0ba1 | 48 | int naptime = 5; |
0ca7a29c SL |
49 | |
50 | int die(); | |
51 | int display(); | |
52 | int suspend(); | |
53 | ||
852c7064 SL |
54 | int showpigs(), openpigs(), fetchpigs(), labelpigs(), initpigs(); |
55 | int showswap(), fetchswap(), labelswap(), initswap(); | |
56 | int showmbufs(), fetchmbufs(), labelmbufs(), initmbufs(); | |
57 | #ifdef notdef | |
58 | int showuser(), openuser(), fetchuser(), labeluser(), inituser(); | |
59 | int shownet(), opennet(), fetchnet(), labelnet(), initnet(); | |
60 | #endif | |
0ca7a29c SL |
61 | |
62 | struct 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 | }; | |
85 | struct cmdtab *curcmd = &cmdtab[0]; | |
86 | ||
87 | main(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 | ||
204 | command(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 | ||
275 | status() | |
276 | { | |
277 | ||
278 | mvprintw(22, 0, "Showing %s, refresh every %d seconds.", | |
279 | curcmd->c_name, naptime); | |
280 | clrtoeol(); | |
281 | } | |
282 | ||
283 | suspend() | |
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 | ||
304 | labels() | |
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 | ||
317 | display() | |
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 | ||
353 | die() | |
354 | { | |
355 | ||
356 | endwin(); | |
357 | exit(0); | |
358 | } | |
852c7064 SL |
359 | |
360 | error(fmt, a1, a2, a3) | |
361 | { | |
362 | ||
363 | mvprintw(22, 0, fmt, a1, a2, a3); | |
364 | clrtoeol(); | |
365 | refresh(); | |
366 | } |