1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)w.c	5.3 (Berkeley) 2/23/86";
  15: #endif not lint
  16: 
  17: /*
  18:  * w - print system status (who and what)
  19:  *
  20:  * This program is similar to the systat command on Tenex/Tops 10/20
  21:  * It needs read permission on /dev/mem, /dev/kmem, and /dev/drum.
  22:  */
  23: #include <sys/param.h>
  24: #include <nlist.h>
  25: #include <stdio.h>
  26: #include <ctype.h>
  27: #include <utmp.h>
  28: #include <sys/stat.h>
  29: #include <sys/dir.h>
  30: #include <sys/user.h>
  31: #include <sys/proc.h>
  32: #include <machine/pte.h>
  33: #include <sys/vm.h>
  34: 
  35: #define NMAX sizeof(utmp.ut_name)
  36: #define LMAX sizeof(utmp.ut_line)
  37: 
  38: #define ARGWIDTH    33  /* # chars left on 80 col crt for args */
  39: 
  40: struct pr {
  41:     short   w_pid;          /* proc.p_pid */
  42:     char    w_flag;         /* proc.p_flag */
  43:     short   w_size;         /* proc.p_size */
  44:     long    w_seekaddr;     /* where to find args */
  45:     long    w_lastpg;       /* disk address of stack */
  46:     int w_igintr;       /* INTR+3*QUIT, 0=die, 1=ign, 2=catch */
  47:     time_t  w_time;         /* CPU time used by this process */
  48:     time_t  w_ctime;        /* CPU time used by children */
  49:     dev_t   w_tty;          /* tty device of process */
  50:     int w_uid;          /* uid of process */
  51:     char    w_comm[15];     /* user.u_comm, null terminated */
  52:     char    w_args[ARGWIDTH+1]; /* args if interesting process */
  53: } *pr;
  54: int nproc;
  55: 
  56: struct  nlist nl[] = {
  57:     { "_proc" },
  58: #define X_PROC      0
  59:     { "_swapdev" },
  60: #define X_SWAPDEV   1
  61:     { "_Usrptmap" },
  62: #define X_USRPTMA   2
  63:     { "_usrpt" },
  64: #define X_USRPT     3
  65:     { "_nswap" },
  66: #define X_NSWAP     4
  67:     { "_avenrun" },
  68: #define X_AVENRUN   5
  69:     { "_boottime" },
  70: #define X_BOOTTIME  6
  71:     { "_nproc" },
  72: #define X_NPROC     7
  73:     { "_dmmin" },
  74: #define X_DMMIN     8
  75:     { "_dmmax" },
  76: #define X_DMMAX     9
  77:     { "" },
  78: };
  79: 
  80: FILE    *ps;
  81: FILE    *ut;
  82: FILE    *bootfd;
  83: int kmem;
  84: int mem;
  85: int swap;           /* /dev/kmem, mem, and swap */
  86: int nswap;
  87: int dmmin, dmmax;
  88: dev_t   tty;
  89: int uid;
  90: char    doing[520];     /* process attached to terminal */
  91: time_t  proctime;       /* cpu time of process in doing */
  92: double  avenrun[3];
  93: struct  proc *aproc;
  94: 
  95: #define DIV60(t)    ((t+30)/60)    /* x/60 rounded */
  96: #define TTYEQ       (tty == pr[i].w_tty && uid == pr[i].w_uid)
  97: #define IGINT       (1+3*1)     /* ignoring both SIGINT & SIGQUIT */
  98: 
  99: char    *getargs();
 100: char    *fread();
 101: char    *ctime();
 102: char    *rindex();
 103: FILE    *popen();
 104: struct  tm *localtime();
 105: time_t  findidle();
 106: 
 107: int debug;          /* true if -d flag: debugging output */
 108: int header = 1;     /* true if -h flag: don't print heading */
 109: int lflag = 1;      /* true if -l flag: long style output */
 110: int login;          /* true if invoked as login shell */
 111: time_t  idle;           /* number of minutes user is idle */
 112: int nusers;         /* number of users logged in now */
 113: char *  sel_user;       /* login of particular user selected */
 114: char firstchar;         /* first char of name of prog invoked as */
 115: time_t  jobtime;        /* total cpu time visible */
 116: time_t  now;            /* the current time of day */
 117: struct  timeval boottime;
 118: time_t  uptime;         /* time of last reboot & elapsed time since */
 119: int np;         /* number of processes currently active */
 120: struct  utmp utmp;
 121: struct  proc mproc;
 122: union {
 123:     struct user U_up;
 124:     char    pad[NBPG][UPAGES];
 125: } Up;
 126: #define up  Up.U_up
 127: 
 128: main(argc, argv)
 129:     char **argv;
 130: {
 131:     int days, hrs, mins;
 132:     register int i, j;
 133:     char *cp;
 134:     register int curpid, empty;
 135: 
 136:     login = (argv[0][0] == '-');
 137:     cp = rindex(argv[0], '/');
 138:     firstchar = login ? argv[0][1] : (cp==0) ? argv[0][0] : cp[1];
 139:     cp = argv[0];   /* for Usage */
 140: 
 141:     while (argc > 1) {
 142:         if (argv[1][0] == '-') {
 143:             for (i=1; argv[1][i]; i++) {
 144:                 switch(argv[1][i]) {
 145: 
 146:                 case 'd':
 147:                     debug++;
 148:                     break;
 149: 
 150:                 case 'h':
 151:                     header = 0;
 152:                     break;
 153: 
 154:                 case 'l':
 155:                     lflag++;
 156:                     break;
 157: 
 158:                 case 's':
 159:                     lflag = 0;
 160:                     break;
 161: 
 162:                 case 'u':
 163:                 case 'w':
 164:                     firstchar = argv[1][i];
 165:                     break;
 166: 
 167:                 default:
 168:                     printf("Bad flag %s\n", argv[1]);
 169:                     exit(1);
 170:                 }
 171:             }
 172:         } else {
 173:             if (!isalnum(argv[1][0]) || argc > 2) {
 174:                 printf("Usage: %s [ -hlsuw ] [ user ]\n", cp);
 175:                 exit(1);
 176:             } else
 177:                 sel_user = argv[1];
 178:         }
 179:         argc--; argv++;
 180:     }
 181: 
 182:     if ((kmem = open("/dev/kmem", 0)) < 0) {
 183:         fprintf(stderr, "No kmem\n");
 184:         exit(1);
 185:     }
 186:     nlist("/vmunix", nl);
 187:     if (nl[0].n_type==0) {
 188:         fprintf(stderr, "No namelist\n");
 189:         exit(1);
 190:     }
 191: 
 192:     if (firstchar != 'u')
 193:         readpr();
 194: 
 195:     ut = fopen("/etc/utmp","r");
 196:     time(&now);
 197:     if (header) {
 198:         /* Print time of day */
 199:         prtat(&now);
 200: 
 201:         /*
 202: 		 * Print how long system has been up.
 203: 		 * (Found by looking for "boottime" in kernel)
 204: 		 */
 205:         lseek(kmem, (long)nl[X_BOOTTIME].n_value, 0);
 206:         read(kmem, &boottime, sizeof (boottime));
 207: 
 208:         uptime = now - boottime.tv_sec;
 209:         uptime += 30;
 210:         days = uptime / (60*60*24);
 211:         uptime %= (60*60*24);
 212:         hrs = uptime / (60*60);
 213:         uptime %= (60*60);
 214:         mins = uptime / 60;
 215: 
 216:         printf("  up");
 217:         if (days > 0)
 218:             printf(" %d day%s,", days, days>1?"s":"");
 219:         if (hrs > 0 && mins > 0) {
 220:             printf(" %2d:%02d,", hrs, mins);
 221:         } else {
 222:             if (hrs > 0)
 223:                 printf(" %d hr%s,", hrs, hrs>1?"s":"");
 224:             if (mins > 0)
 225:                 printf(" %d min%s,", mins, mins>1?"s":"");
 226:         }
 227: 
 228:         /* Print number of users logged in to system */
 229:         while (fread(&utmp, sizeof(utmp), 1, ut)) {
 230:             if (utmp.ut_name[0] != '\0')
 231:                 nusers++;
 232:         }
 233:         rewind(ut);
 234:         printf("  %d user%s", nusers, nusers>1?"s":"");
 235: 
 236:         /*
 237: 		 * Print 1, 5, and 15 minute load averages.
 238: 		 * (Found by looking in kernel for avenrun).
 239: 		 */
 240:         printf(",  load average:");
 241:         lseek(kmem, (long)nl[X_AVENRUN].n_value, 0);
 242:         read(kmem, avenrun, sizeof(avenrun));
 243:         for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) {
 244:             if (i > 0)
 245:                 printf(",");
 246:             printf(" %.2f", avenrun[i]);
 247:         }
 248:         printf("\n");
 249:         if (firstchar == 'u')
 250:             exit(0);
 251: 
 252:         /* Headers for rest of output */
 253:         if (lflag)
 254:             printf("User     tty       login@  idle   JCPU   PCPU  what\n");
 255:         else
 256:             printf("User    tty  idle  what\n");
 257:         fflush(stdout);
 258:     }
 259: 
 260: 
 261:     for (;;) {  /* for each entry in utmp */
 262:         if (fread(&utmp, sizeof(utmp), 1, ut) == NULL) {
 263:             fclose(ut);
 264:             exit(0);
 265:         }
 266:         if (utmp.ut_name[0] == '\0')
 267:             continue;   /* that tty is free */
 268:         if (sel_user && strcmpn(utmp.ut_name, sel_user, NMAX) != 0)
 269:             continue;   /* we wanted only somebody else */
 270: 
 271:         gettty();
 272:         jobtime = 0;
 273:         proctime = 0;
 274:         strcpy(doing, "-"); /* default act: normally never prints */
 275:         empty = 1;
 276:         curpid = -1;
 277:         idle = findidle();
 278:         for (i=0; i<np; i++) {  /* for each process on this tty */
 279:             if (!(TTYEQ))
 280:                 continue;
 281:             jobtime += pr[i].w_time + pr[i].w_ctime;
 282:             proctime += pr[i].w_time;
 283:             /*
 284: 			 * Meaning of debug fields following proc name is:
 285: 			 * & by itself: ignoring both SIGINT and QUIT.
 286: 			 *		(==> this proc is not a candidate.)
 287: 			 * & <i> <q>:   i is SIGINT status, q is quit.
 288: 			 *		0 == DFL, 1 == IGN, 2 == caught.
 289: 			 * *:		proc pgrp == tty pgrp.
 290: 			 */
 291:              if (debug) {
 292:                 printf("\t\t%d\t%s", pr[i].w_pid, pr[i].w_args);
 293:                 if ((j=pr[i].w_igintr) > 0)
 294:                     if (j==IGINT)
 295:                         printf(" &");
 296:                     else
 297:                         printf(" & %d %d", j%3, j/3);
 298:                 printf("\n");
 299:             }
 300:             if (empty && pr[i].w_igintr!=IGINT) {
 301:                 empty = 0;
 302:                 curpid = -1;
 303:             }
 304:             if(pr[i].w_pid>curpid && (pr[i].w_igintr!=IGINT || empty)){
 305:                 curpid = pr[i].w_pid;
 306:                 strcpy(doing, lflag ? pr[i].w_args : pr[i].w_comm);
 307: #ifdef notdef
 308:                 if (doing[0]==0 || doing[0]=='-' && doing[1]<=' ' || doing[0] == '?') {
 309:                     strcat(doing, " (");
 310:                     strcat(doing, pr[i].w_comm);
 311:                     strcat(doing, ")");
 312:                 }
 313: #endif
 314:             }
 315:         }
 316:         putline();
 317:     }
 318: }
 319: 
 320: /* figure out the major/minor device # pair for this tty */
 321: gettty()
 322: {
 323:     char ttybuf[20];
 324:     struct stat statbuf;
 325: 
 326:     ttybuf[0] = 0;
 327:     strcpy(ttybuf, "/dev/");
 328:     strcat(ttybuf, utmp.ut_line);
 329:     stat(ttybuf, &statbuf);
 330:     tty = statbuf.st_rdev;
 331:     uid = statbuf.st_uid;
 332: }
 333: 
 334: /*
 335:  * putline: print out the accumulated line of info about one user.
 336:  */
 337: putline()
 338: {
 339:     register int tm;
 340: 
 341:     /* print login name of the user */
 342:     printf("%-*.*s ", NMAX, NMAX, utmp.ut_name);
 343: 
 344:     /* print tty user is on */
 345:     if (lflag)
 346:         /* long form: all (up to) LMAX chars */
 347:         printf("%-*.*s", LMAX, LMAX, utmp.ut_line);
 348:     else {
 349:         /* short form: 2 chars, skipping 'tty' if there */
 350:         if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y')
 351:             printf("%-2.2s", &utmp.ut_line[3]);
 352:         else
 353:             printf("%-2.2s", utmp.ut_line);
 354:     }
 355: 
 356:     if (lflag)
 357:         /* print when the user logged in */
 358:         prtat(&utmp.ut_time);
 359: 
 360:     /* print idle time */
 361:     if (idle >= 36 * 60)
 362:         printf("%2ddays ", (idle + 12 * 60) / (24 * 60));
 363:     else
 364:         prttime(idle," ");
 365: 
 366:     if (lflag) {
 367:         /* print CPU time for all processes & children */
 368:         prttime(jobtime," ");
 369:         /* print cpu time for interesting process */
 370:         prttime(proctime," ");
 371:     }
 372: 
 373:     /* what user is doing, either command tail or args */
 374:     printf(" %-.32s\n",doing);
 375:     fflush(stdout);
 376: }
 377: 
 378: /* find & return number of minutes current tty has been idle */
 379: findidle()
 380: {
 381:     struct stat stbuf;
 382:     long lastaction, diff;
 383:     char ttyname[20];
 384: 
 385:     strcpy(ttyname, "/dev/");
 386:     strcatn(ttyname, utmp.ut_line, LMAX);
 387:     stat(ttyname, &stbuf);
 388:     time(&now);
 389:     lastaction = stbuf.st_atime;
 390:     diff = now - lastaction;
 391:     diff = DIV60(diff);
 392:     if (diff < 0) diff = 0;
 393:     return(diff);
 394: }
 395: 
 396: #define HR  (60 * 60)
 397: #define DAY (24 * HR)
 398: #define MON (30 * DAY)
 399: 
 400: /*
 401:  * prttime prints a time in hours and minutes or minutes and seconds.
 402:  * The character string tail is printed at the end, obvious
 403:  * strings to pass are "", " ", or "am".
 404:  */
 405: prttime(tim, tail)
 406:     time_t tim;
 407:     char *tail;
 408: {
 409: 
 410:     if (tim >= 60) {
 411:         printf("%3d:", tim/60);
 412:         tim %= 60;
 413:         printf("%02d", tim);
 414:     } else if (tim > 0)
 415:         printf("    %2d", tim);
 416:     else
 417:         printf("      ");
 418:     printf("%s", tail);
 419: }
 420: 
 421: char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
 422: char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
 423:         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 424: 
 425: /* prtat prints a 12 hour time given a pointer to a time of day */
 426: prtat(time)
 427:     long *time;
 428: {
 429:     struct tm *p;
 430:     register int hr, pm;
 431: 
 432:     p = localtime(time);
 433:     hr = p->tm_hour;
 434:     pm = (hr > 11);
 435:     if (hr > 11)
 436:         hr -= 12;
 437:     if (hr == 0)
 438:         hr = 12;
 439:     if (now - *time <= 18 * HR)
 440:         prttime(hr * 60 + p->tm_min, pm ? "pm" : "am");
 441:     else if (now - *time <= 7 * DAY)
 442:         printf(" %s%2d%s", weekday[p->tm_wday], hr, pm ? "pm" : "am");
 443:     else
 444:         printf(" %2d%s%2d", p->tm_mday, month[p->tm_mon], p->tm_year);
 445: }
 446: 
 447: /*
 448:  * readpr finds and reads in the array pr, containing the interesting
 449:  * parts of the proc and user tables for each live process.
 450:  */
 451: readpr()
 452: {
 453:     int pn, mf, addr, c;
 454:     int szpt, pfnum, i;
 455:     struct pte *Usrptma, *usrpt, *pte, apte;
 456:     struct dblock db;
 457: 
 458:     Usrptma = (struct pte *) nl[X_USRPTMA].n_value;
 459:     usrpt = (struct pte *) nl[X_USRPT].n_value;
 460:     if((mem = open("/dev/mem", 0)) < 0) {
 461:         fprintf(stderr, "No mem\n");
 462:         exit(1);
 463:     }
 464:     if ((swap = open("/dev/drum", 0)) < 0) {
 465:         fprintf(stderr, "No drum\n");
 466:         exit(1);
 467:     }
 468:     /*
 469: 	 * read mem to find swap dev.
 470: 	 */
 471:     lseek(kmem, (long)nl[X_SWAPDEV].n_value, 0);
 472:     read(kmem, &nl[X_SWAPDEV].n_value, sizeof(nl[X_SWAPDEV].n_value));
 473:     /*
 474: 	 * Find base of and parameters of swap
 475: 	 */
 476:     lseek(kmem, (long)nl[X_NSWAP].n_value, 0);
 477:     read(kmem, &nswap, sizeof(nswap));
 478:     lseek(kmem, (long)nl[X_DMMIN].n_value, 0);
 479:     read(kmem, &dmmin, sizeof(dmmin));
 480:     lseek(kmem, (long)nl[X_DMMAX].n_value, 0);
 481:     read(kmem, &dmmax, sizeof(dmmax));
 482:     /*
 483: 	 * Locate proc table
 484: 	 */
 485:     lseek(kmem, (long)nl[X_NPROC].n_value, 0);
 486:     read(kmem, &nproc, sizeof(nproc));
 487:     pr = (struct pr *)calloc(nproc, sizeof (struct pr));
 488:     np = 0;
 489:     lseek(kmem, (long)nl[X_PROC].n_value, 0);
 490:     read(kmem, &aproc, sizeof(aproc));
 491:     for (pn=0; pn<nproc; pn++) {
 492:         lseek(kmem, (int)(aproc + pn), 0);
 493:         read(kmem, &mproc, sizeof mproc);
 494:         /* decide if it's an interesting process */
 495:         if (mproc.p_stat==0 || mproc.p_stat==SZOMB || mproc.p_pgrp==0)
 496:             continue;
 497:         /* find & read in the user structure */
 498:         if ((mproc.p_flag & SLOAD) == 0) {
 499:             /* not in memory - get from swap device */
 500:             addr = dtob(mproc.p_swaddr);
 501:             lseek(swap, (long)addr, 0);
 502:             if (read(swap, &up, sizeof(up)) != sizeof(up)) {
 503:                 continue;
 504:             }
 505:         } else {
 506:             int p0br, cc;
 507: #define INTPPG (NBPG / sizeof (int))
 508:             struct pte pagetbl[NBPG / sizeof (struct pte)];
 509:             /* loaded, get each page from memory separately */
 510:             szpt = mproc.p_szpt;
 511:             p0br = (int)mproc.p_p0br;
 512:             pte = &Usrptma[btokmx(mproc.p_p0br) + szpt-1];
 513:             lseek(kmem, (long)pte, 0);
 514:             if (read(kmem, &apte, sizeof(apte)) != sizeof(apte))
 515:                 continue;
 516:             lseek(mem, ctob(apte.pg_pfnum), 0);
 517:             if (read(mem,pagetbl,sizeof(pagetbl)) != sizeof(pagetbl))
 518: cont:
 519:                 continue;
 520:             for(cc=0; cc<UPAGES; cc++) {    /* get u area */
 521:                 int upage = pagetbl[NPTEPG-UPAGES+cc].pg_pfnum;
 522:                 lseek(mem,ctob(upage),0);
 523:                 if (read(mem,((int *)&up)+INTPPG*cc,NBPG) != NBPG)
 524:                     goto cont;
 525:             }
 526:             szpt = up.u_pcb.pcb_szpt;
 527:             pr[np].w_seekaddr = ctob(apte.pg_pfnum);
 528:         }
 529:         vstodb(0, CLSIZE, &up.u_smap, &db, 1);
 530:         pr[np].w_lastpg = dtob(db.db_base);
 531:         if (up.u_ttyp == NULL)
 532:             continue;
 533: 
 534:         /* save the interesting parts */
 535:         pr[np].w_pid = mproc.p_pid;
 536:         pr[np].w_flag = mproc.p_flag;
 537:         pr[np].w_size = mproc.p_dsize + mproc.p_ssize;
 538:         pr[np].w_igintr = (((int)up.u_signal[2]==1) +
 539:             2*((int)up.u_signal[2]>1) + 3*((int)up.u_signal[3]==1)) +
 540:             6*((int)up.u_signal[3]>1);
 541:         pr[np].w_time =
 542:             up.u_ru.ru_utime.tv_sec + up.u_ru.ru_stime.tv_sec;
 543:         pr[np].w_ctime =
 544:             up.u_cru.ru_utime.tv_sec + up.u_cru.ru_stime.tv_sec;
 545:         pr[np].w_tty = up.u_ttyd;
 546:         pr[np].w_uid = mproc.p_uid;
 547:         up.u_comm[14] = 0;  /* Bug: This bombs next field. */
 548:         strcpy(pr[np].w_comm, up.u_comm);
 549:         /*
 550: 		 * Get args if there's a chance we'll print it.
 551: 		 * Cant just save pointer: getargs returns static place.
 552: 		 * Cant use strcpyn: that crock blank pads.
 553: 		 */
 554:         pr[np].w_args[0] = 0;
 555:         strcatn(pr[np].w_args,getargs(&pr[np]),ARGWIDTH);
 556:         if (pr[np].w_args[0]==0 || pr[np].w_args[0]=='-' && pr[np].w_args[1]<=' ' || pr[np].w_args[0] == '?') {
 557:             strcat(pr[np].w_args, " (");
 558:             strcat(pr[np].w_args, pr[np].w_comm);
 559:             strcat(pr[np].w_args, ")");
 560:         }
 561:         np++;
 562:     }
 563: }
 564: 
 565: /*
 566:  * getargs: given a pointer to a proc structure, this looks at the swap area
 567:  * and tries to reconstruct the arguments. This is straight out of ps.
 568:  */
 569: char *
 570: getargs(p)
 571:     struct pr *p;
 572: {
 573:     int c, addr, nbad;
 574:     static int abuf[CLSIZE*NBPG/sizeof(int)];
 575:     struct pte pagetbl[NPTEPG];
 576:     register int *ip;
 577:     register char *cp, *cp1;
 578: 
 579:     if ((p->w_flag & SLOAD) == 0) {
 580:         lseek(swap, p->w_lastpg, 0);
 581:         if (read(swap, abuf, sizeof(abuf)) != sizeof(abuf))
 582:             return(p->w_comm);
 583:     } else {
 584:         c = p->w_seekaddr;
 585:         lseek(mem,c,0);
 586:         if (read(mem,pagetbl,NBPG) != NBPG)
 587:             return(p->w_comm);
 588:         if (pagetbl[NPTEPG-CLSIZE-UPAGES].pg_fod==0 && pagetbl[NPTEPG-CLSIZE-UPAGES].pg_pfnum) {
 589:             lseek(mem,ctob(pagetbl[NPTEPG-CLSIZE-UPAGES].pg_pfnum),0);
 590:             if (read(mem,abuf,sizeof(abuf)) != sizeof(abuf))
 591:                 return(p->w_comm);
 592:         } else {
 593:             lseek(swap, p->w_lastpg, 0);
 594:             if (read(swap, abuf, sizeof(abuf)) != sizeof(abuf))
 595:                 return(p->w_comm);
 596:         }
 597:     }
 598:     abuf[sizeof(abuf)/sizeof(abuf[0])-1] = 0;
 599:     for (ip = &abuf[sizeof(abuf)/sizeof(abuf[0])-2]; ip > abuf;) {
 600:         /* Look from top for -1 or 0 as terminator flag. */
 601:         if (*--ip == -1 || *ip == 0) {
 602:             cp = (char *)(ip+1);
 603:             if (*cp==0)
 604:                 cp++;
 605:             nbad = 0;   /* up to 5 funny chars as ?'s */
 606:             for (cp1 = cp; cp1 < (char *)&abuf[sizeof(abuf)/sizeof(abuf[0])]; cp1++) {
 607:                 c = *cp1&0177;
 608:                 if (c==0)  /* nulls between args => spaces */
 609:                     *cp1 = ' ';
 610:                 else if (c < ' ' || c > 0176) {
 611:                     if (++nbad >= 5) {
 612:                         *cp1++ = ' ';
 613:                         break;
 614:                     }
 615:                     *cp1 = '?';
 616:                 } else if (c=='=') {    /* Oops - found an
 617: 							 * environment var, back
 618: 							 * over & erase it. */
 619:                     *cp1 = 0;
 620:                     while (cp1>cp && *--cp1!=' ')
 621:                         *cp1 = 0;
 622:                     break;
 623:                 }
 624:             }
 625:             while (*--cp1==' ') /* strip trailing spaces */
 626:                 *cp1 = 0;
 627:             return(cp);
 628:         }
 629:     }
 630:     return (p->w_comm);
 631: }
 632: 
 633: /*
 634:  * Given a base/size pair in virtual swap area,
 635:  * return a physical base/size pair which is the
 636:  * (largest) initial, physically contiguous block.
 637:  */
 638: vstodb(vsbase, vssize, dmp, dbp, rev)
 639:     register int vsbase;
 640:     int vssize;
 641:     struct dmap *dmp;
 642:     register struct dblock *dbp;
 643: {
 644:     register int blk = dmmin;
 645:     register swblk_t *ip = dmp->dm_map;
 646: 
 647:     vsbase = ctod(vsbase);
 648:     vssize = ctod(vssize);
 649:     if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
 650:         panic("vstodb");
 651:     while (vsbase >= blk) {
 652:         vsbase -= blk;
 653:         if (blk < dmmax)
 654:             blk *= 2;
 655:         ip++;
 656:     }
 657:     if (*ip <= 0 || *ip + blk > nswap)
 658:         panic("vstodb *ip");
 659:     dbp->db_size = min(vssize, blk - vsbase);
 660:     dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
 661: }
 662: 
 663: panic(cp)
 664:     char *cp;
 665: {
 666: 
 667:     /* printf("%s\n", cp); */
 668: }
 669: 
 670: min(a, b)
 671: {
 672: 
 673:     return (a < b ? a : b);
 674: }

Defined functions

findidle defined in line 379; used 2 times
getargs defined in line 569; used 2 times
gettty defined in line 321; used 1 times
main defined in line 128; never used
min defined in line 670; used 1 times
panic defined in line 663; used 2 times
prtat defined in line 426; used 2 times
prttime defined in line 405; used 4 times
putline defined in line 337; used 1 times
readpr defined in line 451; used 1 times
vstodb defined in line 638; used 1 times

Defined variables

aproc defined in line 93; used 3 times
avenrun defined in line 92; used 5 times
boottime defined in line 117; used 3 times
copyright defined in line 8; never used
debug defined in line 107; used 2 times
dmmax defined in line 87; used 3 times
dmmin defined in line 87; used 3 times
doing defined in line 90; used 10 times
firstchar defined in line 114; used 4 times
header defined in line 108; used 2 times
kmem defined in line 83; used 21 times
lflag defined in line 109; used 7 times
login defined in line 110; used 2 times
mem defined in line 84; used 9 times
month defined in line 422; used 1 times
mproc defined in line 121; used 15 times
nl defined in line 56; used 14 times
np defined in line 119; used 25 times
nproc defined in line 54; used 4 times
nswap defined in line 86; used 3 times
nusers defined in line 112; used 3 times
pr defined in line 53; used 38 times
sccsid defined in line 14; never used
sel_user defined in line 113; used 3 times
swap defined in line 85; used 7 times
uid defined in line 89; used 2 times
utmp defined in line 120; used 19 times
weekday defined in line 421; used 1 times

Defined struct's

pr defined in line 40; used 6 times

Defined macros

ARGWIDTH defined in line 38; used 2 times
DAY defined in line 397; used 2 times
DIV60 defined in line 95; used 1 times
HR defined in line 396; used 2 times
IGINT defined in line 97; used 3 times
INTPPG defined in line 507; used 1 times
LMAX defined in line 36; used 3 times
MON defined in line 398; never used
NMAX defined in line 35; used 3 times
TTYEQ defined in line 96; used 1 times
X_AVENRUN defined in line 68; used 1 times
X_BOOTTIME defined in line 70; used 1 times
X_DMMAX defined in line 76; used 1 times
X_DMMIN defined in line 74; used 1 times
X_NPROC defined in line 72; used 1 times
X_NSWAP defined in line 66; used 1 times
X_PROC defined in line 58; used 1 times
X_SWAPDEV defined in line 60; used 3 times
X_USRPT defined in line 64; used 1 times
X_USRPTMA defined in line 62; used 1 times
up defined in line 126; used 18 times
Last modified: 1986-02-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2341
Valid CSS Valid XHTML 1.0 Strict