BSD 3 development
[unix-history] / usr / src / cmd / lastcomm.c
CommitLineData
7033246b
LE
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
16struct acct acct_buff [BUFSIZ / sizeof (struct acct)];
17
18char yes = 1,
19 no = 0,
20
21 user_list [1000][9];
22
23time_t expand ();
24
25struct passwd
26 *passwd,
27 *getpwent ();
28
29struct stat stat_buff;
30
31main (argc, argv)
32char **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
129time_t
130expand (t)
131unsigned 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
145move (a, b)
146char *a, *b;
147{
148 while (*b++ = *a++);
149}
150
151equal (a, b)
152char *a, *b;
153{
154 for (;; a++, b++)
155 {
156 if (*a != *b) return no;
157 if (!*a) return yes;
158 }
159}