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