aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/last.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/pending/last.c')
-rw-r--r--toys/pending/last.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/toys/pending/last.c b/toys/pending/last.c
index 80d1935a..06d81ce9 100644
--- a/toys/pending/last.c
+++ b/toys/pending/last.c
@@ -18,8 +18,8 @@ config LAST
-W Display the information without host-column truncation.
-f FILE Read from file FILE instead of /var/log/wtmp.
*/
-#define FOR_last
+#define FOR_last
#include "toys.h"
#include <utmp.h>
@@ -29,6 +29,7 @@ config LAST
GLOBALS(
char *file;
+
struct arg_list *list;
)
@@ -94,7 +95,6 @@ static void seize_duration(time_t tm0, time_t tm1)
void last_main(void)
{
struct utmp ut;
- struct stat sb;
time_t tm[3] = {0,}; //array for time avlues, previous, current
char *file = "/var/log/wtmp";
int fd, pwidth, curlog_type = EMPTY;
@@ -102,31 +102,26 @@ void last_main(void)
if (toys.optflags & FLAG_f) file = TT.file;
- TT.list = NULL;
pwidth = (toys.optflags & FLAG_W) ? 46 : 16;
- time(&tm[1]);
+ *tm = time(tm+1);
fd = xopen(file, O_RDONLY);
loc = xlseek(fd, 0, SEEK_END);
- // in case of empty file or 'filesize < sizeof(ut)'
- fstat(fd, &sb);
- if (sizeof(ut) > sb.st_size) {
- xclose(fd);
- printf("\n%s begins %-24.24s\n", basename(file), ctime(&sb.st_ctime));
- return;
- }
- loc = xlseek(fd, loc - sizeof(ut), SEEK_SET);
- while (1) {
+ // Loop through file structures in reverse order.
+ for (;;) {
+ loc -= sizeof(ut);
+ if(loc < 0) break;
+ xlseek(fd, loc, SEEK_SET);
+
xreadall(fd, &ut, sizeof(ut));
- tm[0] = (time_t)ut.ut_tv.tv_sec;
- if (ut.ut_line[0] == '~') {
+ *tm = ut.ut_tv.tv_sec;
+ if (*ut.ut_line == '~') {
if (!strcmp(ut.ut_user, "runlevel")) ut.ut_type = RUN_LVL;
else if (!strcmp(ut.ut_user, "reboot")) ut.ut_type = BOOT_TIME;
else if (!strcmp(ut.ut_user, "shutdown")) ut.ut_type = SHUTDOWN_TIME;
- }
- else if (ut.ut_user[0] == '\0') ut.ut_type = DEAD_PROCESS;
- else if (ut.ut_user[0] && ut.ut_line[0] && (ut.ut_type != DEAD_PROCESS)
- && (strcmp(ut.ut_user, "LOGIN")) ) ut.ut_type = USER_PROCESS;
+ } else if (!*ut.ut_user) ut.ut_type = DEAD_PROCESS;
+ else if (*ut.ut_user && *ut.ut_line && ut.ut_type != DEAD_PROCESS
+ && strcmp(ut.ut_user, "LOGIN")) ut.ut_type = USER_PROCESS;
/* The pair of terminal names '|' / '}' logs the
* old/new system time when date changes it.
*/
@@ -134,8 +129,10 @@ void last_main(void)
if (ut.ut_line[0] == '|') ut.ut_type = OLD_TIME;
if (ut.ut_line[0] == '{') ut.ut_type = NEW_TIME;
}
- if ( (ut.ut_type == SHUTDOWN_TIME) || ((ut.ut_type == RUN_LVL) &&
- (((ut.ut_pid & 255) == '0') || ((ut.ut_pid & 255) == '6')))) {
+
+ if ((ut.ut_type == SHUTDOWN_TIME) || ((ut.ut_type == RUN_LVL) &&
+ (((ut.ut_pid & 255) == '0') || ((ut.ut_pid & 255) == '6'))))
+ {
tm[1] = tm[2] = (time_t)ut.ut_tv.tv_sec;
free_list();
curlog_type = RUN_LVL;
@@ -150,6 +147,7 @@ void last_main(void)
tm[2] = (time_t)ut.ut_tv.tv_sec;
} else if (ut.ut_type == USER_PROCESS && *ut.ut_line) {
struct arg_list *l = find_and_dlink(&TT.list, ut.ut_line);
+
if (l) {
struct utmp *u = (struct utmp *)l->arg;
seize_duration(tm[0], u->ut_tv.tv_sec);
@@ -194,10 +192,11 @@ void last_main(void)
loc -= sizeof(ut);
if(loc < 0) break;
xlseek(fd, loc, SEEK_SET);
- } // End of while.
+ }
- fflush(stdout);
xclose(fd);
+
if (CFG_TOYBOX_FREE) free_list();
- printf("\n%s begins %-24.24s\n", basename(file), ctime(&tm[0]));
+
+ xprintf("\n%s begins %-24.24s\n", basename(file), ctime(tm));
}