missing arg
[unix-history] / usr / src / usr.bin / lastcomm / lastcomm.c
CommitLineData
41b37529 1static char *sccsid = "@(#)lastcomm.c 4.3 (Berkeley) %G%";
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 {
41b37529 52 if (user_list[passwd->pw_uid][0]==0)
a2d7fa08 53 move (passwd->pw_name, user_list [passwd->pw_uid]);
c7eeef87
BJ
54 }
55
56 acct_desc = open ("/usr/adm/acct", 0);
57 if (acct_desc < 0)
58 {
59 perror ("/usr/adm/acct");
60 return;
61 }
62 fstat (acct_desc, &stat_buff);
63 n_blocks = (stat_buff.st_size + BUFSIZ - 1) / BUFSIZ;
64
65 /*
66 * read one block's worth
67 */
68 for (i_block = n_blocks - 1; i_block >= 0; i_block--)
69 {
70 lseek (acct_desc, i_block * BUFSIZ, 0);
71 n_byte = read (acct_desc, acct_buff, BUFSIZ);
72 n_entry = n_byte / sizeof acct_buff [0];
73 for (i = n_entry - 1; i >= 0; i--)
74 {
75 if (!*user_list [acct_buff [i].ac_uid]) continue;
76 /*
77 * get the times
78 */
79 x = expand (acct_buff [i].ac_utime)
80 +
81 expand (acct_buff [i].ac_stime);
82 /*
83 * null terminate the command name
84 */
85 acct_buff [i].ac_comm [10] = 0;
86 /*
87 * replace missing command names with question marks
88 */
89 if (!*acct_buff [i].ac_comm)
90 {
91 move ("?", acct_buff [i].ac_comm);
92 }
93 /*
94 * replace control characters with question marks
95 */
96 for (p = acct_buff [i].ac_comm; *p; p++)
97 {
98 if (*p < '!' || '~' < *p) *p = '?';
99 }
100 for (j = 1; j < argc; j++)
101 {
102 if
103 (
104 equal (acct_buff [i].ac_comm, argv [j])
105 ||
106 equal
107 (
108 user_list [acct_buff [i].ac_uid],
109 argv [j]
110 )
111 )
112 {
113 break;
114 }
115 }
116 if (argc == 1 || j != argc)
117 {
118 printf
119 (
120 "%-10s %-8s %6.2f %.16s\n",
121 acct_buff [i].ac_comm,
122 user_list [acct_buff [i].ac_uid],
123 x / 60.0,
124 ctime (&acct_buff [i].ac_btime)
125 );
126 }
127 }
128 }
129}
130
131time_t
132expand (t)
133unsigned t;
134{
135 register time_t nt;
136
137 nt = t & 017777;
138 t >>= 13;
139 while (t)
140 {
141 t--;
142 nt <<= 3;
143 }
144 return (nt);
145}
146
147move (a, b)
148char *a, *b;
149{
150 while (*b++ = *a++);
151}
152
153equal (a, b)
154char *a, *b;
155{
156 for (;; a++, b++)
157 {
158 if (*a != *b) return no;
159 if (!*a) return yes;
160 }
161}