1 static char *sccsid = "@(#)lastcomm.c 4.1 (Berkeley) 10/01/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 } 161