Annotation of 43BSDReno/usr.bin/lastcomm/lastcomm.c, revision 1.1.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: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: char copyright[] =
                     22: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
                     23:  All rights reserved.\n";
                     24: #endif /* not lint */
                     25: 
                     26: #ifndef lint
                     27: static char sccsid[] = "@(#)lastcomm.c 5.11 (Berkeley) 6/1/90";
                     28: #endif /* not lint */
                     29: 
                     30: /*
                     31:  * last command
                     32:  */
                     33: #include <sys/param.h>
                     34: #include <sys/acct.h>
                     35: #include <sys/file.h>
                     36: #include <sys/stat.h>
                     37: #include <utmp.h>
                     38: #include <struct.h>
                     39: #include <ctype.h>
                     40: #include <stdio.h>
                     41: #include "pathnames.h"
                     42: 
                     43: struct acct buf[DEV_BSIZE / sizeof (struct acct)];
                     44: 
                     45: time_t expand();
                     46: char   *flagbits();
                     47: char   *getdev();
                     48: 
                     49: main(argc, argv)
                     50:        int argc;
                     51:        char *argv[];
                     52: {
                     53:        extern int optind;
                     54:        extern char *optarg;
                     55:        register struct acct *acp;
                     56:        register int bn, cc;
                     57:        struct stat sb;
                     58:        int ch, fd;
                     59:        char *acctfile, *ctime(), *strcpy(), *user_from_uid();
                     60:        long lseek();
                     61: 
                     62:        acctfile = _PATH_ACCT;
                     63:        while ((ch = getopt(argc, argv, "f:")) != EOF)
                     64:                switch((char)ch) {
                     65:                case 'f':
                     66:                        acctfile = optarg;
                     67:                        break;
                     68:                case '?':
                     69:                default:
                     70:                        fputs("lastcomm [ -f file ]\n", stderr);
                     71:                        exit(1);
                     72:                }
                     73:        argv += optind;
                     74: 
                     75:        fd = open(acctfile, O_RDONLY);
                     76:        if (fd < 0) {
                     77:                perror(acctfile);
                     78:                exit(1);
                     79:        }
                     80:        (void)fstat(fd, &sb);
                     81:        setpassent(1);
                     82:        for (bn = btodb(sb.st_size); bn >= 0; bn--) {
                     83:                (void)lseek(fd, (off_t)dbtob(bn), L_SET);
                     84:                cc = read(fd, buf, DEV_BSIZE);
                     85:                if (cc < 0) {
                     86:                        perror("read");
                     87:                        break;
                     88:                }
                     89:                acp = buf + (cc / sizeof (buf[0])) - 1;
                     90:                for (; acp >= buf; acp--) {
                     91:                        register char *cp;
                     92:                        time_t x;
                     93: 
                     94:                        if (acp->ac_comm[0] == '\0')
                     95:                                (void)strcpy(acp->ac_comm, "?");
                     96:                        for (cp = &acp->ac_comm[0];
                     97:                             cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp;
                     98:                             cp++)
                     99:                                if (!isascii(*cp) || iscntrl(*cp))
                    100:                                        *cp = '?';
                    101:                        if (*argv && !ok(argv, acp))
                    102:                                continue;
                    103:                        x = expand(acp->ac_utime) + expand(acp->ac_stime);
                    104:                        printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
                    105:                                fldsiz(acct, ac_comm), fldsiz(acct, ac_comm),
                    106:                                acp->ac_comm, flagbits(acp->ac_flag),
                    107:                                UT_NAMESIZE, user_from_uid(acp->ac_uid, 0),
                    108:                                UT_LINESIZE, getdev(acp->ac_tty),
                    109:                                x / (double)AHZ, ctime(&acp->ac_btime));
                    110:                }
                    111:        }
                    112: }
                    113: 
                    114: time_t
                    115: expand (t)
                    116:        unsigned t;
                    117: {
                    118:        register time_t nt;
                    119: 
                    120:        nt = t & 017777;
                    121:        t >>= 13;
                    122:        while (t) {
                    123:                t--;
                    124:                nt <<= 3;
                    125:        }
                    126:        return (nt);
                    127: }
                    128: 
                    129: char *
                    130: flagbits(f)
                    131:        register int f;
                    132: {
                    133:        static char flags[20];
                    134:        char *p, *strcpy();
                    135: 
                    136: #define        BIT(flag, ch)   if (f & flag) *p++ = ch;
                    137:        p = strcpy(flags, "-    ");
                    138:        BIT(ASU, 'S');
                    139:        BIT(AFORK, 'F');
                    140:        BIT(ACOMPAT, 'C');
                    141:        BIT(ACORE, 'D');
                    142:        BIT(AXSIG, 'X');
                    143:        return (flags);
                    144: }
                    145: 
                    146: ok(argv, acp)
                    147:        register char *argv[];
                    148:        register struct acct *acp;
                    149: {
                    150:        register char *cp;
                    151:        char *user_from_uid();
                    152: 
                    153:        do {
                    154:                cp = user_from_uid(acp->ac_uid, 0);
                    155:                if (!strcmp(cp, *argv)) 
                    156:                        return(1);
                    157:                if ((cp = getdev(acp->ac_tty)) && !strcmp(cp, *argv))
                    158:                        return(1);
                    159:                if (!strncmp(acp->ac_comm, *argv, fldsiz(acct, ac_comm)))
                    160:                        return(1);
                    161:        } while (*++argv);
                    162:        return(0);
                    163: }
                    164: 
                    165: #include <sys/dir.h>
                    166: 
                    167: #define N_DEVS         43              /* hash value for device names */
                    168: #define NDEVS          500             /* max number of file names in /dev */
                    169: 
                    170: struct devhash {
                    171:        dev_t   dev_dev;
                    172:        char    dev_name [UT_LINESIZE + 1];
                    173:        struct  devhash * dev_nxt;
                    174: };
                    175: struct devhash *dev_hash[N_DEVS];
                    176: struct devhash *dev_chain;
                    177: #define HASH(d)        (((int) d) % N_DEVS)
                    178: 
                    179: setupdevs()
                    180: {
                    181:        register DIR * fd;
                    182:        register struct devhash * hashtab;
                    183:        register ndevs = NDEVS;
                    184:        struct direct * dp;
                    185:        char *malloc();
                    186: 
                    187:        /*NOSTRICT*/
                    188:        hashtab = (struct devhash *)malloc(NDEVS * sizeof(struct devhash));
                    189:        if (hashtab == (struct devhash *)0) {
                    190:                fputs("No mem for dev table\n", stderr);
                    191:                return;
                    192:        }
                    193:        if ((fd = opendir(_PATH_DEV)) == NULL) {
                    194:                perror(_PATH_DEV);
                    195:                return;
                    196:        }
                    197:        while (dp = readdir(fd)) {
                    198:                if (dp->d_ino == 0)
                    199:                        continue;
                    200:                if (dp->d_name[0] != 't' && strcmp(dp->d_name, "console"))
                    201:                        continue;
                    202:                (void)strncpy(hashtab->dev_name, dp->d_name, UT_LINESIZE);
                    203:                hashtab->dev_name[UT_LINESIZE] = 0;
                    204:                hashtab->dev_nxt = dev_chain;
                    205:                dev_chain = hashtab;
                    206:                hashtab++;
                    207:                if (--ndevs <= 0)
                    208:                        break;
                    209:        }
                    210:        closedir(fd);
                    211: }
                    212: 
                    213: char *
                    214: getdev(dev)
                    215:        dev_t dev;
                    216: {
                    217:        register struct devhash *hp, *nhp;
                    218:        struct stat statb;
                    219:        char name[fldsiz(devhash, dev_name) + 6];
                    220:        static dev_t lastdev = (dev_t) -1;
                    221:        static char *lastname;
                    222:        static int init = 0;
                    223:        char *strcpy(), *strcat();
                    224: 
                    225:        if (dev == NODEV)
                    226:                return ("__");
                    227:        if (dev == lastdev)
                    228:                return (lastname);
                    229:        if (!init) {
                    230:                setupdevs();
                    231:                init++;
                    232:        }
                    233:        for (hp = dev_hash[HASH(dev)]; hp; hp = hp->dev_nxt)
                    234:                if (hp->dev_dev == dev) {
                    235:                        lastdev = dev;
                    236:                        return (lastname = hp->dev_name);
                    237:                }
                    238:        for (hp = dev_chain; hp; hp = nhp) {
                    239:                nhp = hp->dev_nxt;
                    240:                (void)strcpy(name, _PATH_DEV);
                    241:                strcat(name, hp->dev_name);
                    242:                if (stat(name, &statb) < 0)     /* name truncated usually */
                    243:                        continue;
                    244:                if ((statb.st_mode & S_IFMT) != S_IFCHR)
                    245:                        continue;
                    246:                hp->dev_dev = statb.st_rdev;
                    247:                hp->dev_nxt = dev_hash[HASH(hp->dev_dev)];
                    248:                dev_hash[HASH(hp->dev_dev)] = hp;
                    249:                if (hp->dev_dev == dev) {
                    250:                        dev_chain = nhp;
                    251:                        lastdev = dev;
                    252:                        return (lastname = hp->dev_name);
                    253:                }
                    254:        }
                    255:        dev_chain = (struct devhash *) 0;
                    256:        return ("??");
                    257: }

unix.superglobalmegacorp.com

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