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