/* Print lastlog entries. */
/* brg Wed Aug 13 21:54:49 CDT 2003 */

#include <sys/types.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <utmp.h>
#include <unistd.h>
#include <pwd.h>

void
for_each_pwent(void (*fn) (struct passwd *))
{
	struct passwd  *pw;
	setpassent(1);
	while ((pw = getpwent()) != NULL) {
		fn(pw);
	}
	endpwent();
}

FILE           *fp;

void
print_lastlog_entry(struct passwd * pw)
{
	/* meowwwwwwwwww; */
	struct lastlog  l;
	char            line[1 + UT_LINESIZE];
	char            host[1 + UT_HOSTSIZE];
	char            timestr[25];
	struct tm      *t;
	if (fseek(fp, pw->pw_uid * sizeof(struct lastlog), SEEK_SET) == 0) {
		fread(&l, sizeof(l), 1, fp);
		strncpy(line, l.ll_line, UT_LINESIZE);
		line[UT_LINESIZE] = '\0';
		strncpy(host, l.ll_host, UT_HOSTSIZE);
		host[UT_HOSTSIZE] = '\0';
		t = localtime(&l.ll_time);
		strftime(timestr, sizeof(timestr), "%Y-%m-%d %T", t);
		printf("%-8s %-8s %-16s %-32s\n", pw->pw_name, line, host, timestr);
	} else {
		printf("%-8s   ** error **\n", pw->pw_name);
	}
}

void
usage(void)
{
	fprintf(stderr, "Usage: lastlog [-f file] [username]\n");
	exit(1);
}

int
main(int argc, char **argv)
{
	char           *filename = _PATH_LASTLOG;
	char            ch;
	char           *user = NULL;

	while ((ch = getopt(argc, argv, "f:")) != -1)
		switch (ch) {
		case 'f':
			filename = optarg;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc == 1) {
		user = argv[0];
	}
	fp = fopen(filename, "rb");
	if (!fp) {
		perror(filename);
		return 1;
	}
	if (user) {
		struct passwd  *pw;
		pw = getpwnam(user);
		if (!pw) {
			fprintf(stderr, "%s: user unknown\n", user);
			return 1;
		}
		print_lastlog_entry(pw);
	} else {
		for_each_pwent(print_lastlog_entry);
	}
	fclose(fp);
	return 0;
}
