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