1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T 7 * All rights reserved. 8 * 9 * 10 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 11 * Use is subject to license terms. 12 */ 13 14 #pragma ident "%Z%%M% %I% %E% SMI" 15 16 #include "lastcomm.h" 17 18 /* 19 * lc_pacct() provides the functionality of lastcomm when applied to the basic 20 * SVR4 accounting file, /var/adm/pacct. Definitions for this accounting file 21 * format are given in <sys/acct.h>. 22 */ 23 24 extern ulong_t expand(comp_t); 25 26 static int 27 ok(int argc, char *argv[], int index, struct acct *acp) 28 { 29 int j; 30 31 for (j = index; j < argc; j++) 32 if (strcmp(getname(acp->ac_uid), argv[j]) && 33 strcmp(getdev(acp->ac_tty), argv[j]) && 34 strncmp(acp->ac_comm, argv[j], fldsiz(acct, ac_comm))) 35 break; 36 return (j == argc); 37 } 38 39 int 40 lc_pacct(char *name, int argc, char *argv[], int index) 41 { 42 struct acct buf[NACCT]; 43 int bn, cc; 44 struct acct *acp; 45 struct stat sb; 46 time_t t; 47 int fd; 48 49 if ((fd = open(name, O_RDONLY)) < 0) { 50 perror(name); 51 return (1); 52 } 53 54 (void) fstat(fd, &sb); 55 56 if (sb.st_size % sizeof (struct acct)) { 57 (void) fprintf(stderr, gettext("lastcomm: accounting file" 58 " is corrupted\n")); 59 return (1); 60 } 61 62 for (bn = ((unsigned)sb.st_size / BUF_SIZ) + 1; bn >= 0; bn--) { 63 if (lseek(fd, (unsigned)bn * BUF_SIZ, 0) == -1) { 64 perror("lseek"); 65 return (1); 66 } 67 cc = read(fd, buf, BUF_SIZ); 68 if (cc < 0) { 69 perror("read"); 70 return (1); 71 } 72 acp = buf + (cc / sizeof (buf[0])) - 1; 73 for (; acp >= buf; acp--) { 74 char *cp; 75 ulong_t x; 76 77 if (acp->ac_flag > 0100) { 78 (void) fprintf(stderr, gettext("lastcomm: " 79 "accounting file is corrupted\n")); 80 return (1); 81 } 82 if (acp->ac_comm[0] == '\0') 83 (void) strcpy(acp->ac_comm, "?"); 84 for (cp = &acp->ac_comm[0]; 85 cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp; 86 cp++) 87 if (!isascii(*cp) || iscntrl(*cp)) 88 *cp = '?'; 89 if (argc > index && !ok(argc, argv, index, acp)) 90 continue; 91 x = expand(acp->ac_utime) + expand(acp->ac_stime); 92 t = acp->ac_btime; 93 (void) printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n", 94 fldsiz(acct, ac_comm), fldsiz(acct, ac_comm), 95 acp->ac_comm, 96 flagbits(acp->ac_flag), 97 NMAX, getname(acp->ac_uid), 98 LMAX, getdev(acp->ac_tty), 99 x / (double)HZ, ctime(&t)); 100 } 101 } 102 return (0); 103 } 104