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
flagbits defined in line 114; used 2 times
getdev defined in line 177; used 3 times
getname defined in line 155; used 3 times
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
copyright defined in line 8; never used
sccsid defined in line 12; never used
utmp defined in line 148; used 3 times

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
CAMASK defined in line 153; used 1 times
NCACHE defined in line 152; used 2 times
NMAX defined in line 149; used 2 times
SCPYN defined in line 150; used 1 times
Last modified: 1997-05-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3414
Valid CSS Valid XHTML 1.0 Strict