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