]>
Commit | Line | Data |
---|---|---|
44bd5ea7 A |
1 | /* $NetBSD: lcmd2.c,v 1.9 1998/08/25 20:59:42 ross Exp $ */ |
2 | ||
3 | /* | |
4 | * Copyright (c) 1983, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | |
6 | * | |
7 | * This code is derived from software contributed to Berkeley by | |
8 | * Edward Wang at The University of California, Berkeley. | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. All advertising materials mentioning features or use of this software | |
19 | * must display the following acknowledgement: | |
20 | * This product includes software developed by the University of | |
21 | * California, Berkeley and its contributors. | |
22 | * 4. Neither the name of the University nor the names of its contributors | |
23 | * may be used to endorse or promote products derived from this software | |
24 | * without specific prior written permission. | |
25 | * | |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
36 | * SUCH DAMAGE. | |
37 | */ | |
38 | ||
39 | #include <sys/cdefs.h> | |
40 | #ifndef lint | |
41 | #if 0 | |
42 | static char sccsid[] = "@(#)lcmd2.c 8.1 (Berkeley) 6/6/93"; | |
43 | #else | |
44 | __RCSID("$NetBSD: lcmd2.c,v 1.9 1998/08/25 20:59:42 ross Exp $"); | |
45 | #endif | |
46 | #endif /* not lint */ | |
47 | ||
48 | #include <sys/types.h> | |
49 | #include <sys/time.h> | |
50 | #include <sys/resource.h> | |
51 | #include <string.h> | |
52 | #include "defs.h" | |
53 | #include "window_string.h" | |
54 | #include "var.h" | |
55 | #include "lcmd.h" | |
56 | #include "alias.h" | |
57 | ||
58 | int printalias __P((void *, struct var *)); | |
59 | int printvar __P((void *, struct var *)); | |
60 | char *strtime __P((struct timeval *t)); | |
61 | ||
62 | void | |
63 | l_iostat(v, a) | |
64 | struct value *v, *a; | |
65 | { | |
66 | struct ww *w; | |
67 | ||
68 | if ((w = openiwin(16, "IO Statistics")) == 0) { | |
69 | error("Can't open statistics window: %s.", wwerror()); | |
70 | return; | |
71 | } | |
72 | wwprintf(w, "ttflush\twrite\terror\tzero\tchar\n"); | |
73 | wwprintf(w, "%d\t%d\t%d\t%d\t%d\n", | |
74 | wwnflush, wwnwr, wwnwre, wwnwrz, wwnwrc); | |
75 | wwprintf(w, "token\tuse\tbad\tsaving\ttotal\tbaud\n"); | |
76 | wwprintf(w, "%d\t%d\t%d\t%d\t%d\t%d/%d (%.1f/%.1f)\n", | |
77 | wwntokdef, wwntokuse, wwntokbad, wwntoksave, wwntokc, | |
78 | wwntokc - wwntoksave ? | |
79 | (int) ((float) wwbaud * wwntokc / | |
80 | (wwntokc - wwntoksave)) : | |
81 | wwbaud, | |
82 | wwnwrc ? (int) ((float) wwbaud * (wwnwrc + wwntoksave) / | |
83 | wwnwrc) : | |
84 | wwbaud, | |
85 | wwntokc - wwntoksave ? | |
86 | (float) wwntokc / (wwntokc - wwntoksave) : 1.0, | |
87 | wwnwrc ? (float) (wwnwrc + wwntoksave) / wwnwrc : 1.0); | |
88 | wwprintf(w, "wwwrite\tattempt\tchar\n"); | |
89 | wwprintf(w, "%d\t%d\t%d\n", | |
90 | wwnwwr, wwnwwra, wwnwwrc); | |
91 | wwprintf(w, "wwupdat\tline\tmiss\tscan\tclreol\tclreos\tmiss\tline\n"); | |
92 | wwprintf(w, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", | |
93 | wwnupdate, wwnupdline, wwnupdmiss, wwnupdscan, wwnupdclreol, | |
94 | wwnupdclreos, wwnupdclreosmiss, wwnupdclreosline); | |
95 | wwprintf(w, "select\terror\tzero\n"); | |
96 | wwprintf(w, "%d\t%d\t%d\n", | |
97 | wwnselect, wwnselecte, wwnselectz); | |
98 | wwprintf(w, "read\terror\tzero\tchar\tack\tnack\tstat\terrorc\n"); | |
99 | wwprintf(w, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", | |
100 | wwnread, wwnreade, wwnreadz, wwnreadc, wwnreadack, wwnreadnack, | |
101 | wwnreadstat, wwnreadec); | |
102 | wwprintf(w, "ptyread\terror\tzero\tcontrol\tdata\tchar\n"); | |
103 | wwprintf(w, "%d\t%d\t%d\t%d\t%d\t%d\n", | |
104 | wwnwread, wwnwreade, wwnwreadz, | |
105 | wwnwreadp, wwnwreadd, wwnwreadc); | |
106 | waitnl(w); | |
107 | closeiwin(w); | |
108 | } | |
109 | ||
110 | struct lcmd_arg arg_time[] = { | |
111 | { "who", 1, ARG_STR }, | |
112 | { 0 } | |
113 | }; | |
114 | ||
115 | void | |
116 | l_time(v, a) | |
117 | struct value *v, *a; | |
118 | { | |
119 | struct ww *w; | |
120 | struct rusage rusage; | |
121 | struct timeval timeval; | |
122 | ||
123 | if ((w = openiwin(8, "Timing and Resource Usage")) == 0) { | |
124 | error("Can't open time window: %s.", wwerror()); | |
125 | return; | |
126 | } | |
127 | ||
128 | (void) gettimeofday(&timeval, (struct timezone *)0); | |
129 | timersub(&timeval, &starttime, &timeval); | |
130 | (void) getrusage(a->v_type == V_STR | |
131 | && str_match(a->v_str, "children", 1) | |
132 | ? RUSAGE_CHILDREN : RUSAGE_SELF, &rusage); | |
133 | ||
134 | wwprintf(w, "%-15s %-15s %-15s\n", | |
135 | "time", "utime", "stime"); | |
136 | wwprintf(w, "%-15s ", strtime(&timeval)); | |
137 | wwprintf(w, "%-15s ", strtime(&rusage.ru_utime)); | |
138 | wwprintf(w, "%-15s\n", strtime(&rusage.ru_stime)); | |
139 | wwprintf(w, "%-15s %-15s %-15s %-15s\n", | |
140 | "maxrss", "ixrss", "idrss", "isrss"); | |
141 | wwprintf(w, "%-15ld %-15ld %-15ld %-15ld\n", | |
142 | rusage.ru_maxrss, rusage.ru_ixrss, | |
143 | rusage.ru_idrss, rusage.ru_isrss); | |
144 | wwprintf(w, "%-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s\n", | |
145 | "minflt", "majflt", "nswap", "inblk", "oublk", | |
146 | "msgsnd", "msgrcv", "nsigs", "nvcsw", "nivcsw"); | |
147 | wwprintf(w, "%-7ld %-7ld %-7ld %-7ld %-7ld %-7ld %-7ld %-7ld %-7ld %-7ld\n", | |
148 | rusage.ru_minflt, rusage.ru_majflt, rusage.ru_nswap, | |
149 | rusage.ru_inblock, rusage.ru_oublock, | |
150 | rusage.ru_msgsnd, rusage.ru_msgrcv, rusage.ru_nsignals, | |
151 | rusage.ru_nvcsw, rusage.ru_nivcsw); | |
152 | ||
153 | waitnl(w); | |
154 | closeiwin(w); | |
155 | } | |
156 | ||
157 | char * | |
158 | strtime(t) | |
159 | struct timeval *t; | |
160 | { | |
161 | char fill = 0; | |
162 | static char buf[20]; | |
163 | char *p = buf; | |
164 | ||
165 | if (t->tv_sec > 60*60) { | |
166 | (void) sprintf(p, "%ld:", (long int)t->tv_sec / (60*60)); | |
167 | while (*p++) | |
168 | ; | |
169 | p--; | |
170 | t->tv_sec %= 60*60; | |
171 | fill++; | |
172 | } | |
173 | if (t->tv_sec > 60) { | |
174 | (void) sprintf(p, fill ? "%02ld:" : "%ld:", t->tv_sec / 60); | |
175 | while (*p++) | |
176 | ; | |
177 | p--; | |
178 | t->tv_sec %= 60; | |
179 | fill++; | |
180 | } | |
181 | (void) sprintf(p, fill ? "%02ld.%02d" : "%ld.%02ld", | |
182 | t->tv_sec, t->tv_usec / 10000); | |
183 | return buf; | |
184 | } | |
185 | ||
186 | void | |
187 | l_list(v, a) | |
188 | struct value *v, *a; | |
189 | { | |
190 | struct ww *w, *wp; | |
191 | int i; | |
192 | int n; | |
193 | ||
194 | for (n = 0, i = 0; i < NWINDOW; i++) | |
195 | if (window[i] != 0) | |
196 | n++; | |
197 | if (n == 0) { | |
198 | error("No windows."); | |
199 | return; | |
200 | } | |
201 | if ((w = openiwin(n + 2, "Windows")) == 0) { | |
202 | error("Can't open listing window: %s.", wwerror()); | |
203 | return; | |
204 | } | |
205 | for (i = 0; i < NWINDOW; i++) { | |
206 | if ((wp = window[i]) == 0) | |
207 | continue; | |
208 | wwprintf(w, "%c %c %-13s %-.*s\n", | |
209 | wp == selwin ? '+' : (wp == lastselwin ? '-' : ' '), | |
210 | i + '1', | |
211 | wp->ww_state == WWS_HASPROC ? "" : "(No process)", | |
212 | wwncol - 20, | |
213 | wp->ww_label ? wp->ww_label : "(No label)"); | |
214 | } | |
215 | waitnl(w); | |
216 | closeiwin(w); | |
217 | } | |
218 | ||
219 | void | |
220 | l_variable(v, a) | |
221 | struct value *v, *a; | |
222 | { | |
223 | struct ww *w; | |
224 | ||
225 | if ((w = openiwin(wwnrow - 3, "Variables")) == 0) { | |
226 | error("Can't open variable window: %s.", wwerror()); | |
227 | return; | |
228 | } | |
229 | if (var_walk(printvar, (void *)w) >= 0) | |
230 | waitnl(w); | |
231 | closeiwin(w); | |
232 | } | |
233 | ||
234 | int | |
235 | printvar(vw, r) | |
236 | void *vw; | |
237 | struct var *r; | |
238 | { | |
239 | struct ww *w = vw; | |
240 | if (more(w, 0) == 2) | |
241 | return -1; | |
242 | wwprintf(w, "%16s ", r->r_name); | |
243 | switch (r->r_val.v_type) { | |
244 | case V_STR: | |
245 | wwprintf(w, "%s\n", r->r_val.v_str); | |
246 | break; | |
247 | case V_NUM: | |
248 | wwprintf(w, "%d\n", r->r_val.v_num); | |
249 | break; | |
250 | case V_ERR: | |
251 | wwprintf(w, "ERROR\n"); | |
252 | break; | |
253 | } | |
254 | return 0; | |
255 | } | |
256 | ||
257 | struct lcmd_arg arg_def_shell[] = { | |
258 | { "", 0, ARG_ANY|ARG_LIST }, | |
259 | { 0 } | |
260 | }; | |
261 | ||
262 | void | |
263 | l_def_shell(v, a) | |
264 | struct value *v, *a; | |
265 | { | |
266 | char **pp; | |
267 | struct value *vp; | |
268 | ||
269 | if (a->v_type == V_ERR) { | |
270 | if ((v->v_str = str_cpy(default_shellfile)) != 0) | |
271 | v->v_type = V_STR; | |
272 | return; | |
273 | } | |
274 | if ((v->v_str = default_shellfile)) { | |
275 | v->v_type = V_STR; | |
276 | for (pp = default_shell + 1; *pp; pp++) { | |
277 | str_free(*pp); | |
278 | *pp = 0; | |
279 | } | |
280 | } | |
281 | for (pp = default_shell, vp = a; | |
282 | vp->v_type != V_ERR && | |
283 | pp < &default_shell[sizeof default_shell/sizeof *default_shell-1]; | |
284 | pp++, vp++) | |
285 | if ((*pp = vp->v_type == V_STR ? | |
286 | str_cpy(vp->v_str) : str_itoa(vp->v_num)) == 0) { | |
287 | /* just leave default_shell[] the way it is */ | |
288 | p_memerror(); | |
289 | break; | |
290 | } | |
291 | if ((default_shellfile = *default_shell)) { | |
292 | if ((*default_shell = strrchr(default_shellfile, '/'))) | |
293 | (*default_shell)++; | |
294 | else | |
295 | *default_shell = default_shellfile; | |
296 | } | |
297 | } | |
298 | ||
299 | struct lcmd_arg arg_alias[] = { | |
300 | { "", 0, ARG_STR }, | |
301 | { "", 0, ARG_STR|ARG_LIST }, | |
302 | { 0 } | |
303 | }; | |
304 | ||
305 | void | |
306 | l_alias(v, a) | |
307 | struct value *v, *a; | |
308 | { | |
309 | if (a->v_type == V_ERR) { | |
310 | struct ww *w; | |
311 | ||
312 | if ((w = openiwin(wwnrow - 3, "Aliases")) == 0) { | |
313 | error("Can't open alias window: %s.", wwerror()); | |
314 | return; | |
315 | } | |
316 | if (alias_walk(printalias, (void *)w) >= 0) | |
317 | waitnl(w); | |
318 | closeiwin(w); | |
319 | } else { | |
320 | struct alias *ap = 0; | |
321 | ||
322 | if ((ap = alias_lookup(a->v_str))) { | |
323 | if ((v->v_str = str_cpy(ap->a_buf)) == 0) { | |
324 | p_memerror(); | |
325 | return; | |
326 | } | |
327 | v->v_type = V_STR; | |
328 | } | |
329 | if (a[1].v_type == V_STR) { | |
330 | struct value *vp; | |
331 | char *p, *q; | |
332 | char *str; | |
333 | int n; | |
334 | ||
335 | for (n = 0, vp = a + 1; vp->v_type != V_ERR; vp++, n++) | |
336 | for (p = vp->v_str; *p; p++, n++) | |
337 | ; | |
338 | if ((str = str_alloc(n)) == 0) { | |
339 | p_memerror(); | |
340 | return; | |
341 | } | |
342 | for (q = str, vp = a + 1; vp->v_type != V_ERR; | |
343 | vp++, q[-1] = ' ') | |
344 | for (p = vp->v_str; (*q++ = *p++);) | |
345 | ; | |
346 | q[-1] = 0; | |
347 | if ((ap = alias_set(a[0].v_str, (char *)0)) == 0) { | |
348 | p_memerror(); | |
349 | str_free(str); | |
350 | return; | |
351 | } | |
352 | ap->a_buf = str; | |
353 | } | |
354 | } | |
355 | } | |
356 | ||
357 | int | |
358 | printalias(vw, a) | |
359 | void *vw; | |
360 | struct alias *a; | |
361 | { | |
362 | struct ww *w = vw; | |
363 | if (more(w, 0) == 2) | |
364 | return -1; | |
365 | wwprintf(w, "%16s %s\n", a->a_name, a->a_buf); | |
366 | return 0; | |
367 | } | |
368 | ||
369 | struct lcmd_arg arg_unalias[] = { | |
370 | { "alias", 1, ARG_STR }, | |
371 | { 0 } | |
372 | }; | |
373 | ||
374 | void | |
375 | l_unalias(v, a) | |
376 | struct value *v, *a; | |
377 | { | |
378 | if (a->v_type == ARG_STR) | |
379 | v->v_num = alias_unset(a->v_str); | |
380 | v->v_type = V_NUM; | |
381 | } | |
382 | ||
383 | struct lcmd_arg arg_echo[] = { | |
384 | { "window", 1, ARG_NUM }, | |
385 | { "", 0, ARG_ANY|ARG_LIST }, | |
386 | { 0 } | |
387 | }; | |
388 | ||
389 | void | |
390 | l_echo(v, a) | |
391 | struct value *v, *a; | |
392 | { | |
393 | char buf[20]; | |
394 | struct ww *w; | |
395 | ||
396 | if ((w = vtowin(a++, selwin)) == 0) | |
397 | return; | |
398 | while (a->v_type != V_ERR) { | |
399 | if (a->v_type == V_NUM) { | |
400 | (void) sprintf(buf, "%d", a->v_num); | |
401 | (void) wwwrite(w, buf, strlen(buf)); | |
402 | } else | |
403 | (void) wwwrite(w, a->v_str, strlen(a->v_str)); | |
404 | if ((++a)->v_type != V_ERR) | |
405 | (void) wwwrite(w, " ", 1); | |
406 | } | |
407 | (void) wwwrite(w, "\r\n", 2); | |
408 | } |