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 #include "lastcomm.h" 15 16 /* 17 * lc_pacct() provides the functionality of lastcomm when applied to the basic 18 * SVR4 accounting file, /var/adm/pacct. Definitions for this accounting file 19 * format are given in <sys/acct.h>. 20 */ 21 22 extern ulong_t expand(comp_t); 23 24 static int 25 ok(int argc, char *argv[], int index, struct acct *acp) 26 { 27 int j; 28 29 for (j = index; j < argc; j++) 30 if (strcmp(getname(acp->ac_uid), argv[j]) && 31 strcmp(getdev(acp->ac_tty), argv[j]) && 32 strncmp(acp->ac_comm, argv[j], fldsiz(acct, ac_comm))) 33 break; 34 return (j == argc); 35 } 36 37 int 38 lc_pacct(char *name, int argc, char *argv[], int index) 39 { 40 struct acct buf[NACCT]; 41 int bn, cc; 42 struct acct *acp; 43 struct stat sb; 44 time_t t; 45 int fd; 46 47 if ((fd = open(name, O_RDONLY)) < 0) { 48 perror(name); 49 return (1); 50 } 51 52 (void) fstat(fd, &sb); 53 54 if (sb.st_size % sizeof (struct acct)) { 55 (void) fprintf(stderr, gettext("lastcomm: accounting file" 56 " is corrupted\n")); 57 return (1); 58 } 59 60 for (bn = ((unsigned)sb.st_size / BUF_SIZ) + 1; bn >= 0; bn--) { 61 if (lseek(fd, (unsigned)bn * BUF_SIZ, 0) == -1) { 62 perror("lseek"); 63 return (1); 64 } 65 cc = read(fd, buf, BUF_SIZ); 66 if (cc < 0) { 67 perror("read"); 68 return (1); 69 } 70 acp = buf + (cc / sizeof (buf[0])) - 1; 71 for (; acp >= buf; acp--) { 72 char *cp; 73 ulong_t x; 74 75 if (acp->ac_flag > 0100) { 76 (void) fprintf(stderr, gettext("lastcomm: " 77 "accounting file is corrupted\n")); 78 return (1); 79 } 80 if (acp->ac_comm[0] == '\0') 81 (void) strcpy(acp->ac_comm, "?"); 82 for (cp = &acp->ac_comm[0]; 83 cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp; 84 cp++) 85 if (!isascii(*cp) || iscntrl(*cp)) 86 *cp = '?'; 87 if (argc > index && !ok(argc, argv, index, acp)) 88 continue; 89 x = expand(acp->ac_utime) + expand(acp->ac_stime); 90 t = acp->ac_btime; 91 (void) printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n", 92 fldsiz(acct, ac_comm), fldsiz(acct, ac_comm), 93 acp->ac_comm, 94 flagbits(acp->ac_flag), 95 NMAX, getname(acp->ac_uid), 96 LMAX, getdev(acp->ac_tty), 97 x / (double)HZ, ctime(&t)); 98 } 99 } 100 return (0); 101 } 102