Annotation of 43BSDTahoe/ucb/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 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[] = "@(#)lastcomm.c 5.6 (Berkeley) 6/29/88";
                     26: #endif /* not lint */
                     27: 
                     28: /*
                     29:  * last command
                     30:  */
                     31: #include <sys/param.h>
                     32: #include <sys/acct.h>
                     33: #include <sys/file.h>
                     34: #include <sys/stat.h>
                     35: #include <utmp.h>
                     36: #include <struct.h>
                     37: #include <ctype.h>
                     38: #include <stdio.h>
                     39: 
                     40: struct acct buf[DEV_BSIZE / sizeof (struct acct)];
                     41: 
                     42: time_t expand();
                     43: char   *flagbits();
                     44: char   *getname();
                     45: char   *getdev();
                     46: 
                     47: main(argc, argv)
                     48:        int argc;
                     49:        char *argv[];
                     50: {
                     51:        extern int optind;
                     52:        extern char *optarg;
                     53:        register struct acct *acp;
                     54:        register int bn, cc;
                     55:        struct stat sb;
                     56:        int ch, fd;
                     57:        char *acctfile, *strcpy(), *ctime();
                     58:        long lseek();
                     59: 
                     60:        acctfile = NULL;
                     61:        while ((ch = getopt(argc, argv, "f:")) != EOF)
                     62:                switch((char)ch) {
                     63:                case 'f':
                     64:                        acctfile = optarg;
                     65:                        break;
                     66:                case '?':
                     67:                default:
                     68:                        fputs("lastcomm [ -f file ]\n", stderr);
                     69:                        exit(1);
                     70:                }
                     71:        argv += optind;
                     72:        if (!acctfile)
                     73:                acctfile = "/usr/adm/acct";
                     74:        fd = open(acctfile, O_RDONLY);
                     75:        if (fd < 0) {
                     76:                perror(acctfile);
                     77:                exit(1);
                     78:        }
                     79:        (void)fstat(fd, &sb);
                     80:        for (bn = btodb(sb.st_size); bn >= 0; bn--) {
                     81:                (void)lseek(fd, (off_t)dbtob(bn), L_SET);
                     82:                cc = read(fd, buf, DEV_BSIZE);
                     83:                if (cc < 0) {
                     84:                        perror("read");
                     85:                        break;
                     86:                }
                     87:                acp = buf + (cc / sizeof (buf[0])) - 1;
                     88:                for (; acp >= buf; acp--) {
                     89:                        register char *cp;
                     90:                        time_t x;
                     91: 
                     92:                        if (acp->ac_comm[0] == '\0')
                     93:                                (void)strcpy(acp->ac_comm, "?");
                     94:                        for (cp = &acp->ac_comm[0];
                     95:                             cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp;
                     96:                             cp++)
                     97:                                if (!isascii(*cp) || iscntrl(*cp))
                     98:                                        *cp = '?';
                     99:                        if (*argv && !ok(argv, acp))
                    100:                                continue;
                    101:                        x = expand(acp->ac_utime) + expand(acp->ac_stime);
                    102:                        printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
                    103:                                fldsiz(acct, ac_comm),
                    104:                                fldsiz(acct, ac_comm),
                    105:                                acp->ac_comm, flagbits(acp->ac_flag),
                    106:                                fldsiz(utmp, ut_name),
                    107:                                (cp = getname(acp->ac_uid)) ? cp : "",
                    108:                                fldsiz(utmp, ut_line), 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: 
                    152:        do {
                    153:                if ((cp = getname(acp->ac_uid)) && !strcmp(cp, *argv) ||
                    154:                    (cp = getdev(acp->ac_tty)) && !strcmp(cp, *argv) ||
                    155:                    !strncmp(acp->ac_comm, *argv, fldsiz(acct, ac_comm)))
                    156:                        return(1);
                    157:        } while (*++argv);
                    158:        return(0);
                    159: }
                    160: 
                    161: /* should be done with nameserver or database */
                    162: 
                    163: #include <pwd.h>
                    164: 
                    165: struct utmp utmp;
                    166: #define        NMAX    (sizeof (utmp.ut_name))
                    167: #define SCPYN(a, b)    strncpy(a, b, NMAX)
                    168: 
                    169: #define NCACHE 64              /* power of 2 */
                    170: #define CAMASK NCACHE - 1
                    171: 
                    172: char *
                    173: getname(uid)
                    174:        uid_t uid;
                    175: {
                    176:        extern int _pw_stayopen;
                    177:        static struct ncache {
                    178:                uid_t   uid;
                    179:                char    name[NMAX+1];
                    180:        } c_uid[NCACHE];
                    181:        register struct passwd *pw;
                    182:        register struct ncache *cp;
                    183: 
                    184:        _pw_stayopen = 1;
                    185:        cp = c_uid + (uid & CAMASK);
                    186:        if (cp->uid == uid && *cp->name)
                    187:                return(cp->name);
                    188:        if (!(pw = getpwuid(uid)))
                    189:                return((char *)0);
                    190:        cp->uid = uid;
                    191:        SCPYN(cp->name, pw->pw_name);
                    192:        return(cp->name);
                    193: }
                    194: 
                    195: #include <sys/dir.h>
                    196: 
                    197: #define N_DEVS         43              /* hash value for device names */
                    198: #define NDEVS          500             /* max number of file names in /dev */
                    199: 
                    200: struct devhash {
                    201:        dev_t   dev_dev;
                    202:        char    dev_name [fldsiz(utmp, ut_line) + 1];
                    203:        struct  devhash * dev_nxt;
                    204: };
                    205: struct devhash *dev_hash[N_DEVS];
                    206: struct devhash *dev_chain;
                    207: #define HASH(d)        (((int) d) % N_DEVS)
                    208: 
                    209: setupdevs()
                    210: {
                    211:        register DIR * fd;
                    212:        register struct devhash * hashtab;
                    213:        register ndevs = NDEVS;
                    214:        struct direct * dp;
                    215:        char *malloc();
                    216: 
                    217:        /*NOSTRICT*/
                    218:        hashtab = (struct devhash *)malloc(NDEVS * sizeof(struct devhash));
                    219:        if (hashtab == (struct devhash *)0) {
                    220:                fputs("No mem for dev table\n", stderr);
                    221:                return;
                    222:        }
                    223:        if ((fd = opendir("/dev")) == NULL) {
                    224:                perror("/dev");
                    225:                return;
                    226:        }
                    227:        while (dp = readdir(fd)) {
                    228:                if (dp->d_ino == 0)
                    229:                        continue;
                    230:                if (dp->d_name[0] != 't' && strcmp(dp->d_name, "console"))
                    231:                        continue;
                    232:                strncpy(hashtab->dev_name, dp->d_name, fldsiz(utmp, ut_line));
                    233:                hashtab->dev_name[fldsiz(utmp, ut_line)] = 0;
                    234:                hashtab->dev_nxt = dev_chain;
                    235:                dev_chain = hashtab;
                    236:                hashtab++;
                    237:                if (--ndevs <= 0)
                    238:                        break;
                    239:        }
                    240:        closedir(fd);
                    241: }
                    242: 
                    243: char *
                    244: getdev(dev)
                    245:        dev_t dev;
                    246: {
                    247:        register struct devhash *hp, *nhp;
                    248:        struct stat statb;
                    249:        char name[fldsiz(devhash, dev_name) + 6];
                    250:        static dev_t lastdev = (dev_t) -1;
                    251:        static char *lastname;
                    252:        static int init = 0;
                    253:        char *strcpy(), *strcat();
                    254: 
                    255:        if (dev == NODEV)
                    256:                return ("__");
                    257:        if (dev == lastdev)
                    258:                return (lastname);
                    259:        if (!init) {
                    260:                setupdevs();
                    261:                init++;
                    262:        }
                    263:        for (hp = dev_hash[HASH(dev)]; hp; hp = hp->dev_nxt)
                    264:                if (hp->dev_dev == dev) {
                    265:                        lastdev = dev;
                    266:                        return (lastname = hp->dev_name);
                    267:                }
                    268:        for (hp = dev_chain; hp; hp = nhp) {
                    269:                nhp = hp->dev_nxt;
                    270:                strcpy(name, "/dev/");
                    271:                strcat(name, hp->dev_name);
                    272:                if (stat(name, &statb) < 0)     /* name truncated usually */
                    273:                        continue;
                    274:                if ((statb.st_mode & S_IFMT) != S_IFCHR)
                    275:                        continue;
                    276:                hp->dev_dev = statb.st_rdev;
                    277:                hp->dev_nxt = dev_hash[HASH(hp->dev_dev)];
                    278:                dev_hash[HASH(hp->dev_dev)] = hp;
                    279:                if (hp->dev_dev == dev) {
                    280:                        dev_chain = nhp;
                    281:                        lastdev = dev;
                    282:                        return (lastname = hp->dev_name);
                    283:                }
                    284:        }
                    285:        dev_chain = (struct devhash *) 0;
                    286:        return ("??");
                    287: }

unix.superglobalmegacorp.com

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