1: /*
   2:  * w - print system status (who and what)
   3:  *
   4:  * This program is similar to the systat command on Tenex/Tops 10/20
   5:  * It needs read permission on /dev/mem and /dev/swap.
   6:  *
   7:  * PDP-11 V7 version that does not run off ps -r.
   8:  */
   9: #include <whoami.h>
  10: #include <a.out.h>
  11: #include <core.h>
  12: #include <stdio.h>
  13: #include <ctype.h>
  14: #include <utmp.h>
  15: #include <time.h>
  16: #include <sys/param.h>
  17: #include <sys/stat.h>
  18: #include <sys/proc.h>
  19: #include <sys/dir.h>
  20: #include <sys/user.h>
  21: #include <sys/tty.h>
  22: 
  23: #define ARGWIDTH    33  /* # chars left on 80 col crt for args */
  24: #define ARGLIST 1024    /* amount of stack to examine for argument list */
  25: 
  26: struct smproc {
  27:     long    w_addr;         /* address in file for args */
  28:     short   w_pid;          /* proc.p_pid */
  29:     int w_igintr;       /* INTR+3*QUIT, 0=die, 1=ign, 2=catch */
  30:     time_t  w_time;         /* CPU time used by this process */
  31:     time_t  w_ctime;        /* CPU time used by children */
  32:     dev_t   w_tty;          /* tty device of process */
  33:     char    w_comm[15];     /* user.u_comm, null terminated */
  34:     char    w_args[ARGWIDTH+1]; /* args if interesting process */
  35: } *pr;
  36: 
  37: struct  nlist nl[] = {
  38:     { "_proc" },
  39: #define X_PROC      0
  40:     { "_swapdev" },
  41: #define X_SWAPDEV   1
  42:     { "_swplo" },
  43: #define X_SWPLO     2
  44:     { "_avenrun" },
  45: #define X_AVENRUN   3
  46:     { "_bootime" },
  47: #define X_BOOTIME   4
  48:     { "_nproc" },
  49: #define X_NPROC     5
  50:     { 0 },
  51: };
  52: 
  53: FILE    *ps;
  54: FILE    *ut;
  55: FILE    *bootfd;
  56: int swmem;
  57: int mem;
  58: int swap;           /* /dev/mem, mem, and swap */
  59: int nswap;
  60: int file;
  61: dev_t   tty;
  62: char    doing[520];     /* process attached to terminal */
  63: time_t  proctime;       /* cpu time of process in doing */
  64: short   avenrun[3];
  65: double  load[3];
  66: 
  67: #define DIV60(t)    ((t+30)/60)    /* x/60 rounded */
  68: #define TTYEQ       (tty == pr[i].w_tty)
  69: #define IGINT       (1+3*1)     /* ignoring both SIGINT & SIGQUIT */
  70: 
  71: long    round();
  72: char    *getargs();
  73: char    *fread();
  74: char    *ctime();
  75: char    *rindex();
  76: char    *getptr();
  77: FILE    *popen();
  78: struct  tm *localtime();
  79: 
  80: int debug;          /* true if -d flag: debugging output */
  81: int header = 1;     /* true if -h flag: don't print heading */
  82: int lflag = 1;      /* true if -l flag: long style output */
  83: int login;          /* true if invoked as login shell */
  84: time_t  idle;           /* number of minutes user is idle */
  85: int nusers;         /* number of users logged in now */
  86: char *  sel_user;       /* login of particular user selected */
  87: char firstchar;         /* first char of name of prog invoked as */
  88: time_t  jobtime;        /* total cpu time visible */
  89: time_t  now;            /* the current time of day */
  90: struct  tm *nowt;       /* current time as time struct */
  91: time_t  bootime, uptime;    /* time of last reboot & elapsed time since */
  92: int np;         /* number of processes currently active */
  93: struct  utmp utmp;
  94: struct  proc mproc;
  95: struct  user up;
  96: char    fill[512];
  97: 
  98: struct map {
  99:     long    b1, e1; long f1;
 100:     long    b2, e2; long f2;
 101: };
 102: struct map datmap;
 103: 
 104: main(argc, argv)
 105:     char **argv;
 106: {
 107:     int days, hrs, mins;
 108:     register int i, j;
 109:     char *cp;
 110:     register int curpid, empty;
 111:     extern char _sobuf[];
 112: 
 113:     setbuf(stdout, _sobuf);
 114:     login = (argv[0][0] == '-');
 115:     cp = rindex(argv[0], '/');
 116:     firstchar = login ? argv[0][1] : (cp==0) ? argv[0][0] : cp[1];
 117:     cp = argv[0];   /* for Usage */
 118: 
 119:     while (argc > 1) {
 120:         if (argv[1][0] == '-') {
 121:             for (i=1; argv[1][i]; i++) {
 122:                 switch(argv[1][i]) {
 123: 
 124:                 case 'd':
 125:                     debug++;
 126:                     break;
 127: 
 128:                 case 'h':
 129:                     header = 0;
 130:                     break;
 131: 
 132:                 case 'l':
 133:                     lflag++;
 134:                     break;
 135: 
 136:                 case 's':
 137:                     lflag = 0;
 138:                     break;
 139: 
 140:                 case 'u':
 141:                 case 'w':
 142:                     firstchar = argv[1][1];
 143:                     break;
 144: 
 145:                 default:
 146:                     printf("Bad flag %s\n", argv[1]);
 147:                     exit(1);
 148:                 }
 149:             }
 150:         } else {
 151:             if (!isalnum(argv[1][0]) || argc > 2) {
 152:                 printf("Usage: %s [ -hlsuw ] [ user ]\n", cp);
 153:                 exit(1);
 154:             } else
 155:                 sel_user = argv[1];
 156:         }
 157:         argc--; argv++;
 158:     }
 159: 
 160:     if ((mem = open("/dev/kmem", 0)) < 0) {
 161:         fprintf(stderr, "No mem\n");
 162:         exit(1);
 163:     }
 164:     nlist("/unix", nl);
 165:     if (nl[0].n_type==0) {
 166:         fprintf(stderr, "No namelist\n");
 167:         exit(1);
 168:     }
 169: 
 170:     if (firstchar != 'u')
 171:         readpr();
 172: 
 173:     ut = fopen("/etc/utmp","r");
 174:     if (header) {
 175:         /* Print time of day */
 176:         time(&now);
 177:         nowt = localtime(&now);
 178:         prtat(nowt);
 179: 
 180:         if (nl[X_BOOTIME].n_type > 0) {
 181:             /*
 182: 			 * Print how long system has been up.
 183: 			 * (Found by looking for "bootime" in kernel)
 184: 			 */
 185:             lseek(mem, (long)nl[X_BOOTIME].n_value, 0);
 186:             read(mem, &bootime, sizeof (bootime));
 187: 
 188:             uptime = now - bootime;
 189:             days = uptime / (60L*60L*24L);
 190:             uptime %= (60L*60L*24L);
 191:             hrs = uptime / (60L*60L);
 192:             uptime %= (60L*60L);
 193:             mins = DIV60(uptime);
 194: 
 195:             printf("  up");
 196:             if (days > 0)
 197:                 printf(" %d day%s,", days, days>1?"s":"");
 198:             if (hrs > 0 && mins > 0) {
 199:                 printf(" %2d:%02d,", hrs, mins);
 200:             } else {
 201:                 if (hrs > 0)
 202:                     printf(" %d hr%s,", hrs, hrs>1?"s":"");
 203:                 if (mins > 0)
 204:                     printf(" %d min%s,", mins, mins>1?"s":"");
 205:             }
 206:         }
 207: 
 208:         /* Print number of users logged in to system */
 209:         while (fread(&utmp, sizeof(utmp), 1, ut)) {
 210:             if (utmp.ut_name[0] != '\0')
 211:                 nusers++;
 212:         }
 213:         rewind(ut);
 214:         printf("  %d user%c", nusers, nusers > 1 ?  's' : '\0');
 215: 
 216:         if (nl[X_AVENRUN].n_type > 0) {
 217:             /*
 218: 			 * Print 1, 5, and 15 minute load averages.
 219: 			 * (Found by looking in kernel for avenrun).
 220: 			 */
 221:             printf(",  load average:");
 222:             lseek(mem, (long)nl[X_AVENRUN].n_value, 0);
 223:             read(mem, avenrun, sizeof(avenrun));
 224:             for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) {
 225:                 load[i] = avenrun[i] / 256.0;
 226:                 if (i > 0)
 227:                     printf(",");
 228:                 printf(" %.2f", load[i]);
 229:             }
 230:         }
 231:         printf("\n");
 232:         if (firstchar == 'u')
 233:             exit(0);
 234: 
 235:         /* Headers for rest of output */
 236:         if (lflag)
 237:             printf("User     tty       login@  idle   JCPU   PCPU  what\n");
 238:         else
 239:             printf("User     tty   idle  what\n");
 240:         fflush(stdout);
 241:     }
 242: 
 243: 
 244:     for (;;) {  /* for each entry in utmp */
 245:         if (fread(&utmp, sizeof(utmp), 1, ut) == NULL) {
 246:             fclose(ut);
 247:             exit(0);
 248:         }
 249:         if (utmp.ut_name[0] == '\0')
 250:             continue;   /* that tty is free */
 251:         if (sel_user && strncmp(utmp.ut_name, sel_user, 8) != 0)
 252:             continue;   /* we wanted only somebody else */
 253: 
 254:         gettty();
 255:         jobtime = 0;
 256:         proctime = 0;
 257:         strcpy(doing, "-"); /* default act: normally never prints */
 258:         empty = 1;
 259:         curpid = -1;
 260:         idle = findidle();
 261:         for (i=0; i<np; i++) {  /* for each process on this tty */
 262:             if (!(TTYEQ))
 263:                 continue;
 264:             jobtime += pr[i].w_time + pr[i].w_ctime;
 265:             proctime += pr[i].w_time;
 266:             if (debug) {
 267:                 printf("\t\t%d\t%s", pr[i].w_pid, pr[i].w_args);
 268:                 if ((j=pr[i].w_igintr) > 0)
 269:                     if (j==IGINT)
 270:                         printf(" &");
 271:                     else
 272:                         printf(" & %d %d", j%3, j/3);
 273:                 printf("\n");
 274:             }
 275:             if (empty && pr[i].w_igintr!=IGINT) {
 276:                 empty = 0;
 277:                 curpid = -1;
 278:             }
 279:             if(pr[i].w_pid>curpid && (pr[i].w_igintr!=IGINT || empty)){
 280:                 curpid = pr[i].w_pid;
 281:                 strcpy(doing, lflag ? pr[i].w_args : pr[i].w_comm);
 282:                 if (doing[0]==0 || doing[0]=='-' && doing[1]<=' ' || doing[0] == '?') {
 283:                     strcat(doing, " (");
 284:                     strcat(doing, pr[i].w_comm);
 285:                     strcat(doing, ")");
 286:                 }
 287:             }
 288:         }
 289:         putline();
 290:     }
 291: }
 292: 
 293: /* figure out the major/minor device # pair for this tty */
 294: gettty()
 295: {
 296:     char ttybuf[20];
 297:     struct stat statbuf;
 298: 
 299:     ttybuf[0] = 0;
 300:     strcpy(ttybuf, "/dev/");
 301:     strcat(ttybuf, utmp.ut_line);
 302:     stat(ttybuf, &statbuf);
 303:     tty = statbuf.st_rdev;
 304: }
 305: 
 306: /*
 307:  * putline: print out the accumulated line of info about one user.
 308:  */
 309: putline()
 310: {
 311:     register int tm;
 312: 
 313:     /* print login name of the user */
 314:     printf("%-8.8s ", utmp.ut_name);
 315: 
 316:     /* print tty user is on */
 317:     if (lflag)
 318:         /* long form: all (up to) 8 chars */
 319:         printf("%-8.8s", utmp.ut_line);
 320:     else {
 321:         /* short form: 4 chars, skipping 'tty' if there */
 322:         if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y')
 323:             printf("%-4.4s", &utmp.ut_line[3]);
 324:         else
 325:             printf("%-4.4s", utmp.ut_line);
 326:     }
 327: 
 328:     if (lflag)
 329:         /* print when the user logged in */
 330:         prtat(localtime(&utmp.ut_time));
 331: 
 332:     /* print idle time */
 333:     prttime(idle," ");
 334: 
 335:     if (lflag) {
 336:         /* print CPU time for all processes & children */
 337:         prttime(DIV60(jobtime)," ");
 338:         /* print cpu time for interesting process */
 339:         prttime(DIV60(proctime)," ");
 340:     }
 341: 
 342:     /* what user is doing, either command tail or args */
 343:     printf(" %-.32s\n",doing);
 344:     fflush(stdout);
 345: }
 346: 
 347: /* find & return number of minutes current tty has been idle */
 348: findidle()
 349: {
 350:     struct stat stbuf;
 351:     long lastaction, diff;
 352:     char ttyname[20];
 353: 
 354:     strcpy(ttyname, "/dev/");
 355:     strncat(ttyname, utmp.ut_line, 8);
 356:     stat(ttyname, &stbuf);
 357:     time(&now);
 358:     lastaction = stbuf.st_atime;
 359:     diff = now - lastaction;
 360:     diff = DIV60(diff);
 361:     if (diff < 0) diff = 0;
 362:     return(diff);
 363: }
 364: 
 365: /*
 366:  * prttime prints a time in hours and minutes.
 367:  * The character string tail is printed at the end, obvious
 368:  * strings to pass are "", " ", or "am".
 369:  */
 370: prttime(tim, tail)
 371:     time_t tim;
 372:     char *tail;
 373: {
 374:     register int didhrs = 0;
 375: 
 376:     if (tim >= 60) {
 377:         printf("%3ld:", tim/60);
 378:         didhrs++;
 379:     } else {
 380:         printf("    ");
 381:     }
 382:     tim %= 60;
 383:     if (tim > 0 || didhrs) {
 384:         printf(didhrs&&tim<10 ? "%02ld" : "%2ld", tim);
 385:     } else {
 386:         printf("  ");
 387:     }
 388:     printf("%s", tail);
 389: }
 390: 
 391: /* prtat prints a 12 hour time given a pointer to a time of day */
 392: prtat(p)
 393:     struct tm *p;
 394: {
 395:     register int pm;
 396:     register time_t t;
 397: 
 398:     t = p -> tm_hour;
 399:     pm = (t > 11);
 400:     if (t > 11)
 401:         t -= 12;
 402:     if (t == 0)
 403:         t = 12;
 404:     prttime(t*60 + p->tm_min, pm ? "pm" : "am");
 405: }
 406: 
 407: /*
 408:  * readpr finds and reads in the array pr, containing the interesting
 409:  * parts of the proc and user tables for each live process.
 410:  */
 411: readpr()
 412: {
 413:     int pn, mf, c, nproc;
 414:     int szpt, pfnum, i;
 415:     long addr;
 416: #ifdef  VIRUS_VFORK
 417:     long daddr, saddr;
 418: #endif
 419:     daddr_t swplo;
 420:     long txtsiz, datsiz, stksiz;
 421:     int septxt;
 422: 
 423:     if((swmem = open("/dev/mem", 0)) < 0) {
 424:         perror("/dev/mem");
 425:         exit(1);
 426:     }
 427:     if ((swap = open("/dev/swap", 0)) < 0) {
 428:         perror("/dev/swap");
 429:         exit(1);
 430:     }
 431:     /*
 432: 	 * read mem to find swap dev.
 433: 	 */
 434:     lseek(mem, (long)nl[X_SWAPDEV].n_value, 0);
 435:     read(mem, &nl[X_SWAPDEV].n_value, sizeof(nl[X_SWAPDEV].n_value));
 436:     /*
 437: 	 * Find base of swap
 438: 	 */
 439:     lseek(mem, (long)nl[X_SWPLO].n_value, 0);
 440:     read(mem, &swplo, sizeof(swplo));
 441:     if (nl[X_NPROC].n_value == 0) {
 442:         fprintf(stderr, "nproc not in namelist\n");
 443:         exit(1);
 444:     }
 445:     lseek (mem, (off_t) nl[X_NPROC].n_value, 0);
 446:     read(mem, (char *)&nproc, sizeof(nproc));
 447:     pr = (struct smproc *) malloc(nproc * sizeof(struct smproc));
 448:     if (pr == (struct smproc *)NULL) {
 449:         fprintf("Not enough memory for proc table\n");
 450:         exit(1);
 451:     }
 452:     /*
 453: 	 * Locate proc table
 454: 	 */
 455:     np = 0;
 456:     for (pn=0; pn<nproc; pn++) {
 457:         lseek(mem, (long)(nl[X_PROC].n_value + pn*(sizeof mproc)), 0);
 458:         pread(mem, &mproc, sizeof mproc, (long)(nl[X_PROC].n_value + pn*(sizeof mproc)));
 459:         /* decide if it's an interesting process */
 460:         if (mproc.p_stat==0 || mproc.p_pgrp==0)
 461:             continue;
 462: 
 463: #ifdef notdef
 464:         /*
 465: 		 * The following improves speed on systems with lots of ttys
 466: 		 * by skipping gettys and inits, but loses when root logs in.
 467: 		 */
 468:         if (mproc.p_ppid == 1 && mproc.p_uid == 0)
 469:             continue;
 470: #endif
 471:         /* find & read in the user structure */
 472:         if (mproc.p_flag&SLOAD) {
 473:             addr = ctob((long)mproc.p_addr);
 474: #ifdef  VIRUS_VFORK
 475:             daddr = ctob((long)mproc.p_daddr);
 476:             saddr = ctob((long)mproc.p_saddr);
 477: #endif
 478:             file = swmem;
 479:         } else {
 480:             addr = (mproc.p_addr+swplo)<<9;
 481: #ifdef  VIRUS_VFORK
 482:             daddr = (mproc.p_daddr+swplo)<<9;
 483:             saddr = (mproc.p_saddr+swplo)<<9;
 484: #endif
 485:             file = swap;
 486:         }
 487:         lseek(file, addr, 0);
 488:         if (pread(file, (char *)&up, sizeof(up), addr) != sizeof(up))
 489:             continue;
 490:         if (up.u_ttyp == NULL)
 491:             continue;
 492: 
 493:         /* set up address maps for user pcs */
 494:         txtsiz = ctob(up.u_tsize);
 495:         datsiz = ctob(up.u_dsize);
 496:         stksiz = ctob(up.u_ssize);
 497:         septxt = up.u_sep;
 498:         datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ));
 499:         datmap.e1 = datmap.b1+datsiz;
 500: #ifdef  VIRUS_VFORK
 501:         datmap.f1 = daddr;
 502: #else
 503:         datmap.f1 = ctob(USIZE)+addr;
 504: #endif
 505:         datmap.b2 = stackbas(stksiz);
 506:         datmap.e2 = stacktop(stksiz);
 507: #ifdef  VIRUS_VFORK
 508:         datmap.f2 = saddr;
 509: #else
 510:         datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr;
 511: #endif
 512: 
 513:         /* save the interesting parts */
 514: #ifdef  VIRUS_VFORK
 515:         pr[np].w_addr = saddr + ctob((long)mproc.p_ssize) - ARGLIST;
 516: #else
 517:         pr[np].w_addr = addr + ctob((long)mproc.p_size) - ARGLIST;
 518: #endif
 519:         pr[np].w_pid = mproc.p_pid;
 520:         pr[np].w_igintr = ((up.u_signal[2]==1) + 2*(up.u_signal[2]>1) + 3*(up.u_signal[3]==1)) + 6*(up.u_signal[3]>1);
 521:         pr[np].w_time = up.u_utime + up.u_stime;
 522:         pr[np].w_ctime = up.u_cutime + up.u_cstime;
 523:         pr[np].w_tty = up.u_ttyd;
 524:         up.u_comm[14] = 0;  /* Bug: This bombs next field. */
 525:         strcpy(pr[np].w_comm, up.u_comm);
 526:         /*
 527: 		 * Get args if there's a chance we'll print it.
 528: 		 * Cant just save pointer: getargs returns static place.
 529: 		 * Cant use strncpy: that crock blank pads.
 530: 		 */
 531:         pr[np].w_args[0] = 0;
 532:         strncat(pr[np].w_args,getargs(&pr[np]),ARGWIDTH);
 533:         if (pr[np].w_args[0]==0 || pr[np].w_args[0]=='-' && pr[np].w_args[1]<=' ' || pr[np].w_args[0] == '?') {
 534:             strcat(pr[np].w_args, " (");
 535:             strcat(pr[np].w_args, pr[np].w_comm);
 536:             strcat(pr[np].w_args, ")");
 537:         }
 538:         np++;
 539:     }
 540: }
 541: 
 542: /*
 543:  * getargs: given a pointer to a proc structure, this looks at the swap area
 544:  * and tries to reconstruct the arguments. This is straight out of ps.
 545:  */
 546: char *
 547: getargs(p)
 548:     struct smproc *p;
 549: {
 550:     int c, nbad;
 551:     static char abuf[ARGLIST];
 552:     register int *ip;
 553:     register char *cp, *cp1;
 554:     char **ap;
 555:     long addr;
 556: 
 557:     addr = p->w_addr;
 558: 
 559:     /* look for sh special */
 560:     lseek(file, addr+ARGLIST-sizeof(char **), 0);
 561:     if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *))
 562:         return(NULL);
 563:     if (ap) {
 564:         char *b = (char *) abuf;
 565:         char *bp = b;
 566:         while((cp=getptr(ap++)) && cp && (bp<b+ARGWIDTH) ) {
 567:             nbad = 0;
 568:             while((c=getbyte(cp++)) && (bp<b+ARGWIDTH)) {
 569:                 if (c<' ' || c>'~') {
 570:                     if (nbad++>3)
 571:                         break;
 572:                     continue;
 573:                 }
 574:                 *bp++ = c;
 575:             }
 576:             *bp++ = ' ';
 577:         }
 578:         *bp++ = 0;
 579:         return(b);
 580:     }
 581: 
 582:     lseek(file, addr, 0);
 583:     if (pread(file, abuf, sizeof(abuf), addr) != sizeof(abuf))
 584:         return(1);
 585:     for (ip = (int *) &abuf[ARGLIST]-2; ip > (int *) abuf;) {
 586:         /* Look from top for -1 or 0 as terminator flag. */
 587:         if (*--ip == -1 || *ip == 0) {
 588:             cp = (char *)(ip+1);
 589:             if (*cp==0)
 590:                 cp++;
 591:             nbad = 0;   /* up to 5 funny chars as ?'s */
 592:             for (cp1 = cp; cp1 < (char *)&abuf[ARGLIST]; cp1++) {
 593:                 c = *cp1&0177;
 594:                 if (c==0)  /* nulls between args => spaces */
 595:                     *cp1 = ' ';
 596:                 else if (c < ' ' || c > 0176) {
 597:                     if (++nbad >= 5) {
 598:                         *cp1++ = ' ';
 599:                         break;
 600:                     }
 601:                     *cp1 = '?';
 602:                 } else if (c=='=') {    /* Oops - found an
 603: 							 * environment var, back
 604: 							 * over & erase it. */
 605:                     *cp1 = 0;
 606:                     while (cp1>cp && *--cp1!=' ')
 607:                         *cp1 = 0;
 608:                     break;
 609:                 }
 610:             }
 611:             while (*--cp1==' ') /* strip trailing spaces */
 612:                 *cp1 = 0;
 613:             return(cp);
 614:         }
 615:     }
 616:     return (p->w_comm);
 617: }
 618: 
 619: min(a, b)
 620: {
 621: 
 622:     return (a < b ? a : b);
 623: }
 624: 
 625: char *
 626: getptr(adr)
 627: char **adr;
 628: {
 629:     char *ptr;
 630:     register char *p, *pa;
 631:     register i;
 632: 
 633:     ptr = 0;
 634:     pa = (char *)adr;
 635:     p = (char *)&ptr;
 636:     for (i=0; i<sizeof(ptr); i++)
 637:         *p++ = getbyte(pa++);
 638:     return(ptr);
 639: }
 640: 
 641: getbyte(adr)
 642: char *adr;
 643: {
 644:     register struct map *amap = &datmap;
 645:     char b;
 646:     long saddr;
 647: 
 648:     if(!within(adr, amap->b1, amap->e1)) {
 649:         if(within(adr, amap->b2, amap->e2)) {
 650:             saddr = (unsigned)adr + amap->f2 - amap->b2;
 651:         } else
 652:             return(0);
 653:     } else
 654:         saddr = (unsigned)adr + amap->f1 - amap->b1;
 655:     if(lseek(file, saddr, 0)==-1
 656:            || read(file, &b, 1)<1) {
 657:         return(0);
 658:     }
 659:     return((unsigned)b);
 660: }
 661: 
 662: 
 663: within(adr,lbd,ubd)
 664: char *adr;
 665: long lbd, ubd;
 666: {
 667:     return((unsigned)adr>=lbd && (unsigned)adr<ubd);
 668: }
 669: 
 670: long
 671: round(a, b)
 672:     long        a, b;
 673: {
 674:     long        w = ((a+b-1)/b)*b;
 675: 
 676:     return(w);
 677: }
 678: 
 679: /*
 680:  * pread is like read, but if it's /dev/mem we use the phys
 681:  * system call for speed.  (On systems without phys we have
 682:  * to use regular read.)
 683:  */
 684: pread(fd, ptr, nbytes, loc)
 685: char *ptr;
 686: long loc;
 687: {
 688:     int rc;
 689:     extern int errno;
 690: 
 691:     if (fd == swmem) {
 692:         rc=phys(6, nbytes/64+1, (short)(loc/64));
 693:         if (rc>=0) {
 694:             memcpy(ptr, 0140000, nbytes);
 695:             return nbytes;
 696:         } else {
 697:             return read(fd, ptr, nbytes);
 698:         }
 699:     } else {
 700:         return read(fd, ptr, nbytes);
 701:     }
 702: }
 703: 
 704: memcpy(dest, src, nbytes)
 705: register char *dest, *src;
 706: register int nbytes;
 707: {
 708:     while (nbytes--)
 709:         *dest++ = *src++;
 710: }

Defined functions

findidle defined in line 348; used 1 times
getargs defined in line 546; used 2 times
getbyte defined in line 641; used 2 times
getptr defined in line 625; used 2 times
gettty defined in line 294; used 1 times
main defined in line 104; never used
memcpy defined in line 704; used 1 times
min defined in line 619; never used
pread defined in line 684; used 3 times
prtat defined in line 392; used 2 times
prttime defined in line 370; used 4 times
putline defined in line 309; used 1 times
readpr defined in line 411; used 1 times
round defined in line 670; used 2 times
within defined in line 663; used 2 times

Defined variables

avenrun defined in line 64; used 5 times
bootime defined in line 91; used 3 times
datmap defined in line 102; used 12 times
debug defined in line 80; used 2 times
doing defined in line 62; used 10 times
file defined in line 60; used 10 times
fill defined in line 96; never used
firstchar defined in line 87; used 4 times
header defined in line 81; used 2 times
idle defined in line 84; used 2 times
jobtime defined in line 88; used 3 times
lflag defined in line 82; used 7 times
load defined in line 65; used 2 times
login defined in line 83; used 2 times
mem defined in line 57; used 13 times
mproc defined in line 94; used 18 times
nl defined in line 37; used 14 times
now defined in line 89; used 5 times
nowt defined in line 90; used 2 times
np defined in line 92; used 22 times
nswap defined in line 59; never used
nusers defined in line 85; used 3 times
pr defined in line 35; used 35 times
proctime defined in line 63; used 3 times
sel_user defined in line 86; used 3 times
swap defined in line 58; used 2 times
swmem defined in line 56; used 3 times
tty defined in line 61; used 2 times
up defined in line 95; used 19 times
uptime defined in line 91; used 6 times
utmp defined in line 93; used 17 times

Defined struct's

map defined in line 98; used 4 times
smproc defined in line 26; used 8 times

Defined macros

ARGLIST defined in line 24; used 6 times
ARGWIDTH defined in line 23; used 4 times
DIV60 defined in line 67; used 4 times
IGINT defined in line 69; used 3 times
TTYEQ defined in line 68; used 1 times
X_AVENRUN defined in line 45; used 2 times
X_BOOTIME defined in line 47; used 2 times
X_NPROC defined in line 49; used 2 times
X_PROC defined in line 39; used 2 times
X_SWAPDEV defined in line 41; used 3 times
X_SWPLO defined in line 43; used 1 times
Last modified: 1983-03-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1634
Valid CSS Valid XHTML 1.0 Strict