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

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

unix.superglobalmegacorp.com

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