Annotation of 43BSDTahoe/ucb/sysline/sysline.c, revision 1.1

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

unix.superglobalmegacorp.com

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