/* vi: set sw=4 ts=4: */
/*
 * (sysvinit like) last implementation
 *
 * Copyright (C) 2008 by Patricia Muscalu <patricia.muscalu@axis.com>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

#include "libbb.h"

/* NB: ut_name and ut_user are the same field, use only one name (ut_user)
 * to reduce confusion */

#ifndef SHUTDOWN_TIME
#  define SHUTDOWN_TIME 254
#endif

#define HEADER_FORMAT     "%-8.8s %-12.12s %-*.*s %-16.16s %-7.7s %s\n"
#define HEADER_LINE       "USER", "TTY", \
	INET_ADDRSTRLEN, INET_ADDRSTRLEN, "HOST", "LOGIN", "  TIME", ""
#define HEADER_LINE_WIDE  "USER", "TTY", \
	INET6_ADDRSTRLEN, INET6_ADDRSTRLEN, "HOST", "LOGIN", "  TIME", ""

enum {
	NORMAL,
	LOGGED,
	DOWN,
	REBOOT,
	CRASH,
	GONE
};

enum {
	LAST_OPT_W = (1 << 0),  /* -W wide            */
	LAST_OPT_f = (1 << 1),  /* -f input file      */
	LAST_OPT_H = (1 << 2),  /* -H header          */
};

#define show_wide (option_mask32 & LAST_OPT_W)

static void show_entry(struct utmp *ut, int state, time_t dur_secs)
{
	unsigned days, hours, mins;
	char duration[32];
	char login_time[17];
	char logout_time[8];
	const char *logout_str;
	const char *duration_str;
	time_t tmp;

	/* manpages say ut_tv.tv_sec *is* time_t,
	 * but some systems have it wrong */
	tmp = ut->ut_tv.tv_sec;
	safe_strncpy(login_time, ctime(&tmp), 17);
	snprintf(logout_time, 8, "- %s", ctime(&dur_secs) + 11);

	dur_secs = MAX(dur_secs - (time_t)ut->ut_tv.tv_sec, (time_t)0);
	/* unsigned int is easier to divide than time_t (which may be signed long) */
	mins = dur_secs / 60;
	days = mins / (24*60);
	mins = mins % (24*60);
	hours = mins / 60;
	mins = mins % 60;

//	if (days) {
		sprintf(duration, "(%u+%02u:%02u)", days, hours, mins);
//	} else {
//		sprintf(duration, " (%02u:%02u)", hours, mins);
//	}

	logout_str = logout_time;
	duration_str = duration;
	switch (state) {
	case NORMAL:
		break;
	case LOGGED:
		logout_str = "  still";
		duration_str = "logged in";
		break;
	case DOWN:
		logout_str = "- down ";
		break;
	case REBOOT:
		break;
	case CRASH:
		logout_str = "- crash";
		break;
	case GONE:
		logout_str = "   gone";
		duration_str = "- no logout";
		break;
	}

	printf(HEADER_FORMAT,
		   ut->ut_user,
		   ut->ut_line,
		   show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN,
		   show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN,
		   ut->ut_host,
		   login_time,
		   logout_str,
		   duration_str);
}

static int get_ut_type(struct utmp *ut)
{
	if (ut->ut_line[0] == '~') {
		if (strcmp(ut->ut_user, "shutdown") == 0) {
			return SHUTDOWN_TIME;
		}
		if (strcmp(ut->ut_user, "reboot") == 0) {
			return BOOT_TIME;
		}
		if (strcmp(ut->ut_user, "runlevel") == 0) {
			return RUN_LVL;
		}
		return ut->ut_type;
	}

	if (ut->ut_user[0] == 0) {
		return DEAD_PROCESS;
	}

	if ((ut->ut_type != DEAD_PROCESS)
	 && (strcmp(ut->ut_user, "LOGIN") != 0)
	 && ut->ut_user[0]
	 && ut->ut_line[0]
	) {
		ut->ut_type = USER_PROCESS;
	}

	if (strcmp(ut->ut_user, "date") == 0) {
		if (ut->ut_line[0] == '|') {
			return OLD_TIME;
		}
		if (ut->ut_line[0] == '{') {
			return NEW_TIME;
		}
	}
	return ut->ut_type;
}

static int is_runlevel_shutdown(struct utmp *ut)
{
	if (((ut->ut_pid & 255) == '0') || ((ut->ut_pid & 255) == '6')) {
		return 1;
	}

	return 0;
}

int last_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int last_main(int argc UNUSED_PARAM, char **argv)
{
	struct utmp ut;
	const char *filename = _PATH_WTMP;
	llist_t *zlist;
	off_t pos;
	time_t start_time;
	time_t boot_time;
	time_t down_time;
	int file;
	unsigned opt;
	smallint going_down;
	smallint boot_down;

	opt = getopt32(argv, "Wf:" /* "H" */, &filename);
#ifdef BUT_UTIL_LINUX_LAST_HAS_NO_SUCH_OPT
	if (opt & LAST_OPT_H) {
		/* Print header line */
		if (opt & LAST_OPT_W) {
			printf(HEADER_FORMAT, HEADER_LINE_WIDE);
		} else {
			printf(HEADER_FORMAT, HEADER_LINE);
		}
	}
#endif

	file = xopen(filename, O_RDONLY);
	{
		/* in case the file is empty... */
		struct stat st;
		fstat(file, &st);
		start_time = st.st_ctime;
	}

	time(&down_time);
	going_down = 0;
	boot_down = NORMAL; /* 0 */
	zlist = NULL;
	boot_time = 0;
	/* get file size, rounding down to last full record */
	pos = xlseek(file, 0, SEEK_END) / sizeof(ut) * sizeof(ut);
	for (;;) {
		pos -= (off_t)sizeof(ut);
		if (pos < 0) {
			/* Beyond the beginning of the file boundary =>
			 * the whole file has been read. */
			break;
		}
		xlseek(file, pos, SEEK_SET);
		xread(file, &ut, sizeof(ut));
		/* rewritten by each record, eventially will have
		 * first record's ut_tv.tv_sec: */
		start_time = ut.ut_tv.tv_sec;

		switch (get_ut_type(&ut)) {
		case SHUTDOWN_TIME:
			down_time = ut.ut_tv.tv_sec;
			boot_down = DOWN;
			going_down = 1;
			break;
		case RUN_LVL:
			if (is_runlevel_shutdown(&ut)) {
				down_time = ut.ut_tv.tv_sec;
				going_down = 1;
				boot_down = DOWN;
			}
			break;
		case BOOT_TIME:
			strcpy(ut.ut_line, "system boot");
			show_entry(&ut, REBOOT, down_time);
			boot_down = CRASH;
			going_down = 1;
			break;
		case DEAD_PROCESS:
			if (!ut.ut_line[0]) {
				break;
			}
			/* add_entry */
			llist_add_to(&zlist, memcpy(xmalloc(sizeof(ut)), &ut, sizeof(ut)));
			break;
		case USER_PROCESS: {
			int show;

			if (!ut.ut_line[0]) {
				break;
			}
			/* find_entry */
			show = 1;
			{
				llist_t *el, *next;
				for (el = zlist; el; el = next) {
					struct utmp *up = (struct utmp *)el->data;
					next = el->link;
					if (strncmp(up->ut_line, ut.ut_line, UT_LINESIZE) == 0) {
						if (show) {
							show_entry(&ut, NORMAL, up->ut_tv.tv_sec);
							show = 0;
						}
						llist_unlink(&zlist, el);
						free(el->data);
						free(el);
					}
				}
			}

			if (show) {
				int state = boot_down;

				if (boot_time == 0) {
					state = LOGGED;
					/* Check if the process is alive */
					if ((ut.ut_pid > 0)
					 && (kill(ut.ut_pid, 0) != 0)
					 && (errno == ESRCH)) {
						state = GONE;
					}
				}
				show_entry(&ut, state, boot_time);
			}
			/* add_entry */
			llist_add_to(&zlist, memcpy(xmalloc(sizeof(ut)), &ut, sizeof(ut)));
			break;
		}
		}

		if (going_down) {
			boot_time = ut.ut_tv.tv_sec;
			llist_free(zlist, free);
			zlist = NULL;
			going_down = 0;
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		llist_free(zlist, free);
	}

	printf("\nwtmp begins %s", ctime(&start_time));

	if (ENABLE_FEATURE_CLEAN_UP)
		close(file);
	fflush_stdout_and_exit(EXIT_SUCCESS);
}
