# 2.11BSD#431 - /usr/src/ucb/lastcomm.c

##### Functions

    expand            X
    flagbits          X
    getdev            X
    getname           X
    main              X
    ok                X
    usage             X

##### Variables

    buf               X
    copyright         X
    utmp              X

##### Macros

    BIT               X
    CAMASK            X
    NCACHE            X
    NMAX              X
    SCPYN             X

##### struct's

    ncache            X

       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: #if defined(DOSCCS) && !defined(lint)
       8: char copyright[] =
       9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
      10:  All rights reserved.\n";
      11:
      12: static char sccsid[] = "@(#)lastcomm.c	5.2.4 (2.11BSD GTE) 1997/5/7";
      13: #endif
      14:
      15: /*
      16:  * lastcomm command
      17:  */
      18: #include <sys/param.h>
      19: #include <sys/acct.h>
      20: #include <sys/file.h>
      21:
      22: #include <stdio.h>
      23: #include <pwd.h>
      24: #include <sys/stat.h>
      25: #include <utmp.h>
      26: #include <struct.h>
      27: #include <ctype.h>
      28: #include <stdlib.h>
      29:
      30: struct  acct buf[DEV_BSIZE / sizeof (struct acct)];
      31:
      32: time_t  expand();
      33: char    *flagbits();
      34: char    *getname();
      35: char    *getdev();
      36:
      37: main(argc, argv)
      38:     char *argv[];
      39: {
      40:     register int bn, cc;
      41:     register struct acct *acp;
      42:     int fd, ch;
      43:     struct stat sb;
      44:     char *acctfile = "/usr/adm/acct";
      45:
      46:     while   ((ch = getopt(argc, argv, "f:")) != EOF)
      47:         {
      48:         switch  (ch)
      49:             {
      50:             case    'f':
      51:                 acctfile = optarg;
      52:                 break;
      53:             case    '?':
      54:             default:
      55:                 usage();
      56:             }
      57:         }
      58:     argc -= optind;
      59:     argv += optind;
      60:
      61:     fd = open(acctfile, O_RDONLY);
      62:     if (fd < 0)
      63:         err(1, "%s", acctfile);
      64:
      65:     fstat(fd, &sb);
      66:     for (bn = btodb(sb.st_size); bn >= 0; bn--) {
      67:         lseek(fd, (off_t)dbtob(bn), L_SET);
      68:         cc = read(fd, buf, DEV_BSIZE);
      69:         if (cc < 0) {
      70:             perror("read");
      71:             break;
      72:         }
      73:         acp = buf + (cc / sizeof (buf[0])) - 1;
      74:         for (; acp >= buf; acp--) {
      75:             register char *cp;
      76:             time_t x;
      77:
      78:             if (acp->ac_comm[0] == '\0')
      79:                 strcpy(acp->ac_comm, "?");
      80:             for (cp = &acp->ac_comm[0];
      81:                  cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp;
      82:                  cp++)
      83:                 if (!isascii(*cp) || iscntrl(*cp))
      84:                     *cp = '?';
      85:             if (*argv && !ok(argv, acp))
      86:                 continue;
      87:             x = expand(acp->ac_utime) + expand(acp->ac_stime);
      88:             printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
      89:                 fldsiz(acct, ac_comm), fldsiz(acct, ac_comm),
      90:                 acp->ac_comm,
      91:                 flagbits(acp->ac_flag),
      92:                 fldsiz(utmp, ut_name), getname(acp->ac_uid),
      93:                 fldsiz(utmp, ut_line), getdev(acp->ac_tty),
      94:                 x / (double)AHZ, ctime(&acp->ac_btime));
      95:         }
      96:     }
      97: }
      98:
      99: time_t
     100: expand (t)
     101:     unsigned t;
     102: {
     103:     register time_t nt;
     104:
     105:     nt = t & 017777;
     106:     t >>= 13;
     107:     while (t) {
     108:         t--;
     109:         nt <<= 3;
     110:     }
     111:     return (nt);
     112: }
     113:
     114: char *
     115: flagbits(f)
     116:     register int f;
     117: {
     118:     register int i = 0;
     119:     static char flags[20];
     120:
     121: #define BIT(flag, ch)   flags[i++] = (f & flag) ? ch : ' '
     122:     BIT(ASU, 'S');
     123:     BIT(AFORK, 'F');
     124:     BIT(ACOMPAT, 'C');
     125:     BIT(ACORE, 'D');
     126:     BIT(AXSIG, 'X');
     127:     flags[i] = '\0';
     128:     return (flags);
     129: }
     130:
     131: ok(argv, acp)
     132:     register char *argv[];
     133:     register struct acct *acp;
     134: {
     135:     do {
     136:         if (!strcmp(getname(acp->ac_uid), *argv))
     137:             return(1);
     138:         if (!strcmp(getdev(acp->ac_tty), *argv))
     139:             return(1);
     140:         if (!strncmp(acp->ac_comm, *argv, fldsiz(acct, ac_comm)))
     141:             return(1);
     142:     } while (*++argv);
     143:     return (0);
     144: }
     145:
     146: /* should be done with nameserver or database */
     147:
     148: struct  utmp utmp;
     149: #define NMAX    (sizeof (utmp.ut_name))
     150: #define SCPYN(a, b) strncpy(a, b, NMAX)
     151:
     152: #define NCACHE  64      /* power of 2 */
     153: #define CAMASK  NCACHE - 1
     154:
     155: char *
     156: getname(uid)
     157:     uid_t uid;
     158: {
     159:     static struct ncache {
     160:         uid_t   uid;
     161:         char    name[NMAX+1];
     162:     } c_uid[NCACHE];
     163:     register struct passwd *pw;
     164:     register struct ncache *cp;
     165:
     166:     setpassent(1);
     167:     cp = c_uid + (uid & CAMASK);
     168:     if (cp->uid == uid && *cp->name)
     169:         return(cp->name);
     170:     if (!(pw = getpwuid(uid)))
     171:         return((char *)0);
     172:     cp->uid = uid;
     173:     SCPYN(cp->name, pw->pw_name);
     174:     return(cp->name);
     175: }
     176:
     177: char *
     178: getdev(dev)
     179:     dev_t dev;
     180: {
     181:     static dev_t lastdev = (dev_t) -1;
     182:     static char *lastname;
     183:
     184:     if (dev == NODEV)       /* Special case */
     185:         return ("__");
     186:     if (dev == lastdev)     /* One-element cache. */
     187:         return (lastname);
     188:     lastdev = dev;
     189:     lastname = devname(dev, S_IFCHR);
     190:     return (lastname);
     191: }
     192:
     193: void
     194: usage()
     195:     {
     196:
     197:     (void)fprintf(stderr,
     198:         "lastcomm [ -f file ] [ command ...] [ user ...] [ tty ...]\n");
     199:     exit(1);
     200:     }

#### Defined functions

expand defined in line 99; used 3 times

- in line 32, 87(2)

flagbits defined in line 114; used 2 times

- in line 33, 91

getdev defined in line 177; used 3 times

- in line 35, 93, 138

getname defined in line 155; used 3 times

- in line 34, 92, 136

main defined in line 37; never used
ok defined in line 131; used 1 times

- in line 85

usage defined in line 193; used 1 times

- in line 55

#### Defined variables

buf defined in line 30; used 4 times

- in line 68-74(4)

copyright defined in line 8; never used
sccsid defined in line 12; never used
utmp defined in line 148; used 3 times

- in line 92-93(2), 149

#### Defined struct's

ncache defined in line 159; used 2 times

- in line 164(2)

#### Defined macros

BIT defined in line 121; used 5 times

- in line 122-126(5)

CAMASK defined in line 153; used 1 times

- in line 167

NCACHE defined in line 152; used 2 times

- in line 153, 162

NMAX defined in line 149; used 2 times

- in line 150, 161

SCPYN defined in line 150; used 1 times

- in line 173

Last modified: 1997-05-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 802 |