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