BSD 4 release
[unix-history] / usr / src / cmd / lastcomm.c
CommitLineData
31cef89c 1static char *sccsid = "@(#)lastcomm.c 4.1 (Berkeley) 10/1/80";
c7eeef87
BJ
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
17struct acct acct_buff [BUFSIZ / sizeof (struct acct)];
18
19char yes = 1,
20 no = 0,
21
22 user_list [1000][9];
23
24time_t expand ();
25
26struct passwd
27 *passwd,
28 *getpwent ();
29
30struct stat stat_buff;
31
32main (argc, argv)
33char **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
130time_t
131expand (t)
132unsigned 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
146move (a, b)
147char *a, *b;
148{
149 while (*b++ = *a++);
150}
151
152equal (a, b)
153char *a, *b;
154{
155 for (;; a++, b++)
156 {
157 if (*a != *b) return no;
158 if (!*a) return yes;
159 }
160}