Annotation of 43BSD/ucb/lastcomm.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[] = "@(#)lastcomm.c 5.2 (Berkeley) 5/4/86";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * last command
        !            19:  */
        !            20: #include <sys/param.h>
        !            21: #include <sys/acct.h>
        !            22: #include <sys/file.h>
        !            23: 
        !            24: #include <stdio.h>
        !            25: #include <pwd.h>
        !            26: #include <sys/stat.h>
        !            27: #include <utmp.h>
        !            28: #include <struct.h>
        !            29: #include <ctype.h>
        !            30: 
        !            31: struct acct buf[DEV_BSIZE / sizeof (struct acct)];
        !            32: 
        !            33: time_t expand();
        !            34: char   *flagbits();
        !            35: char   *getname();
        !            36: char   *getdev();
        !            37: 
        !            38: main(argc, argv)
        !            39:        char *argv[];
        !            40: {
        !            41:        register int bn, cc;
        !            42:        register struct acct *acp;
        !            43:        int fd;
        !            44:        struct stat sb;
        !            45: 
        !            46:        fd = open("/usr/adm/acct", O_RDONLY);
        !            47:        if (fd < 0) {
        !            48:                perror("/usr/adm/acct");
        !            49:                exit(1);
        !            50:        }
        !            51:        fstat(fd, &sb);
        !            52:        for (bn = btodb(sb.st_size); bn >= 0; bn--) {
        !            53:                lseek(fd, dbtob(bn), L_SET);
        !            54:                cc = read(fd, buf, DEV_BSIZE);
        !            55:                if (cc < 0) {
        !            56:                        perror("read");
        !            57:                        break;
        !            58:                }
        !            59:                acp = buf + (cc / sizeof (buf[0])) - 1;
        !            60:                for (; acp >= buf; acp--) {
        !            61:                        register char *cp;
        !            62:                        time_t x;
        !            63: 
        !            64:                        if (acp->ac_comm[0] == '\0')
        !            65:                                strcpy(acp->ac_comm, "?");
        !            66:                        for (cp = &acp->ac_comm[0];
        !            67:                             cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp;
        !            68:                             cp++)
        !            69:                                if (!isascii(*cp) || iscntrl(*cp))
        !            70:                                        *cp = '?';
        !            71:                        if (argc > 1 && !ok(argc, argv, acp))
        !            72:                                continue;
        !            73:                        x = expand(acp->ac_utime) + expand(acp->ac_stime);
        !            74:                        printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
        !            75:                                fldsiz(acct, ac_comm), fldsiz(acct, ac_comm),
        !            76:                                acp->ac_comm,
        !            77:                                flagbits(acp->ac_flag),
        !            78:                                fldsiz(utmp, ut_name), getname(acp->ac_uid),
        !            79:                                fldsiz(utmp, ut_line), getdev(acp->ac_tty),
        !            80:                                x / (double)AHZ, ctime(&acp->ac_btime));
        !            81:                }
        !            82:        }
        !            83: }
        !            84: 
        !            85: time_t
        !            86: expand (t)
        !            87:        unsigned t;
        !            88: {
        !            89:        register time_t nt;
        !            90: 
        !            91:        nt = t & 017777;
        !            92:        t >>= 13;
        !            93:        while (t) {
        !            94:                t--;
        !            95:                nt <<= 3;
        !            96:        }
        !            97:        return (nt);
        !            98: }
        !            99: 
        !           100: char *
        !           101: flagbits(f)
        !           102:        register int f;
        !           103: {
        !           104:        register int i = 0;
        !           105:        static char flags[20];
        !           106: 
        !           107: #define BIT(flag, ch)  flags[i++] = (f & flag) ? ch : ' '
        !           108:        BIT(ASU, 'S');
        !           109:        BIT(AFORK, 'F');
        !           110:        BIT(ACOMPAT, 'C');
        !           111:        BIT(ACORE, 'D');
        !           112:        BIT(AXSIG, 'X');
        !           113:        flags[i] = '\0';
        !           114:        return (flags);
        !           115: }
        !           116: 
        !           117: ok(argc, argv, acp)
        !           118:        register int argc;
        !           119:        register char *argv[];
        !           120:        register struct acct *acp;
        !           121: {
        !           122:        register int j;
        !           123: 
        !           124:        for (j = 1; j < argc; j++)
        !           125:                if (strcmp(getname(acp->ac_uid), argv[j]) &&
        !           126:                    strcmp(getdev(acp->ac_tty), argv[j]) &&
        !           127:                    strncmp(acp->ac_comm, argv[j], fldsiz(acct, ac_comm)))
        !           128:                        break;
        !           129:        return (j == argc);
        !           130: }
        !           131: 
        !           132: /* should be done with nameserver or database */
        !           133: 
        !           134: struct utmp utmp;
        !           135: 
        !           136: #define NUID   2048
        !           137: #define        NMAX    (sizeof (utmp.ut_name))
        !           138: 
        !           139: char   names[NUID][NMAX+1];
        !           140: char   outrangename[NMAX+1];
        !           141: int    outrangeuid = -1;
        !           142: 
        !           143: char *
        !           144: getname(uid)
        !           145: {
        !           146:        register struct passwd *pw;
        !           147:        static init;
        !           148:        struct passwd *getpwent();
        !           149: 
        !           150:        if (uid >= 0 && uid < NUID && names[uid][0])
        !           151:                return (&names[uid][0]);
        !           152:        if (uid >= 0 && uid == outrangeuid)
        !           153:                return (outrangename);
        !           154:        if (init == 2) {
        !           155:                if (uid < NUID)
        !           156:                        return (0);
        !           157:                setpwent();
        !           158:                while (pw = getpwent()) {
        !           159:                        if (pw->pw_uid != uid)
        !           160:                                continue;
        !           161:                        outrangeuid = pw->pw_uid;
        !           162:                        strncpy(outrangename, pw->pw_name, NMAX);
        !           163:                        endpwent();
        !           164:                        return (outrangename);
        !           165:                }
        !           166:                endpwent();
        !           167:                return (0);
        !           168:        }
        !           169:        if (init == 0)
        !           170:                setpwent(), init = 1;
        !           171:        while (pw = getpwent()) {
        !           172:                if (pw->pw_uid < 0 || pw->pw_uid >= NUID) {
        !           173:                        if (pw->pw_uid == uid) {
        !           174:                                outrangeuid = pw->pw_uid;
        !           175:                                strncpy(outrangename, pw->pw_name, NMAX);
        !           176:                                return (outrangename);
        !           177:                        }
        !           178:                        continue;
        !           179:                }
        !           180:                if (names[pw->pw_uid][0])
        !           181:                        continue;
        !           182:                strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
        !           183:                if (pw->pw_uid == uid)
        !           184:                        return (&names[uid][0]);
        !           185:        }
        !           186:        init = 2;
        !           187:        endpwent();
        !           188:        return (0);
        !           189: }
        !           190: 
        !           191: #include <sys/dir.h>
        !           192: 
        !           193: #define N_DEVS         43              /* hash value for device names */
        !           194: #define NDEVS          500             /* max number of file names in /dev */
        !           195: 
        !           196: struct devhash {
        !           197:        dev_t   dev_dev;
        !           198:        char    dev_name [fldsiz(utmp, ut_line) + 1];
        !           199:        struct  devhash * dev_nxt;
        !           200: };
        !           201: struct devhash *dev_hash[N_DEVS];
        !           202: struct devhash *dev_chain;
        !           203: #define HASH(d)        (((int) d) % N_DEVS)
        !           204: 
        !           205: setupdevs()
        !           206: {
        !           207:        register DIR * fd;
        !           208:        register struct devhash * hashtab;
        !           209:        register ndevs = NDEVS;
        !           210:        struct direct * dp;
        !           211: 
        !           212:        if ((fd = opendir("/dev")) == NULL) {
        !           213:                perror("/dev");
        !           214:                return;
        !           215:        }
        !           216:        hashtab = (struct devhash *)malloc(NDEVS * sizeof(struct devhash));
        !           217:        if (hashtab == (struct devhash *)0) {
        !           218:                fprintf(stderr, "No mem for dev table\n");
        !           219:                closedir(fd);
        !           220:                return;
        !           221:        }
        !           222:        while (dp = readdir(fd)) {
        !           223:                if (dp->d_ino == 0)
        !           224:                        continue;
        !           225:                if (dp->d_name[0] != 't' && strcmp(dp->d_name, "console"))
        !           226:                        continue;
        !           227:                strncpy(hashtab->dev_name, dp->d_name, fldsiz(utmp, ut_line));
        !           228:                hashtab->dev_name[fldsiz(utmp, ut_line)] = 0;
        !           229:                hashtab->dev_nxt = dev_chain;
        !           230:                dev_chain = hashtab;
        !           231:                hashtab++;
        !           232:                if (--ndevs <= 0)
        !           233:                        break;
        !           234:        }
        !           235:        closedir(fd);
        !           236: }
        !           237: 
        !           238: char *
        !           239: getdev(dev)
        !           240:        dev_t dev;
        !           241: {
        !           242:        register struct devhash *hp, *nhp;
        !           243:        struct stat statb;
        !           244:        char name[fldsiz(devhash, dev_name) + 6];
        !           245:        static dev_t lastdev = (dev_t) -1;
        !           246:        static char *lastname;
        !           247:        static int init = 0;
        !           248: 
        !           249:        if (dev == NODEV)
        !           250:                return ("__");
        !           251:        if (dev == lastdev)
        !           252:                return (lastname);
        !           253:        if (!init) {
        !           254:                setupdevs();
        !           255:                init++;
        !           256:        }
        !           257:        for (hp = dev_hash[HASH(dev)]; hp; hp = hp->dev_nxt)
        !           258:                if (hp->dev_dev == dev) {
        !           259:                        lastdev = dev;
        !           260:                        return (lastname = hp->dev_name);
        !           261:                }
        !           262:        for (hp = dev_chain; hp; hp = nhp) {
        !           263:                nhp = hp->dev_nxt;
        !           264:                strcpy(name, "/dev/");
        !           265:                strcat(name, hp->dev_name);
        !           266:                if (stat(name, &statb) < 0)     /* name truncated usually */
        !           267:                        continue;
        !           268:                if ((statb.st_mode & S_IFMT) != S_IFCHR)
        !           269:                        continue;
        !           270:                hp->dev_dev = statb.st_rdev;
        !           271:                hp->dev_nxt = dev_hash[HASH(hp->dev_dev)];
        !           272:                dev_hash[HASH(hp->dev_dev)] = hp;
        !           273:                if (hp->dev_dev == dev) {
        !           274:                        dev_chain = nhp;
        !           275:                        lastdev = dev;
        !           276:                        return (lastname = hp->dev_name);
        !           277:                }
        !           278:        }
        !           279:        dev_chain = (struct devhash *) 0;
        !           280:        return ("??");
        !           281: }

unix.superglobalmegacorp.com

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