* Copyright (c) 1980 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)lastcomm.c 5.11 (Berkeley) 6/1/90";
struct acct buf
[DEV_BSIZE
/ sizeof (struct acct
)];
register struct acct
*acp
;
char *acctfile
, *ctime(), *strcpy(), *user_from_uid();
while ((ch
= getopt(argc
, argv
, "f:")) != EOF
)
fputs("lastcomm [ -f file ]\n", stderr
);
fd
= open(acctfile
, O_RDONLY
);
for (bn
= btodb(sb
.st_size
); bn
>= 0; bn
--) {
(void)lseek(fd
, (off_t
)dbtob(bn
), L_SET
);
cc
= read(fd
, buf
, DEV_BSIZE
);
acp
= buf
+ (cc
/ sizeof (buf
[0])) - 1;
for (; acp
>= buf
; acp
--) {
if (acp
->ac_comm
[0] == '\0')
(void)strcpy(acp
->ac_comm
, "?");
for (cp
= &acp
->ac_comm
[0];
cp
< &acp
->ac_comm
[fldsiz(acct
, ac_comm
)] && *cp
;
if (!isascii(*cp
) || iscntrl(*cp
))
if (*argv
&& !ok(argv
, acp
))
x
= expand(acp
->ac_utime
) + expand(acp
->ac_stime
);
printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
fldsiz(acct
, ac_comm
), fldsiz(acct
, ac_comm
),
acp
->ac_comm
, flagbits(acp
->ac_flag
),
UT_NAMESIZE
, user_from_uid(acp
->ac_uid
, 0),
UT_LINESIZE
, getdev(acp
->ac_tty
),
x
/ (double)AHZ
, ctime(&acp
->ac_btime
));
#define BIT(flag, ch) if (f & flag) *p++ = ch;
register struct acct
*acp
;
cp
= user_from_uid(acp
->ac_uid
, 0);
if ((cp
= getdev(acp
->ac_tty
)) && !strcmp(cp
, *argv
))
if (!strncmp(acp
->ac_comm
, *argv
, fldsiz(acct
, ac_comm
)))
#define N_DEVS 43 /* hash value for device names */
#define NDEVS 500 /* max number of file names in /dev */
char dev_name
[UT_LINESIZE
+ 1];
struct devhash
* dev_nxt
;
struct devhash
*dev_hash
[N_DEVS
];
struct devhash
*dev_chain
;
#define HASH(d) (((int) d) % N_DEVS)
register struct devhash
* hashtab
;
hashtab
= (struct devhash
*)malloc(NDEVS
* sizeof(struct devhash
));
if (hashtab
== (struct devhash
*)0) {
fputs("No mem for dev table\n", stderr
);
if ((fd
= opendir(_PATH_DEV
)) == NULL
) {
while (dp
= readdir(fd
)) {
if (dp
->d_name
[0] != 't' && strcmp(dp
->d_name
, "console"))
(void)strncpy(hashtab
->dev_name
, dp
->d_name
, UT_LINESIZE
);
hashtab
->dev_name
[UT_LINESIZE
] = 0;
hashtab
->dev_nxt
= dev_chain
;
register struct devhash
*hp
, *nhp
;
char name
[fldsiz(devhash
, dev_name
) + 6];
static dev_t lastdev
= (dev_t
) -1;
char *strcpy(), *strcat();
for (hp
= dev_hash
[HASH(dev
)]; hp
; hp
= hp
->dev_nxt
)
if (hp
->dev_dev
== dev
) {
return (lastname
= hp
->dev_name
);
for (hp
= dev_chain
; hp
; hp
= nhp
) {
(void)strcpy(name
, _PATH_DEV
);
strcat(name
, hp
->dev_name
);
if (stat(name
, &statb
) < 0) /* name truncated usually */
if ((statb
.st_mode
& S_IFMT
) != S_IFCHR
)
hp
->dev_dev
= statb
.st_rdev
;
hp
->dev_nxt
= dev_hash
[HASH(hp
->dev_dev
)];
dev_hash
[HASH(hp
->dev_dev
)] = hp
;
if (hp
->dev_dev
== dev
) {
return (lastname
= hp
->dev_name
);
dev_chain
= (struct devhash
*) 0;