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