1 static char *sccsid = "@(#)lastcomm.c 4.3 (Berkeley) 12/14/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 if (user_list[passwd->pw_uid][0]==0) 53 move (passwd->pw_name, user_list [passwd->pw_uid]); 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 131 time_t 132 expand (t) 133 unsigned 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 147 move (a, b) 148 char *a, *b; 149 { 150 while (*b++ = *a++); 151 } 152 153 equal (a, b) 154 char *a, *b; 155 { 156 for (;; a++, b++) 157 { 158 if (*a != *b) return no; 159 if (!*a) return yes; 160 } 161 } 162