|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.