Annotation of 43BSDReno/usr.bin/w/w.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)w.c        5.24 (Berkeley) 7/27/90";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * w - print system status (who and what)
        !            19:  *
        !            20:  * This program is similar to the systat command on Tenex/Tops 10/20
        !            21:  *
        !            22:  */
        !            23: #include <sys/param.h>
        !            24: #include <utmp.h>
        !            25: #include <sys/stat.h>
        !            26: #include <sys/user.h>
        !            27: #include <sys/proc.h>
        !            28: #include <sys/ioctl.h>
        !            29: #include <machine/pte.h>
        !            30: #include <sys/vm.h>
        !            31: #include <sys/tty.h>
        !            32: #include <nlist.h>
        !            33: #include <kvm.h>
        !            34: #include <ctype.h>
        !            35: #include <paths.h>
        !            36: #include <string.h>
        !            37: #include <stdio.h>
        !            38: 
        !            39: char   *program;
        !            40: int    ttywidth;               /* width of tty */
        !            41: int    argwidth;               /* width of tty */
        !            42: int    header = 1;             /* true if -h flag: don't print heading */
        !            43: int    wcmd = 1;               /* true if this is w(1), and not uptime(1) */
        !            44: int    nusers;                 /* number of users logged in now */
        !            45: char * sel_user;               /* login of particular user selected */
        !            46: time_t now;                    /* the current time of day */
        !            47: struct timeval boottime;
        !            48: time_t uptime;                 /* time of last reboot & elapsed time since */
        !            49: struct utmp utmp;
        !            50: struct winsize ws;
        !            51: int    sortidle;               /* sort bu idle time */
        !            52: 
        !            53: 
        !            54: /*
        !            55:  * One of these per active utmp entry.  
        !            56:  */
        !            57: struct entry {
        !            58:        struct  entry *next;
        !            59:        struct  utmp utmp;
        !            60:        dev_t   tdev;           /* dev_t of terminal */
        !            61:        int     idle;           /* idle time of terminal in minutes */
        !            62:        struct  proc *proc;     /* list of procs in foreground */
        !            63:        char    *args;          /* arg list of interesting process */
        !            64: } *ep, *ehead = NULL, **nextp = &ehead;
        !            65: 
        !            66: struct nlist nl[] = {
        !            67:        { "_boottime" },
        !            68: #define X_BOOTTIME     0
        !            69: #if defined(hp300)
        !            70:        { "_cn_tty" },
        !            71: #define X_CNTTY                1
        !            72: #endif
        !            73:        { "" },
        !            74: };
        !            75: 
        !            76: #define USAGE "[ -hi ] [ user ]"
        !            77: #define usage()        fprintf(stderr, "usage: %s: %s\n", program, USAGE)
        !            78: 
        !            79: main(argc, argv)
        !            80:        char **argv;
        !            81: {
        !            82:        register int i;
        !            83:        struct winsize win;
        !            84:        register struct proc *p;
        !            85:        struct eproc *e;
        !            86:        struct stat *stp, *ttystat();
        !            87:        FILE *ut;
        !            88:        char *cp;
        !            89:        int ch;
        !            90:        extern char *optarg;
        !            91:        extern int optind;
        !            92:        char *strsave();
        !            93: 
        !            94:        program = argv[0];
        !            95:        /*
        !            96:         * are we w(1) or uptime(1)
        !            97:         */
        !            98:        if ((cp = rindex(program, '/')) || *(cp = program) == '-')
        !            99:                cp++;
        !           100:        if (*cp == 'u')
        !           101:                wcmd = 0;
        !           102: 
        !           103:        while ((ch = getopt(argc, argv, "hiflsuw")) != EOF)
        !           104:                switch((char)ch) {
        !           105:                case 'h':
        !           106:                        header = 0;
        !           107:                        break;
        !           108:                case 'i':
        !           109:                        sortidle++;
        !           110:                        break;
        !           111:                case 'f': case 'l': case 's': case 'u': case 'w':
        !           112:                        error("[-flsuw] no longer supported");
        !           113:                        usage();
        !           114:                        exit(1);
        !           115:                case '?':
        !           116:                default:
        !           117:                        usage();
        !           118:                        exit(1);
        !           119:                }
        !           120:        argc -= optind;
        !           121:        argv += optind;
        !           122:        if (argc == 1) {
        !           123:                sel_user = argv[0];
        !           124:                argv++, argc--;
        !           125:        }
        !           126:        if (argc) {
        !           127:                usage();
        !           128:                exit(1);
        !           129:        }
        !           130: 
        !           131:        if (header && kvm_nlist(nl) != 0) {
        !           132:                error("can't get namelist");
        !           133:                exit (1);
        !           134:        }
        !           135:        time(&now);
        !           136:        ut = fopen(_PATH_UTMP, "r");
        !           137:        while (fread(&utmp, sizeof(utmp), 1, ut)) {
        !           138:                if (utmp.ut_name[0] == '\0')
        !           139:                        continue;
        !           140:                nusers++;
        !           141:                if (wcmd == 0 || (sel_user && 
        !           142:                    strncmp(utmp.ut_name, sel_user, UT_NAMESIZE) != 0))
        !           143:                        continue;
        !           144:                if ((ep = (struct entry *)
        !           145:                     calloc(1, sizeof (struct entry))) == NULL) {
        !           146:                        error("out of memory");
        !           147:                        exit(1);
        !           148:                }
        !           149:                *nextp = ep;
        !           150:                nextp = &(ep->next);
        !           151:                bcopy(&utmp, &(ep->utmp), sizeof (struct utmp));
        !           152:                stp = ttystat(ep->utmp.ut_line);
        !           153:                ep->tdev = stp->st_rdev;
        !           154: #if defined(hp300)
        !           155:                /*
        !           156:                 * XXX  If this is the console device, attempt to ascertain
        !           157:                 * the true console device dev_t.
        !           158:                 */
        !           159:                if (ep->tdev == 0) {
        !           160:                        static dev_t cn_dev;
        !           161: 
        !           162:                        if (nl[X_CNTTY].n_value) {
        !           163:                                struct tty cn_tty, *cn_ttyp;
        !           164:                                
        !           165:                                if (kvm_read(nl[X_CNTTY].n_value,
        !           166:                                             &cn_ttyp, sizeof (cn_ttyp)) > 0) {
        !           167:                                        (void)kvm_read(cn_ttyp, &cn_tty,
        !           168:                                                       sizeof (cn_tty));
        !           169:                                        cn_dev = cn_tty.t_dev;
        !           170:                                }
        !           171:                                nl[X_CNTTY].n_value = 0;
        !           172:                        }
        !           173:                        ep->tdev = cn_dev;
        !           174:                }
        !           175: #endif
        !           176:                ep->idle = ((now - stp->st_atime) + 30) / 60; /* secs->mins */
        !           177:                if (ep->idle < 0)
        !           178:                        ep->idle = 0;
        !           179:        }
        !           180:        fclose(ut);
        !           181: 
        !           182:        if (header || wcmd == 0) {
        !           183:                double  avenrun[3];
        !           184:                int days, hrs, mins;
        !           185: 
        !           186:                /*
        !           187:                 * Print time of day 
        !           188:                 */
        !           189:                fputs(attime(&now), stdout);
        !           190:                /*
        !           191:                 * Print how long system has been up.
        !           192:                 * (Found by looking for "boottime" in kernel)
        !           193:                 */
        !           194:                (void)kvm_read((off_t)nl[X_BOOTTIME].n_value, &boottime, 
        !           195:                        sizeof (boottime));
        !           196:                uptime = now - boottime.tv_sec;
        !           197:                uptime += 30;
        !           198:                days = uptime / (60*60*24);
        !           199:                uptime %= (60*60*24);
        !           200:                hrs = uptime / (60*60);
        !           201:                uptime %= (60*60);
        !           202:                mins = uptime / 60;
        !           203: 
        !           204:                printf("  up");
        !           205:                if (days > 0)
        !           206:                        printf(" %d day%s,", days, days>1?"s":"");
        !           207:                if (hrs > 0 && mins > 0) {
        !           208:                        printf(" %2d:%02d,", hrs, mins);
        !           209:                } else {
        !           210:                        if (hrs > 0)
        !           211:                                printf(" %d hr%s,", hrs, hrs>1?"s":"");
        !           212:                        if (mins > 0)
        !           213:                                printf(" %d min%s,", mins, mins>1?"s":"");
        !           214:                }
        !           215: 
        !           216:                /* Print number of users logged in to system */
        !           217:                printf("  %d user%s", nusers, nusers>1?"s":"");
        !           218: 
        !           219:                /*
        !           220:                 * Print 1, 5, and 15 minute load averages.
        !           221:                 */
        !           222:                printf(",  load average:");
        !           223:                (void)getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0]));
        !           224:                for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) {
        !           225:                        if (i > 0)
        !           226:                                printf(",");
        !           227:                        printf(" %.2f", avenrun[i]);
        !           228:                }
        !           229:                printf("\n");
        !           230:                if (wcmd == 0)          /* if uptime(1) then done */
        !           231:                        exit(0);
        !           232: #define HEADER "USER    TTY FROM              LOGIN@  IDLE WHAT\n"
        !           233: #define WUSED  (sizeof (HEADER) - sizeof ("WHAT\n"))
        !           234:                printf(HEADER);
        !           235:        }
        !           236: 
        !           237:        while ((p = kvm_nextproc()) != NULL) {
        !           238:                if (p->p_stat == SZOMB || (p->p_flag & SCTTY) == 0)
        !           239:                        continue;
        !           240:                e = kvm_geteproc(p);
        !           241:                for (ep = ehead; ep != NULL; ep = ep->next) {
        !           242:                        if (ep->tdev == e->e_tdev && e->e_pgid == e->e_tpgid) {
        !           243:                                /*
        !           244:                                 * Proc is in foreground of this terminal
        !           245:                                 */
        !           246:                                if (proc_compare(ep->proc, p))
        !           247:                                        ep->proc = p;
        !           248:                                break;
        !           249:                        }
        !           250:                }
        !           251:        }
        !           252:        if ((ioctl(1, TIOCGWINSZ, &ws) == -1 &&
        !           253:             ioctl(2, TIOCGWINSZ, &ws) == -1 &&
        !           254:             ioctl(0, TIOCGWINSZ, &ws) == -1) || ws.ws_col == 0)
        !           255:               ttywidth = 79;
        !           256:         else
        !           257:               ttywidth = ws.ws_col - 1;
        !           258:        argwidth = ttywidth - WUSED;
        !           259:        if (argwidth < 4)
        !           260:                argwidth = 8;
        !           261:        for (ep = ehead; ep != NULL; ep = ep->next) {
        !           262:                ep->args = strsave(kvm_getargs(ep->proc, kvm_getu(ep->proc)));
        !           263:                if (ep->args == NULL) {
        !           264:                        error("out of memory");
        !           265:                        exit(1);
        !           266:                }
        !           267:        }
        !           268:        /* sort by idle time */
        !           269:        if (sortidle && ehead != NULL) {
        !           270:                struct entry *from = ehead, *save;
        !           271:                
        !           272:                ehead = NULL;
        !           273:                while (from != NULL) {
        !           274:                        for (nextp = &ehead; 
        !           275:                            (*nextp) && from->idle >= (*nextp)->idle;
        !           276:                            nextp = &(*nextp)->next)
        !           277:                                ;
        !           278:                        save = from;
        !           279:                        from = from->next;
        !           280:                        save->next = *nextp;
        !           281:                        *nextp = save;
        !           282:                }
        !           283:        }
        !           284:                        
        !           285:        for (ep = ehead; ep != NULL; ep = ep->next) {
        !           286:                printf("%-*.*s %-2.2s %-*.*s %s",
        !           287:                        UT_NAMESIZE, UT_NAMESIZE, ep->utmp.ut_name,
        !           288:                        strncmp(ep->utmp.ut_line, "tty", 3) == 0 ? 
        !           289:                                ep->utmp.ut_line+3 : ep->utmp.ut_line,
        !           290:                        UT_HOSTSIZE, UT_HOSTSIZE, *ep->utmp.ut_host ?
        !           291:                                ep->utmp.ut_host : "-",
        !           292:                        attime(&ep->utmp.ut_time));
        !           293:                if (ep->idle >= 36 * 60)
        !           294:                        printf(" %ddays ", (ep->idle + 12 * 60) / (24 * 60));
        !           295:                else
        !           296:                        prttime(ep->idle, " ");
        !           297:                printf("%.*s\n", argwidth, ep->args);
        !           298:        }
        !           299: }
        !           300: 
        !           301: struct stat *
        !           302: ttystat(line)
        !           303: {
        !           304:        static struct stat statbuf;
        !           305:        char ttybuf[sizeof (_PATH_DEV) + UT_LINESIZE + 1];
        !           306: 
        !           307:        sprintf(ttybuf, "%s/%.*s", _PATH_DEV, UT_LINESIZE, line);
        !           308:        (void) stat(ttybuf, &statbuf);
        !           309: 
        !           310:        return (&statbuf);
        !           311: }
        !           312: 
        !           313: char *
        !           314: strsave(cp)
        !           315:        char *cp;
        !           316: {
        !           317:        register unsigned len;
        !           318:        register char *dp;
        !           319: 
        !           320:        len = strlen(cp);
        !           321:        dp = (char *)calloc(len+1, sizeof (char));
        !           322:        (void) strcpy(dp, cp);
        !           323:        return (dp);
        !           324: }
        !           325: /*
        !           326:  * prttime prints a time in hours and minutes or minutes and seconds.
        !           327:  * The character string tail is printed at the end, obvious
        !           328:  * strings to pass are "", " ", or "am".
        !           329:  */
        !           330: prttime(tim, tail)
        !           331:        time_t tim;
        !           332:        char *tail;
        !           333: {
        !           334: 
        !           335:        if (tim >= 60) {
        !           336:                printf(" %2d:", tim/60);
        !           337:                tim %= 60;
        !           338:                printf("%02d", tim);
        !           339:        } else if (tim >= 0)
        !           340:                printf("    %2d", tim);
        !           341:        printf("%s", tail);
        !           342: }
        !           343: 
        !           344: #include <varargs.h>
        !           345: 
        !           346: warning(va_alist)
        !           347:        va_dcl
        !           348: {
        !           349:        char *fmt;
        !           350:        va_list ap;
        !           351: 
        !           352:        fprintf(stderr, "%s: warning: ", program);
        !           353:        va_start(ap);
        !           354:        fmt = va_arg(ap, char *);
        !           355:        (void) vfprintf(stderr, fmt, ap);
        !           356:        va_end(ap);
        !           357:        fprintf(stderr, "\n");
        !           358: }
        !           359: 
        !           360: error(va_alist)
        !           361:        va_dcl
        !           362: {
        !           363:        char *fmt;
        !           364:        va_list ap;
        !           365: 
        !           366:        fprintf(stderr, "%s: ", program);
        !           367:        va_start(ap);
        !           368:        fmt = va_arg(ap, char *);
        !           369:        (void) vfprintf(stderr, fmt, ap);
        !           370:        va_end(ap);
        !           371:        fprintf(stderr, "\n");
        !           372: }
        !           373: 
        !           374: syserror(va_alist)
        !           375:        va_dcl
        !           376: {
        !           377:        char *fmt;
        !           378:        va_list ap;
        !           379:        extern errno;
        !           380: 
        !           381:        fprintf(stderr, "%s: ", program);
        !           382:        va_start(ap);
        !           383:        fmt = va_arg(ap, char *);
        !           384:        (void) vfprintf(stderr, fmt, ap);
        !           385:        va_end(ap);
        !           386:        fprintf(stderr, ": %s\n", strerror(errno));
        !           387: }

unix.superglobalmegacorp.com

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