|
|
1.1 ! root 1: static char *sccsid = "@(#)lastcomm.c 4.1 (Berkeley) 10/1/80"; ! 2: # ! 3: ! 4: /* ! 5: * last command ! 6: */ ! 7: ! 8: # include <stdio.h> ! 9: # include <sys/types.h> ! 10: # include <sys/acct.h> ! 11: # include <signal.h> ! 12: # include <pwd.h> ! 13: # include <stat.h> ! 14: ! 15: # define N_USER 1000 ! 16: ! 17: struct acct acct_buff [BUFSIZ / sizeof (struct acct)]; ! 18: ! 19: char yes = 1, ! 20: no = 0, ! 21: ! 22: user_list [1000][9]; ! 23: ! 24: time_t expand (); ! 25: ! 26: struct passwd ! 27: *passwd, ! 28: *getpwent (); ! 29: ! 30: struct stat stat_buff; ! 31: ! 32: main (argc, argv) ! 33: char **argv; ! 34: { ! 35: char acct_desc, ! 36: *p; ! 37: ! 38: long i, ! 39: j, ! 40: i_block, ! 41: n_blocks, ! 42: n_byte, ! 43: n_entry; ! 44: ! 45: float x; ! 46: ! 47: /* ! 48: * set up user names ! 49: */ ! 50: while (passwd = getpwent ()) ! 51: { ! 52: move (passwd->pw_name, user_list [passwd->pw_uid]); ! 53: } ! 54: ! 55: acct_desc = open ("/usr/adm/acct", 0); ! 56: if (acct_desc < 0) ! 57: { ! 58: perror ("/usr/adm/acct"); ! 59: return; ! 60: } ! 61: fstat (acct_desc, &stat_buff); ! 62: n_blocks = (stat_buff.st_size + BUFSIZ - 1) / BUFSIZ; ! 63: ! 64: /* ! 65: * read one block's worth ! 66: */ ! 67: for (i_block = n_blocks - 1; i_block >= 0; i_block--) ! 68: { ! 69: lseek (acct_desc, i_block * BUFSIZ, 0); ! 70: n_byte = read (acct_desc, acct_buff, BUFSIZ); ! 71: n_entry = n_byte / sizeof acct_buff [0]; ! 72: for (i = n_entry - 1; i >= 0; i--) ! 73: { ! 74: if (!*user_list [acct_buff [i].ac_uid]) continue; ! 75: /* ! 76: * get the times ! 77: */ ! 78: x = expand (acct_buff [i].ac_utime) ! 79: + ! 80: expand (acct_buff [i].ac_stime); ! 81: /* ! 82: * null terminate the command name ! 83: */ ! 84: acct_buff [i].ac_comm [10] = 0; ! 85: /* ! 86: * replace missing command names with question marks ! 87: */ ! 88: if (!*acct_buff [i].ac_comm) ! 89: { ! 90: move ("?", acct_buff [i].ac_comm); ! 91: } ! 92: /* ! 93: * replace control characters with question marks ! 94: */ ! 95: for (p = acct_buff [i].ac_comm; *p; p++) ! 96: { ! 97: if (*p < '!' || '~' < *p) *p = '?'; ! 98: } ! 99: for (j = 1; j < argc; j++) ! 100: { ! 101: if ! 102: ( ! 103: equal (acct_buff [i].ac_comm, argv [j]) ! 104: || ! 105: equal ! 106: ( ! 107: user_list [acct_buff [i].ac_uid], ! 108: argv [j] ! 109: ) ! 110: ) ! 111: { ! 112: break; ! 113: } ! 114: } ! 115: if (argc == 1 || j != argc) ! 116: { ! 117: printf ! 118: ( ! 119: "%-10s %-8s %6.2f %.16s\n", ! 120: acct_buff [i].ac_comm, ! 121: user_list [acct_buff [i].ac_uid], ! 122: x / 60.0, ! 123: ctime (&acct_buff [i].ac_btime) ! 124: ); ! 125: } ! 126: } ! 127: } ! 128: } ! 129: ! 130: time_t ! 131: expand (t) ! 132: unsigned t; ! 133: { ! 134: register time_t nt; ! 135: ! 136: nt = t & 017777; ! 137: t >>= 13; ! 138: while (t) ! 139: { ! 140: t--; ! 141: nt <<= 3; ! 142: } ! 143: return (nt); ! 144: } ! 145: ! 146: move (a, b) ! 147: char *a, *b; ! 148: { ! 149: while (*b++ = *a++); ! 150: } ! 151: ! 152: equal (a, b) ! 153: char *a, *b; ! 154: { ! 155: for (;; a++, b++) ! 156: { ! 157: if (*a != *b) return no; ! 158: if (!*a) return yes; ! 159: } ! 160: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.