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