* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)lastcomm.c 5.1 (Berkeley) %G%";
struct acct buf
[DEV_BSIZE
/ sizeof (struct acct
)];
register struct acct
*acp
;
fd
= open("/usr/adm/acct", O_RDONLY
);
for (bn
= btodb(sb
.st_size
); bn
>= 0; bn
--) {
lseek(fd
, 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')
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 (argc
> 1 && !ok(argc
, 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
), acp
->ac_comm
,
fldsiz(utmp
, ut_name
), getname(acp
->ac_uid
),
fldsiz(utmp
, ut_line
), getdev(acp
->ac_tty
),
x
/ (double)AHZ
, ctime(&acp
->ac_btime
));
#define BIT(flag, ch) flags[i++] = (f & flag) ? ch : ' '
register struct acct
*acp
;
for (j
= 1; j
< argc
; j
++)
if (strcmp(getname(acp
->ac_uid
), argv
[j
]) &&
strcmp(getdev(acp
->ac_tty
), argv
[j
]) &&
strncmp(acp
->ac_comm
, argv
[j
], fldsiz(acct
, ac_comm
)))
/* should be done with nameserver or database */
#define NMAX (sizeof (utmp.ut_name))
char names
[NUID
][NMAX
+1];
char outrangename
[NMAX
+1];
register struct passwd
*pw
;
struct passwd
*getpwent();
if (uid
>= 0 && uid
< NUID
&& names
[uid
][0])
if (uid
>= 0 && uid
== outrangeuid
)
while (pw
= getpwent()) {
outrangeuid
= pw
->pw_uid
;
strncpy(outrangename
, pw
->pw_name
, NMAX
);
while (pw
= getpwent()) {
if (pw
->pw_uid
< 0 || pw
->pw_uid
>= NUID
) {
outrangeuid
= pw
->pw_uid
;
strncpy(outrangename
, pw
->pw_name
, NMAX
);
if (names
[pw
->pw_uid
][0])
strncpy(names
[pw
->pw_uid
], pw
->pw_name
, NMAX
);
#define N_DEVS 43 /* hash value for device names */
#define NDEVS 500 /* max number of file names in /dev */
char dev_name
[fldsiz(utmp
, ut_line
) + 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
;
if ((fd
= opendir("/dev")) == NULL
) {
hashtab
= (struct devhash
*)malloc(NDEVS
* sizeof(struct devhash
));
if (hashtab
== (struct devhash
*)0) {
fprintf(stderr
, "No mem for dev table\n");
while (dp
= readdir(fd
)) {
if (dp
->d_name
[0] != 't' && strcmp(dp
->d_name
, "console"))
strncpy(hashtab
->dev_name
, dp
->d_name
, fldsiz(utmp
, ut_line
));
hashtab
->dev_name
[fldsiz(utmp
, ut_line
)] = 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;
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
) {
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;