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[] = "@(#)sysline.c	5.6 (Berkeley) 1/9/86";
  15: #endif not lint
  16: 
  17: /*
  18:  * sysline - system status display on 25th line of terminal
  19:  * j.k.foderaro
  20:  *
  21:  * Prints a variety of information on the special status line of terminals
  22:  * that have a status display capability.  Cursor motions, status commands,
  23:  * etc. are gleamed from /etc/termcap.
  24:  * By default, all information is printed, and flags are given on the command
  25:  * line to disable the printing of information.  The information and
  26:  * disabling flags are:
  27:  *
  28:  *  flag	what
  29:  *  -----	----
  30:  *		time of day
  31:  *		load average and change in load average in the last 5 mins
  32:  *		number of user logged on
  33:  *   -p		# of processes the users owns which are runnable and the
  34:  *		  number which are suspended.  Processes whose parent is 1
  35:  *		  are not counted.
  36:  *   -l		users who've logged on and off.
  37:  *   -m		summarize new mail which has arrived
  38:  *
  39:  *  <other flags>
  40:  *   -r		use non reverse video
  41:  *   -c		turn off 25th line for 5 seconds before redisplaying.
  42:  *   -b		beep once one the half hour, twice on the hour
  43:  *   +N		refresh display every N seconds.
  44:  *   -i		print pid first thing
  45:  *   -e		do simple print designed for an emacs buffer line
  46:  *   -w		do the right things for a window
  47:  *   -h		print hostname between time and load average
  48:  *   -D		print day/date before time of day
  49:  *   -d		debug mode - print status line data in human readable format
  50:  *   -q		quiet mode - don't output diagnostic messages
  51:  *   -s		print Short (left-justified) line if escapes not allowed
  52:  *   -j		Print left Justified line regardless
  53:  */
  54: 
  55: #define BSD4_2          /* for 4.2 BSD */
  56: #define WHO         /* turn this on always */
  57: #define HOSTNAME        /* 4.1a or greater, with hostname() */
  58: #define RWHO            /* 4.1a or greater, with rwho */
  59: #define VMUNIX          /* turn this on if you are running on vmunix */
  60: #define NEW_BOOTTIME        /* 4.1c or greater */
  61: 
  62: #define NETPREFIX "ucb"
  63: #define DEFDELAY 60     /* update status once per minute */
  64: #define MAILDIR "/usr/spool/mail"
  65: /*
  66:  * if MAXLOAD is defined, then if the load average exceeded MAXLOAD
  67:  * then the process table will not be scanned and the log in/out data
  68:  * will not be checked.   The purpose of this is to reduced the load
  69:  * on the system when it is loaded.
  70:  */
  71: #define MAXLOAD 6.0
  72: 
  73: #include <stdio.h>
  74: #include <sys/param.h>
  75: #include <sys/signal.h>
  76: #include <utmp.h>
  77: #include <ctype.h>
  78: #ifndef BSD4_2
  79: #include <unctrl.h>
  80: #endif
  81: #include <sys/time.h>
  82: #include <sys/stat.h>
  83: #ifdef VMUNIX
  84: #include <nlist.h>
  85: #include <sys/vtimes.h>
  86: #include <sys/proc.h>
  87: #endif
  88: #ifdef pdp11
  89: #include <a.out.h>
  90: #include <sys/proc.h>
  91: #endif
  92: #include <curses.h>
  93: #undef nl
  94: #ifdef TERMINFO
  95: #include <term.h>
  96: #endif TERMINFO
  97: 
  98: #ifdef RWHO
  99: #include <protocols/rwhod.h>
 100: 
 101: #define DOWN_THRESHOLD  (11 * 60)
 102: #define RWHOLEADER  "/usr/spool/rwho/whod."
 103: 
 104: struct remotehost {
 105:     char *rh_host;
 106:     int rh_file;
 107: } remotehost[10];
 108: int nremotes = 0;
 109: #endif RWHO
 110: 
 111: struct nlist nl[] = {
 112: #ifdef NEW_BOOTTIME
 113:     { "_boottime" },    /* After 4.1a the label changed to "boottime" */
 114: #else
 115:     { "_bootime" },     /* Under 4.1a and earlier it is "bootime" */
 116: #endif
 117: #define NL_BOOT 0
 118:     { "_proc" },
 119: #define NL_PROC 1
 120:     { "_avenrun" },
 121: #define NL_AVEN 2
 122: #ifdef VMUNIX
 123:     { "_nproc" },
 124: #define NL_NPROC 3
 125: #endif
 126:     0
 127: };
 128: 
 129:     /* stuff for the kernel */
 130: int kmem;           /* file descriptor for /dev/kmem */
 131: struct proc *proc, *procNPROC;
 132: int nproc;
 133: int procadr;
 134: double avenrun[3];      /* used for storing load averages */
 135: 
 136: /*
 137:  * In order to determine how many people are logged on and who has
 138:  * logged in or out, we read in the /etc/utmp file. We also keep track of
 139:  * the previous utmp file.
 140:  */
 141: int ut = -1;            /* the file descriptor */
 142: struct utmp *new, *old;
 143: char *status;           /* per tty status bits, see below */
 144: int nentries;           /* number of utmp entries */
 145:     /* string lengths for printing */
 146: #define LINESIZE (sizeof old->ut_line)
 147: #define NAMESIZE (sizeof old->ut_name)
 148: /*
 149:  * Status codes to say what has happened to a particular entry in utmp.
 150:  * NOCH means no change, ON means new person logged on,
 151:  * OFF means person logged off.
 152:  */
 153: #define NOCH    0
 154: #define ON  0x1
 155: #define OFF 0x2
 156: 
 157: #ifdef WHO
 158: char whofilename[100];
 159: char whofilename2[100];
 160: #endif
 161: 
 162: #ifdef HOSTNAME
 163: char hostname[MAXHOSTNAMELEN+1];    /* one more for null termination */
 164: #endif
 165: 
 166: char lockfilename[100];     /* if exists, will prevent us from running */
 167: 
 168:     /* flags which determine which info is printed */
 169: int mailcheck = 1;  /* m - do biff like checking of mail */
 170: int proccheck = 1;  /* p - give information on processes */
 171: int logcheck = 1;   /* l - tell who logs in and out */
 172: int hostprint = 0;  /* h - print out hostname */
 173: int dateprint = 0;  /* h - print out day/date */
 174: int quiet = 0;      /* q - hush diagnostic messages */
 175: 
 176:     /* flags which determine how things are printed */
 177: int clr_bet_ref = 0;    /* c - clear line between refeshes */
 178: int reverse = 1;    /* r - use reverse video */
 179: int shortline = 0;  /* s - short (left-justified) if escapes not allowed */
 180: int leftline = 0;   /* j - left-justified even if escapes allowed */
 181: 
 182:     /* flags which have terminal do random things	*/
 183: int beep = 0;       /* b - beep every half hour and twice every hour */
 184: int printid = 0;    /* i - print pid of this process at startup */
 185: int synch = 1;      /* synchronize with clock */
 186: 
 187:     /* select output device (status display or straight output) */
 188: int emacs = 0;      /* e - assume status display */
 189: int window = 0;     /* w - window mode */
 190: int dbug = 0;       /* d - debug */
 191: 
 192: /*
 193:  * used to turn off reverse video every REVOFF times
 194:  * in an attempt to not wear out the phospher.
 195:  */
 196: #define REVOFF 5
 197: int revtime = 1;
 198: 
 199:     /* used by mail checker */
 200: off_t mailsize = 0;
 201: off_t linebeg = 0;      /* place where we last left off reading */
 202: 
 203:     /* things used by the string routines */
 204: int chars;          /* number of printable characters */
 205: char *sp;
 206: char strarr[512];       /* big enough now? */
 207:     /* flags to stringdump() */
 208: char sawmail;           /* remember mail was seen to print bells */
 209: char mustclear;         /* status line messed up */
 210: 
 211:     /* strings which control status line display */
 212: #ifdef TERMINFO
 213: char    *rev_out, *rev_end, *arrows;
 214: char    *tparm();
 215: #else
 216: char    to_status_line[64];
 217: char    from_status_line[64];
 218: char    dis_status_line[64];
 219: char    clr_eol[64];
 220: char    rev_out[20], rev_end[20];
 221: char    *arrows, *bell = "\007";
 222: int eslok;  /* escapes on status line okay (reverse, cursor addressing) */
 223: int columns;
 224: #define tparm(cap, parm) tgoto((cap), 0, (parm))
 225: char    *tgoto();
 226: #endif
 227: 
 228:     /* to deal with window size changes */
 229: #ifdef SIGWINCH
 230: int sigwinch();
 231: char winchanged;    /* window size has changed since last update */
 232: #endif
 233: 
 234:     /* random globals */
 235: char *username;
 236: char *ourtty;           /* keep track of what tty we're on */
 237: struct stat stbuf, mstbuf;  /* mstbuf for mail check only */
 238: unsigned delay = DEFDELAY;
 239: short uid;
 240: double loadavg = 0.0;       /* current load average */
 241: int users = 0;
 242: 
 243: char *getenv();
 244: char *ttyname();
 245: char *strcpy1();
 246: char *sysrup();
 247: char *calloc();
 248: char *malloc();
 249: int outc();
 250: int erroutc();
 251: 
 252: main(argc,argv)
 253:     register char **argv;
 254: {
 255:     int clearbotl();
 256:     register char *cp;
 257:     char *home;
 258:     extern char _sobuf[];
 259:     extern char *index();
 260: 
 261:     setbuf(stdout, _sobuf);
 262: 
 263: #ifdef HOSTNAME
 264:     gethostname(hostname, sizeof hostname - 1);
 265:     if ((cp = index(hostname, '.')) != NULL)
 266:         *cp = '\0';
 267: #endif
 268: 
 269:     for (argv++; *argv != 0; argv++)
 270:         switch (**argv) {
 271:         case '-':
 272:             for (cp = *argv + 1; *cp; cp++) {
 273:                 switch(*cp) {
 274:                 case 'r' :  /* turn off reverse video */
 275:                     reverse = 0;
 276:                     break;
 277:                 case 'c':
 278:                     clr_bet_ref = 1;
 279:                     break;
 280:                 case 'h':
 281:                     hostprint = 1;
 282:                     break;
 283:                 case 'D':
 284:                     dateprint = 1;
 285:                     break;
 286: #ifdef RWHO
 287:                 case 'H':
 288:                     if (argv[1] == 0)
 289:                         break;
 290:                     argv++;
 291:                     if (strcmp(hostname, *argv) &&
 292:                         strcmp(&hostname[sizeof NETPREFIX - 1], *argv))
 293:                         remotehost[nremotes++].rh_host = *argv;
 294:                     break;
 295: #endif RWHO
 296:                 case 'm':
 297:                     mailcheck = 0;
 298:                     break;
 299:                 case 'p':
 300:                     proccheck = 0;
 301:                     break;
 302:                 case 'l':
 303:                     logcheck = 0;
 304:                     break;
 305:                 case 'b':
 306:                     beep = 1;
 307:                     break;
 308:                 case 'i':
 309:                     printid = 1;
 310:                     break;
 311:                 case 'w':
 312:                     window = 1;
 313:                     break;
 314:                 case 'e':
 315:                     emacs = 1;
 316:                     break;
 317:                 case 'd':
 318:                     dbug = 1;
 319:                     break;
 320:                 case 'q':
 321:                     quiet = 1;
 322:                     break;
 323:                 case 's':
 324:                     shortline = 1;
 325:                     break;
 326:                 case 'j':
 327:                     leftline = 1;
 328:                     break;
 329:                 default:
 330:                     fprintf(stderr,
 331:                         "sysline: bad flag: %c\n", *cp);
 332:                 }
 333:             }
 334:             break;
 335:         case '+':
 336:             delay = atoi(*argv + 1);
 337:             if (delay < 10)
 338:                 delay = 10;
 339:             else if (delay > 500)
 340:                 delay = 500;
 341:             synch = 0;  /* no more sync */
 342:             break;
 343:         default:
 344:             fprintf(stderr, "sysline: illegal argument %s\n",
 345:                 argv[0]);
 346:         }
 347:     if (emacs) {
 348:         reverse = 0;
 349:         columns = 79;
 350:     } else  /* if not to emacs window, initialize terminal dependent info */
 351:         initterm();
 352: #ifdef SIGWINCH
 353:     /*
 354: 	 * When the window size changes and we are the foreground
 355: 	 * process (true if -w), we get this signal.
 356: 	 */
 357:     signal(SIGWINCH, sigwinch);
 358: #endif
 359:     getwinsize();       /* get window size from ioctl */
 360: 
 361:     /* immediately fork and let the parent die if not emacs mode */
 362:     if (!emacs && !window && !dbug) {
 363:         if (fork())
 364:             exit(0);
 365:         /* pgrp should take care of things, but ignore them anyway */
 366:         signal(SIGINT, SIG_IGN);
 367:         signal(SIGQUIT, SIG_IGN);
 368: #ifdef VMUNIX
 369:         signal(SIGTTOU, SIG_IGN);
 370: #endif
 371:     }
 372:     /*
 373: 	 * When we logoff, init will do a "vhangup()" on this
 374: 	 * tty which turns off I/O access and sends a SIGHUP
 375: 	 * signal.  We catch this and thereby clear the status
 376: 	 * display.  Note that a bug in 4.1bsd caused the SIGHUP
 377: 	 * signal to be sent to the wrong process, so you had to
 378: 	 * `kill -HUP' yourself in your .logout file.
 379: 	 * Do the same thing for SIGTERM, which is the default kill
 380: 	 * signal.
 381: 	 */
 382:     signal(SIGHUP, clearbotl);
 383:     signal(SIGTERM, clearbotl);
 384:     /*
 385: 	 * This is so kill -ALRM to force update won't screw us up..
 386: 	 */
 387:     signal(SIGALRM, SIG_IGN);
 388: 
 389:     uid = getuid();
 390:     ourtty = ttyname(2);    /* remember what tty we are on */
 391:     if (printid) {
 392:         printf("%d\n", getpid());
 393:         fflush(stdout);
 394:     }
 395:     dup2(2, 1);
 396: 
 397:     if ((home = getenv("HOME")) == 0)
 398:         home = "";
 399:     strcpy1(strcpy1(whofilename, home), "/.who");
 400:     strcpy1(strcpy1(whofilename2, home), "/.sysline");
 401:     strcpy1(strcpy1(lockfilename, home), "/.syslinelock");
 402: 
 403:     if ((kmem = open("/dev/kmem",0)) < 0) {
 404:         fprintf(stderr, "Can't open kmem.\n");
 405:         exit(1);
 406:     }
 407:     readnamelist();
 408:     if (proccheck)
 409:         initprocread();
 410:     if (mailcheck)
 411:         if ((username = getenv("USER")) == 0)
 412:             mailcheck = 0;
 413:         else {
 414:             chdir(MAILDIR);
 415:             if (stat(username, &mstbuf) >= 0)
 416:                 mailsize = mstbuf.st_size;
 417:             else
 418:                 mailsize = 0;
 419:         }
 420: 
 421:     while (emacs || window || isloggedin())
 422:         if (access(lockfilename, 0) >= 0)
 423:             sleep(60);
 424:         else {
 425:             prtinfo();
 426:             sleep(delay);
 427:             if (clr_bet_ref) {
 428:                 tputs(dis_status_line, 1, outc);
 429:                 fflush(stdout);
 430:                 sleep(5);
 431:             }
 432:             revtime = (1 + revtime) % REVOFF;
 433:         }
 434:     clearbotl();
 435:     /*NOTREACHED*/
 436: }
 437: 
 438: isloggedin()
 439: {
 440:     /*
 441: 	 * you can tell if a person has logged out if the owner of
 442: 	 * the tty has changed
 443: 	 */
 444:     struct stat statbuf;
 445: 
 446:     return fstat(2, &statbuf) == 0 && statbuf.st_uid == uid;
 447: }
 448: 
 449: readnamelist()
 450: {
 451:     time_t bootime, clock, nintv, time();
 452: 
 453: #ifdef pdp11
 454:     nlist("/unix", nl);
 455: #else
 456:     nlist("/vmunix", nl);
 457: #endif
 458:     if (nl[0].n_value == 0) {
 459:         if (!quiet)
 460:             fprintf(stderr, "No namelist\n");
 461:         return;
 462:     }
 463:     lseek(kmem, (long)nl[NL_BOOT].n_value, 0);
 464:     read(kmem, &bootime, sizeof(bootime));
 465:     (void) time(&clock);
 466:     nintv = clock - bootime;
 467:     if (nintv <= 0L || nintv > 60L*60L*24L*365L) {
 468:         if (!quiet)
 469:             fprintf(stderr,
 470:             "Time makes no sense... namelist must be wrong\n");
 471:         nl[NL_PROC].n_value = nl[NL_AVEN].n_value = 0;
 472:     }
 473: }
 474: 
 475: readutmp(nflag)
 476:     char nflag;
 477: {
 478:     static time_t lastmod;      /* initially zero */
 479:     static off_t utmpsize;      /* ditto */
 480:     struct stat st;
 481: 
 482:     if (ut < 0 && (ut = open("/etc/utmp", 0)) < 0) {
 483:         fprintf(stderr, "sysline: Can't open utmp.\n");
 484:         exit(1);
 485:     }
 486:     if (fstat(ut, &st) < 0 || st.st_mtime == lastmod)
 487:         return 0;
 488:     lastmod = st.st_mtime;
 489:     if (utmpsize != st.st_size) {
 490:         utmpsize = st.st_size;
 491:         nentries = utmpsize / sizeof (struct utmp);
 492:         if (old == 0) {
 493:             old = (struct utmp *)calloc(utmpsize, 1);
 494:             new = (struct utmp *)calloc(utmpsize, 1);
 495:         } else {
 496:             old = (struct utmp *)realloc((char *)old, utmpsize);
 497:             new = (struct utmp *)realloc((char *)new, utmpsize);
 498:             free(status);
 499:         }
 500:         status = malloc(nentries * sizeof *status);
 501:         if (old == 0 || new == 0 || status == 0) {
 502:             fprintf(stderr, "sysline: Out of memory.\n");
 503:             exit(1);
 504:         }
 505:     }
 506:     lseek(ut, 0L, 0);
 507:     (void) read(ut, (char *) (nflag ? new : old), utmpsize);
 508:     return 1;
 509: }
 510: 
 511: /*
 512:  * read in the process table locations and sizes, and allocate space
 513:  * for storing the process table.  This is done only once.
 514:  */
 515: initprocread()
 516: {
 517: 
 518:     if (nl[NL_PROC].n_value == 0)
 519:         return;
 520: #ifdef VMUNIX
 521:     lseek(kmem, (long)nl[NL_PROC].n_value, 0);
 522:     read(kmem, &procadr, sizeof procadr);
 523:     lseek(kmem, (long)nl[NL_NPROC].n_value, 0);
 524:     read(kmem, &nproc, sizeof nproc);
 525: #endif
 526: #ifdef pdp11
 527:     procadr = nl[NL_PROC].n_value;
 528:     nproc = NPROC;          /* from param.h */
 529: #endif
 530:     if ((proc = (struct proc *) calloc(nproc, sizeof (struct proc))) == 0) {
 531:         fprintf(stderr, "Out of memory.\n");
 532:         exit(1);
 533:     }
 534:     procNPROC = proc + nproc;
 535: }
 536: 
 537: /*
 538:  * read in the process table.  This assumes that initprocread has alread been
 539:  * called to set up storage.
 540:  */
 541: readproctab()
 542: {
 543: 
 544:     if (nl[NL_PROC].n_value == 0)
 545:         return (0);
 546:     lseek(kmem, (long)procadr, 0);
 547:     read(kmem, (char *)proc, nproc * sizeof (struct proc));
 548:     return (1);
 549: }
 550: 
 551: prtinfo()
 552: {
 553:     int on, off;
 554:     register i;
 555:     char fullprocess;
 556: 
 557:     stringinit();
 558: #ifdef SIGWINCH
 559:     if (winchanged) {
 560:         winchanged = 0;
 561:         getwinsize();
 562:         mustclear = 1;
 563:     }
 564: #endif
 565: #ifdef WHO
 566:     /* check for file named .who in the home directory */
 567:     whocheck();
 568: #endif
 569:     timeprint();
 570:     /*
 571: 	 * if mail is seen, don't print rest of info, just the mail
 572: 	 * reverse new and old so that next time we run, we won't lose log
 573: 	 * in and out information
 574: 	 */
 575:     if (mailcheck && (sawmail = mailseen()))
 576:         goto bottom;
 577: #ifdef HOSTNAME
 578: #ifdef RWHO
 579:     for (i = 0; i < nremotes; i++) {
 580:         char *tmp;
 581: 
 582:         stringspace();
 583:         tmp = sysrup(remotehost + i);
 584:         stringcat(tmp, strlen(tmp));
 585:     }
 586: #endif
 587:     /*
 588: 	 * print hostname info if requested
 589: 	 */
 590:     if (hostprint) {
 591:         stringspace();
 592:         stringcat(hostname, -1);
 593:     }
 594: #endif
 595:     /*
 596: 	 * print load average and difference between current load average
 597: 	 * and the load average 5 minutes ago
 598: 	 */
 599:     if (nl[NL_AVEN].n_value != 0) {
 600:         double diff;
 601: 
 602:         stringspace();
 603: #ifdef VMUNIX
 604:         lseek(kmem, (long)nl[NL_AVEN].n_value, 0);
 605:         read(kmem, avenrun, sizeof avenrun);
 606: #endif
 607: #ifdef pdp11
 608:         loadav(avenrun);
 609: #endif
 610:         if ((diff = avenrun[0] - avenrun[1]) < 0.0)
 611:             stringprt("%.1f %.1f", avenrun[0],  diff);
 612:         else
 613:             stringprt("%.1f +%.1f", avenrun[0], diff);
 614:         loadavg = avenrun[0];       /* remember load average */
 615:     }
 616:     /*
 617: 	 * print log on and off information
 618: 	 */
 619:     stringspace();
 620:     fullprocess = 1;
 621: #ifdef MAXLOAD
 622:     if (loadavg > MAXLOAD)
 623:         fullprocess = 0;    /* too loaded to run */
 624: #endif
 625:     /*
 626: 	 * Read utmp file (logged in data) only if we are doing a full
 627: 	 * process, or if this is the first time and we are calculating
 628: 	 * the number of users.
 629: 	 */
 630:     on = off = 0;
 631:     if (users == 0) {       /* first time */
 632:         if (readutmp(0))
 633:             for (i = 0; i < nentries; i++)
 634:                 if (old[i].ut_name[0])
 635:                     users++;
 636:     } else if (fullprocess && readutmp(1)) {
 637:         struct utmp *tmp;
 638: 
 639:         users = 0;
 640:         for (i = 0; i < nentries; i++) {
 641:             if (strncmp(old[i].ut_name,
 642:                 new[i].ut_name, NAMESIZE) == 0)
 643:                 status[i] = NOCH;
 644:             else if (old[i].ut_name[0] == '\0') {
 645:                 status[i] = ON;
 646:                 on++;
 647:             } else if (new[i].ut_name[0] == '\0') {
 648:                 status[i] = OFF;
 649:                 off++;
 650:             } else {
 651:                 status[i] = ON | OFF;
 652:                 on++;
 653:                 off++;
 654:             }
 655:             if (new[i].ut_name[0])
 656:                 users++;
 657:         }
 658:         tmp = new;
 659:         new = old;
 660:         old = tmp;
 661:     }
 662:     /*
 663: 	 * Print:
 664: 	 * 	1.  number of users
 665: 	 *	2.  a * for unread mail
 666: 	 *	3.  a - if load is too high
 667: 	 *	4.  number of processes running and stopped
 668: 	 */
 669:     stringprt("%du", users);
 670:     if (mailsize > 0 && mstbuf.st_mtime >= mstbuf.st_atime)
 671:         stringcat("*", -1);
 672:     if (!fullprocess && (proccheck || logcheck))
 673:         stringcat("-", -1);
 674:     if (fullprocess && proccheck && readproctab()) {
 675:         register struct proc *p;
 676:         int procrun, procstop;
 677: 
 678:         /*
 679: 		 * We are only interested in processes which have the same
 680: 		 * uid as us, and whose parent process id is not 1.
 681: 		 */
 682:         procrun = procstop = 0;
 683:         for (p = proc; p < procNPROC; p++) {
 684:             if (p->p_stat == 0 || p->p_pgrp == 0 ||
 685:                 p->p_uid != uid || p->p_ppid == 1)
 686:                 continue;
 687:             switch (p->p_stat) {
 688:             case SSTOP:
 689:                 procstop++;
 690:                 break;
 691:             case SSLEEP:
 692:                 /*
 693: 				 * Sleep can mean waiting for a signal or just
 694: 				 * in a disk or page wait queue ready to run.
 695: 				 * We can tell if it is the later by the pri
 696: 				 * being negative.
 697: 				 */
 698:                 if (p->p_pri < PZERO)
 699:                     procrun++;
 700:                 break;
 701:             case SWAIT:
 702:             case SRUN:
 703:             case SIDL:
 704:                 procrun++;
 705:             }
 706:         }
 707:         if (procrun > 0 || procstop > 0) {
 708:             stringspace();
 709:             if (procrun > 0 && procstop > 0)
 710:                 stringprt("%dr %ds", procrun, procstop);
 711:             else if (procrun > 0)
 712:                 stringprt("%dr", procrun);
 713:             else
 714:                 stringprt("%ds", procstop);
 715:         }
 716:     }
 717:     /*
 718: 	 * If anyone has logged on or off, and we are interested in it,
 719: 	 * print it out.
 720: 	 */
 721:     if (logcheck) {
 722:         /* old and new have already been swapped */
 723:         if (on) {
 724:             stringspace();
 725:             stringcat("on:", -1);
 726:             for (i = 0; i < nentries; i++)
 727:                 if (status[i] & ON) {
 728:                     stringprt(" %.8s", old[i].ut_name);
 729:                     ttyprint(old[i].ut_line);
 730:                 }
 731:         }
 732:         if (off) {
 733:             stringspace();
 734:             stringcat("off:", -1);
 735:             for (i = 0; i < nentries; i++)
 736:                 if (status[i] & OFF) {
 737:                     stringprt(" %.8s", new[i].ut_name);
 738:                     ttyprint(new[i].ut_line);
 739:                 }
 740:         }
 741:     }
 742: bottom:
 743:         /* dump out what we know */
 744:     stringdump();
 745: }
 746: 
 747: timeprint()
 748: {
 749:     long curtime;
 750:     struct tm *tp, *localtime();
 751:     static int beepable = 1;
 752: 
 753:         /* always print time */
 754:     time(&curtime);
 755:     tp = localtime(&curtime);
 756:     if (dateprint)
 757:         stringprt("%.11s", ctime(&curtime));
 758:     stringprt("%d:%02d", tp->tm_hour > 12 ? tp->tm_hour - 12 :
 759:         (tp->tm_hour == 0 ? 12 : tp->tm_hour), tp->tm_min);
 760:     if (synch)          /* sync with clock */
 761:         delay = 60 - tp->tm_sec;
 762:     /*
 763: 	 * Beepable is used to insure that we get at most one set of beeps
 764: 	 * every half hour.
 765: 	 */
 766:     if (beep)
 767:         if (beepable) {
 768:             if (tp->tm_min == 30) {
 769:                 tputs(bell, 1, outc);
 770:                 fflush(stdout);
 771:                 beepable = 0;
 772:             } else if (tp->tm_min == 0) {
 773:                 tputs(bell, 1, outc);
 774:                 fflush(stdout);
 775:                 sleep(2);
 776:                 tputs(bell, 1, outc);
 777:                 fflush(stdout);
 778:                 beepable = 0;
 779:             }
 780:         } else
 781:             if (tp->tm_min != 0 && tp->tm_min != 30)
 782:                 beepable = 1;
 783: }
 784: 
 785: /*
 786:  * whocheck -- check for file named .who and print it on the who line first
 787:  */
 788: whocheck()
 789: {
 790:     int chss;
 791:     register char *p;
 792:     char buff[81];
 793:     int whofile;
 794: 
 795:     if ((whofile = open(whofilename, 0)) < 0 &&
 796:         (whofile = open(whofilename2, 0)) < 0)
 797:         return;
 798:     chss = read(whofile, buff, sizeof buff - 1);
 799:     close(whofile);
 800:     if (chss <= 0)
 801:         return;
 802:     buff[chss] = '\0';
 803:     /*
 804: 	 * Remove all line feeds, and replace by spaces if they are within
 805: 	 * the message, else replace them by nulls.
 806: 	 */
 807:     for (p = buff; *p;)
 808:         if (*p == '\n')
 809:             if (p[1])
 810:                 *p++ = ' ';
 811:             else
 812:                 *p = '\0';
 813:         else
 814:             p++;
 815:     stringcat(buff, p - buff);
 816:     stringspace();
 817: }
 818: 
 819: /*
 820:  * ttyprint -- given the name of a tty, print in the string buffer its
 821:  * short name surrounded by parenthesis.
 822:  * ttyxx is printed as (xx)
 823:  * console is printed as (cty)
 824:  */
 825: ttyprint(name)
 826:     char *name;
 827: {
 828:     char buff[11];
 829: 
 830:     if (strncmp(name, "tty", 3) == 0)
 831:         stringprt("(%.*s)", LINESIZE - 3, name + 3);
 832:     else if (strcmp(name, "console") == 0)
 833:         stringcat("(cty)", -1);
 834:     else
 835:         stringprt("(%.*s)", LINESIZE, name);
 836: }
 837: 
 838: /*
 839:  * mail checking function
 840:  * returns 0 if no mail seen
 841:  */
 842: mailseen()
 843: {
 844:     FILE *mfd;
 845:     register n;
 846:     register char *cp;
 847:     char lbuf[100], sendbuf[100], *bufend;
 848:     char seenspace;
 849:     int retval = 0;
 850: 
 851:     if (stat(username, &mstbuf) < 0) {
 852:         mailsize = 0;
 853:         return 0;
 854:     }
 855:     if (mstbuf.st_size <= mailsize || (mfd = fopen(username,"r")) == NULL) {
 856:         mailsize = mstbuf.st_size;
 857:         return 0;
 858:     }
 859:     fseek(mfd, mailsize, 0);
 860:     while ((n = readline(mfd, lbuf, sizeof lbuf)) >= 0 &&
 861:            strncmp(lbuf, "From ", 5) != 0)
 862:         ;
 863:     if (n < 0) {
 864:         stringcat("Mail has just arrived", 0);
 865:         goto out;
 866:     }
 867:     retval = 1;
 868:     /*
 869: 	 * Found a From line, get second word, which is the sender,
 870: 	 * and print it.
 871: 	 */
 872:     for (cp = lbuf + 5; *cp && *cp != ' '; cp++)    /* skip to blank */
 873:         ;
 874:     *cp = '\0';                 /* terminate name */
 875:     stringspace();
 876:     stringprt("Mail from %s ", lbuf + 5);
 877:     /*
 878: 	 * Print subject, and skip over header.
 879: 	 */
 880:     while ((n = readline(mfd, lbuf, sizeof lbuf)) > 0)
 881:         if (strncmp(lbuf, "Subject:", 8) == 0)
 882:             stringprt("on %s ", lbuf + 9);
 883:     if (!emacs)
 884:         stringcat(arrows, 2);
 885:     else
 886:         stringcat(": ", 2);
 887:     if (n < 0)          /* already at eof */
 888:         goto out;
 889:     /*
 890: 	 * Print as much of the letter as we can.
 891: 	 */
 892:     cp = sendbuf;
 893:     if ((n = columns - chars) > sizeof sendbuf - 1)
 894:         n = sizeof sendbuf - 1;
 895:     bufend = cp + n;
 896:     seenspace = 0;
 897:     while ((n = readline(mfd, lbuf, sizeof lbuf)) >= 0) {
 898:         register char *rp;
 899: 
 900:         if (strncmp(lbuf, "From ", 5) == 0)
 901:             break;
 902:         if (cp >= bufend)
 903:             continue;
 904:         if (!seenspace) {
 905:             *cp++ = ' ';        /* space before lines */
 906:             seenspace = 1;
 907:         }
 908:         rp = lbuf;
 909:         while (*rp && cp < bufend)
 910:             if (isspace(*rp)) {
 911:                 if (!seenspace) {
 912:                     *cp++ = ' ';
 913:                     seenspace = 1;
 914:                 }
 915:                 rp++;
 916:             } else {
 917:                 *cp++ = *rp++;
 918:                 seenspace = 0;
 919:             }
 920:     }
 921:     *cp = 0;
 922:     stringcat(sendbuf, -1);
 923:     /*
 924: 	 * Want to update write time so a star will
 925: 	 * appear after the number of users until the
 926: 	 * user reads his mail.
 927: 	 */
 928: out:
 929:     mailsize = linebeg;
 930:     fclose(mfd);
 931:     touch(username);
 932:     return retval;
 933: }
 934: 
 935: /*
 936:  * readline -- read a line from fp and store it in buf.
 937:  * return the number of characters read.
 938:  */
 939: readline(fp, buf, n)
 940:     register FILE *fp;
 941:     char *buf;
 942:     register n;
 943: {
 944:     register c;
 945:     register char *cp = buf;
 946: 
 947:     linebeg = ftell(fp);        /* remember loc where line begins */
 948:     cp = buf;
 949:     while (--n > 0 && (c = getc(fp)) != EOF && c != '\n')
 950:         *cp++ = c;
 951:     *cp = 0;
 952:     if (c == EOF && cp - buf == 0)
 953:         return -1;
 954:     return cp - buf;
 955: }
 956: 
 957: 
 958: /*
 959:  * string hacking functions
 960:  */
 961: 
 962: stringinit()
 963: {
 964:     sp = strarr;
 965:     chars = 0;
 966: }
 967: 
 968: /*VARARGS1*/
 969: stringprt(format, a, b, c)
 970:     char *format;
 971: {
 972:     char tempbuf[150];
 973: 
 974:     stringcat(sprintf(tempbuf, format, a, b, c), -1);
 975: }
 976: 
 977: stringdump()
 978: {
 979:     char bigbuf[sizeof strarr + 200];
 980:     register char *bp = bigbuf;
 981:     register int i;
 982: 
 983:     if (!emacs) {
 984:         if (sawmail)
 985:             bp = strcpy1(bp, bell);
 986:         if (eslok)
 987:             bp = strcpy1(bp, tparm(to_status_line,
 988:                 leftline ? 0 : columns - chars));
 989:         else {
 990:             bp = strcpy1(bp, to_status_line);
 991:             if (!shortline && !leftline)
 992:                 for (i = columns - chars; --i >= 0;)
 993:                     *bp++ = ' ';
 994:         }
 995:         if (reverse && revtime != 0)
 996:             bp = strcpy1(bp, rev_out);
 997:     }
 998:     *sp = 0;
 999:     bp = strcpy1(bp, strarr);
1000:     if (!emacs) {
1001:         if (reverse)
1002:             bp = strcpy1(bp, rev_end);
1003:         bp = strcpy1(bp, from_status_line);
1004:         if (sawmail)
1005:             bp = strcpy1(strcpy1(bp, bell), bell);
1006:         *bp = 0;
1007:         tputs(bigbuf, 1, outc);
1008:         if (mustclear) {
1009:             mustclear = 0;
1010:             tputs(clr_eol, 1, outc);
1011:         }
1012:         if (dbug)
1013:             putchar('\n');
1014:         fflush(stdout);
1015:     } else
1016:         write(2, bigbuf, bp - bigbuf);
1017: }
1018: 
1019: stringspace()
1020: {
1021:     if (reverse && revtime != 0) {
1022: #ifdef TERMINFO
1023:         stringcat(rev_end,
1024:             magic_cookie_glitch <= 0 ? 0 : magic_cookie_glitch);
1025:         stringcat(" ", 1);
1026:         stringcat(rev_out,
1027:             magic_cookie_glitch <= 0 ? 0 : magic_cookie_glitch);
1028: #else
1029:         stringcat(rev_end, 0);
1030:         stringcat(" ", 1);
1031:         stringcat(rev_out, 0);
1032: #endif TERMINFO
1033:     } else
1034:         stringcat(" ", 1);
1035: }
1036: 
1037: /*
1038:  * stringcat :: concatenate the characters in string str to the list we are
1039:  * 	        building to send out.
1040:  * str - the string to print. may contain funny (terminal control) chars.
1041:  * n  - the number of printable characters in the string
1042:  *	or if -1 then str is all printable so we can truncate it,
1043:  *	otherwise don't print only half a string.
1044:  */
1045: stringcat(str, n)
1046:     register char *str;
1047:     register n;
1048: {
1049:     register char *p = sp;
1050: 
1051:     if (n < 0) {                /* truncate */
1052:         n = columns - chars;
1053:         while ((*p++ = *str++) && --n >= 0)
1054:             ;
1055:         p--;
1056:         chars += p - sp;
1057:         sp = p;
1058:     } else if (chars + n <= columns) {  /* don't truncate */
1059:         while (*p++ = *str++)
1060:             ;
1061:         chars += n;
1062:         sp = p - 1;
1063:     }
1064: }
1065: 
1066: /*
1067:  * touch :: update the modify time of a file.
1068:  */
1069: touch(name)
1070:     char *name;     /* name of file */
1071: {
1072:     register fd;
1073:     char buf;
1074: 
1075:     if ((fd = open(name, 2)) >= 0) {
1076:         read(fd, &buf, 1);      /* get first byte */
1077:         lseek(fd, 0L, 0);       /* go to beginning */
1078:         write(fd, &buf, 1);     /* and rewrite first byte */
1079:         close(fd);
1080:     }
1081: }
1082: 
1083: 
1084: /*
1085:  * clearbotl :: clear bottom line.
1086:  * called when process quits or is killed.
1087:  * it clears the bottom line of the terminal.
1088:  */
1089: clearbotl()
1090: {
1091:     register int fd;
1092:     int exit();
1093: 
1094:     signal(SIGALRM, exit);
1095:     alarm(30);  /* if can't open in 30 secs, just die */
1096:     if (!emacs && (fd = open(ourtty, 1)) >= 0) {
1097:         write(fd, dis_status_line, strlen(dis_status_line));
1098:         close(fd);
1099:     }
1100: #ifdef PROF
1101:     if (chdir("/usr/src/ucb/sysline") < 0)
1102:         (void) chdir("/tmp");
1103: #endif
1104:     exit(0);
1105: }
1106: 
1107: #ifdef TERMINFO
1108: initterm()
1109: {
1110:     static char standbuf[40];
1111: 
1112:     setupterm(0, 1, 0);
1113:     if (!window && !has_status_line) {
1114:         /* not an appropriate terminal */
1115:         if (!quiet)
1116:            fprintf(stderr, "sysline: no status capability for %s\n",
1117:             getenv("TERM"));
1118:         exit(1);
1119:     }
1120:     if (window || status_line_esc_ok) {
1121:         if (set_attributes) {
1122:             /* reverse video mode */
1123:             strcpy(standbuf,
1124:                 tparm(set_attributes,0,0,1,0,0,0,0,0,0));
1125:             rev_out = standbuf;
1126:             rev_end = exit_attribute_mode;
1127:         } else if (enter_standout_mode && exit_standout_mode) {
1128:             rev_out = enter_standout_mode;
1129:             rev_end = exit_standout_mode;
1130:         } else
1131:             rev_out = rev_end = "";
1132:     } else
1133:         rev_out = rev_end = "";
1134:     columns--;  /* avoid cursor wraparound */
1135: }
1136: 
1137: #else   /* TERMCAP */
1138: 
1139: initterm()
1140: {
1141:     char *term, *cp;
1142:     static char tbuf[1024];
1143:     char is2[40];
1144:     extern char *UP;
1145: 
1146:     if ((term = getenv("TERM")) == NULL) {
1147:         if (!quiet)
1148:             fprintf(stderr,
1149:                 "sysline: No TERM variable in enviroment\n");
1150:         exit(1);
1151:     }
1152:     if (tgetent(tbuf, term) <= 0) {
1153:         if (!quiet)
1154:             fprintf(stderr,
1155:                 "sysline: Unknown terminal type: %s\n", term);
1156:         exit(1);
1157:     }
1158:     if (!window && tgetflag("hs") <= 0) {
1159:         if (!strncmp(term, "h19", 3)) {
1160:             /* for upward compatability with h19sys */
1161:             strcpy(to_status_line,
1162:                 "\033j\033x5\033x1\033Y8%+ \033o");
1163:             strcpy(from_status_line, "\033k\033y5");
1164:             strcpy(dis_status_line, "\033y1");
1165:             strcpy(rev_out, "\033p");
1166:             strcpy(rev_end, "\033q");
1167:             arrows = "\033Fhh\033G";
1168:             columns = 80;
1169:             UP = "\b";
1170:             return;
1171:         }
1172:         if (!quiet)
1173:             fprintf(stderr,
1174:                 "sysline: No status capability for %s\n", term);
1175:         exit(1);
1176:     }
1177:     cp = is2;
1178:     if (tgetstr("i2", &cp) != NULL) {
1179:         /* someday tset will do this */
1180:         tputs(is2, 1, erroutc);
1181:         fflush(stdout);
1182:     }
1183: 
1184:     /* the "-1" below is to avoid cursor wraparound problems */
1185:     columns = tgetnum("co") - 1;
1186:     if (window) {
1187:         strcpy(to_status_line, "\r");
1188:         cp = dis_status_line;   /* use the clear line sequence */
1189:         *cp++ = '\r';
1190:         tgetstr("ce", &cp);
1191:         if (leftline)
1192:             strcpy(from_status_line, dis_status_line + 1);
1193:         else
1194:             strcpy(from_status_line, "");
1195:     } else {
1196:         cp = to_status_line;
1197:         tgetstr("ts", &cp);
1198:         cp = from_status_line;
1199:         tgetstr("fs", &cp);
1200:         cp = dis_status_line;
1201:         tgetstr("ds", &cp);
1202:         eslok = tgetflag("es");
1203:     }
1204:     if (eslok || window) {
1205:         cp = rev_out;
1206:         tgetstr("so", &cp);
1207:         cp = rev_end;
1208:         tgetstr("se", &cp);
1209:         cp = clr_eol;
1210:         tgetstr("ce", &cp);
1211:     } else
1212:         reverse = 0;    /* turn off reverse video */
1213:     UP = "\b";
1214:     if (!strncmp(term, "h19", 3))
1215:         arrows = "\033Fhh\033G";    /* "two tiny graphic arrows" */
1216:     else
1217:         arrows = "->";
1218: }
1219: #endif TERMINFO
1220: 
1221: #ifdef pdp11
1222: loadav(ap)
1223: double ap[];
1224: {
1225:     register int i;
1226:     short s_avenrun[3];
1227: 
1228:     lseek(kmem, (long)nl[NL_AVEN].n_value, 0);
1229:     read(kmem, s_avenrun, sizeof(s_avenrun));
1230:     for (i=0; i < (sizeof(s_avenrun)/sizeof(s_avenrun[0])); i++)
1231:         ap[i] = s_avenrun[i] / 256.0;
1232: }
1233: #endif
1234: 
1235: #ifdef RWHO
1236: char *
1237: sysrup(hp)
1238:     register struct remotehost *hp;
1239: {
1240:     char filename[100];
1241:     struct whod wd;
1242: #define WHOD_HDR_SIZE (sizeof (wd) - sizeof (wd.wd_we))
1243:     static char buffer[50];
1244:     time_t now;
1245: 
1246:     /*
1247: 	 * rh_file is initially 0.
1248: 	 * This is ok since standard input is assumed to exist.
1249: 	 */
1250:     if (hp->rh_file == 0) {
1251:         /*
1252: 		 * Try rwho hostname file, and if that fails try ucbhostname.
1253: 		 */
1254:         (void) strcpy1(strcpy1(filename, RWHOLEADER), hp->rh_host);
1255:         if ((hp->rh_file = open(filename, 0)) < 0) {
1256:             (void) strcpy1(strcpy1(strcpy1(filename, RWHOLEADER),
1257:                 NETPREFIX), hp->rh_host);
1258:             hp->rh_file = open(filename, 0);
1259:         }
1260:     }
1261:     if (hp->rh_file < 0)
1262:         return sprintf(buffer, "%s?", hp->rh_host);
1263:     (void) lseek(hp->rh_file, (off_t)0, 0);
1264:     if (read(hp->rh_file, (char *)&wd, WHOD_HDR_SIZE) != WHOD_HDR_SIZE)
1265:         return sprintf(buffer, "%s ?", hp->rh_host);
1266:     (void) time(&now);
1267:     if (now - wd.wd_recvtime > DOWN_THRESHOLD) {
1268:         long interval;
1269:         long days, hours, minutes;
1270: 
1271:         interval = now - wd.wd_recvtime;
1272:         minutes = (interval + 59) / 60; /* round to minutes */
1273:         hours = minutes / 60;       /* extract hours from minutes */
1274:         minutes %= 60;          /* remove hours from minutes */
1275:         days = hours / 24;      /* extract days from hours */
1276:         hours %= 24;            /* remove days from hours */
1277:         if (days > 7 || days < 0)
1278:             (void) sprintf(buffer, "%s down", hp->rh_host);
1279:         else if (days > 0)
1280:             (void) sprintf(buffer, "%s %d+%d:%02d",
1281:                 hp->rh_host, days, hours, minutes);
1282:         else
1283:             (void) sprintf(buffer, "%s %d:%02d",
1284:                 hp->rh_host, hours, minutes);
1285:     } else
1286:         (void) sprintf(buffer, "%s %.1f",
1287:             hp->rh_host, wd.wd_loadav[0]/100.0);
1288:     return buffer;
1289: }
1290: #endif RWHO
1291: 
1292: getwinsize()
1293: {
1294: #ifdef TIOCGWINSZ
1295:     struct winsize winsize;
1296: 
1297:     /* the "-1" below is to avoid cursor wraparound problems */
1298:     if (ioctl(2, TIOCGWINSZ, (char *)&winsize) >= 0 && winsize.ws_col != 0)
1299:         columns = winsize.ws_col - 1;
1300: #endif
1301: }
1302: 
1303: #ifdef SIGWINCH
1304: sigwinch()
1305: {
1306:     winchanged++;
1307: }
1308: #endif
1309: 
1310: char *
1311: strcpy1(p, q)
1312:     register char *p, *q;
1313: {
1314: 
1315:     while (*p++ = *q++)
1316:         ;
1317:     return p - 1;
1318: }
1319: 
1320: outc(c)
1321:     char c;
1322: {
1323:     if (dbug)
1324:         printf("%s", unctrl(c));
1325:     else
1326:         putchar(c);
1327: }
1328: 
1329: erroutc(c)
1330:     char c;
1331: {
1332:     if (dbug)
1333:         fprintf(stderr, "%s", unctrl(c));
1334:     else
1335:         putc(c, stderr);
1336: }

Defined functions

clearbotl defined in line 1089; used 4 times
erroutc defined in line 1329; used 2 times
getwinsize defined in line 1292; used 2 times
initprocread defined in line 515; used 1 times
initterm defined in line 1139; used 1 times
isloggedin defined in line 438; used 1 times
loadav defined in line 1222; used 1 times
mailseen defined in line 842; used 1 times
main defined in line 252; never used
outc defined in line 1320; used 7 times
prtinfo defined in line 551; used 1 times
readline defined in line 939; used 3 times
readnamelist defined in line 449; used 1 times
readproctab defined in line 541; used 1 times
readutmp defined in line 475; used 2 times
sigwinch defined in line 1304; used 2 times
strcpy1 defined in line 1310; used 21 times
stringcat defined in line 1045; used 20 times
stringdump defined in line 977; used 1 times
stringinit defined in line 962; used 1 times
stringprt defined in line 969; used 14 times
stringspace defined in line 1019; used 9 times
sysrup defined in line 1236; used 2 times
timeprint defined in line 747; used 1 times
touch defined in line 1069; used 1 times
ttyprint defined in line 825; used 2 times
whocheck defined in line 788; used 1 times

Defined variables

arrows defined in line 221; used 4 times
avenrun defined in line 134; used 8 times
beep defined in line 183; used 2 times
bell defined in line 221; used 6 times
chars defined in line 204; used 8 times
clr_bet_ref defined in line 177; used 2 times
clr_eol defined in line 219; used 2 times
columns defined in line 223; used 10 times
copyright defined in line 8; never used
dateprint defined in line 173; used 2 times
dbug defined in line 190; used 5 times
delay defined in line 238; used 7 times
dis_status_line defined in line 218; used 7 times
emacs defined in line 188; used 8 times
eslok defined in line 222; used 3 times
from_status_line defined in line 217; used 5 times
hostname defined in line 163; used 6 times
hostprint defined in line 172; used 2 times
kmem defined in line 130; used 13 times
leftline defined in line 180; used 4 times
loadavg defined in line 240; used 2 times
lockfilename defined in line 166; used 2 times
logcheck defined in line 171; used 3 times
mailcheck defined in line 169; used 4 times
mstbuf defined in line 237; used 7 times
mustclear defined in line 209; used 3 times
nentries defined in line 144; used 6 times
new defined in line 142; used 12 times
nl defined in line 111; never used
nproc defined in line 132; used 6 times
nremotes defined in line 108; used 2 times
old defined in line 142; used 15 times
ourtty defined in line 236; used 2 times
printid defined in line 184; used 2 times
proc defined in line 131; used 4 times
procNPROC defined in line 131; used 2 times
procadr defined in line 133; used 4 times
proccheck defined in line 170; used 4 times
quiet defined in line 174; used 7 times
remotehost defined in line 107; used 2 times
rev_end defined in line 220; used 9 times
rev_out defined in line 220; used 9 times
reverse defined in line 178; used 6 times
revtime defined in line 197; used 4 times
sawmail defined in line 208; used 3 times
sccsid defined in line 14; never used
shortline defined in line 179; used 2 times
sp defined in line 205; used 6 times
status defined in line 143; used 10 times
stbuf defined in line 237; never used
strarr defined in line 206; used 3 times
synch defined in line 185; used 2 times
to_status_line defined in line 216; used 5 times
uid defined in line 239; used 3 times
username defined in line 235; used 5 times
users defined in line 241; used 5 times
ut defined in line 141; used 5 times
whofilename defined in line 158; used 2 times
whofilename2 defined in line 159; used 2 times
winchanged defined in line 231; used 3 times
window defined in line 189; used 8 times

Defined struct's

remotehost defined in line 104; used 2 times

Defined macros

BSD4_2 defined in line 55; used 1 times
  • in line 78
DEFDELAY defined in line 63; used 1 times
DOWN_THRESHOLD defined in line 101; used 1 times
HOSTNAME defined in line 57; used 3 times
LINESIZE defined in line 146; used 2 times
MAILDIR defined in line 64; used 1 times
MAXLOAD defined in line 71; used 2 times
NAMESIZE defined in line 147; used 1 times
NETPREFIX defined in line 62; used 2 times
NEW_BOOTTIME defined in line 60; used 1 times
NL_AVEN defined in line 121; used 4 times
NL_BOOT defined in line 117; used 1 times
NL_NPROC defined in line 124; used 1 times
NL_PROC defined in line 119; used 5 times
NOCH defined in line 153; used 1 times
OFF defined in line 155; used 3 times
ON defined in line 154; used 3 times
REVOFF defined in line 196; used 1 times
RWHO defined in line 58; used 4 times
RWHOLEADER defined in line 102; used 2 times
VMUNIX defined in line 59; used 5 times
WHO defined in line 56; used 2 times
WHOD_HDR_SIZE defined in line 1242; used 2 times
tparm defined in line 224; used 3 times
Last modified: 1986-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6619
Valid CSS Valid XHTML 1.0 Strict