|
|
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.