Annotation of 42BSD/ucb/sysline/sysline.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.