From e4677f290b9fbc6feceda0fbe406d19a8881faae Mon Sep 17 00:00:00 2001 From: "Roberto E. Vargas Caballero" Date: Mon, 18 Aug 2014 18:24:29 +0100 Subject: [PATCH] Add lastlog(8) At the moment this does not work with ubase login(1). We should add support to login(1) to write the lastlog entries. Minor modifications by sin. --- LICENSE | 1 + Makefile | 2 ++ lastlog.8 | 11 ++++++++ lastlog.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 lastlog.8 create mode 100644 lastlog.c diff --git a/LICENSE b/LICENSE index ed2376d..29531aa 100644 --- a/LICENSE +++ b/LICENSE @@ -8,6 +8,7 @@ MIT/X Consortium License © 2014 Carlos J. Torres © 2014 Hiltjo Posthuma © 2014 Laslo Hunhold +© 2014 Roberto E. Vargas Caballero Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Makefile b/Makefile index 5a3f0fd..9350306 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ LIB = \ util/tty.o SRC = \ + lastlog.c \ chvt.c \ clear.c \ ctrlaltdel.c \ @@ -115,6 +116,7 @@ MAN8 = \ hwclock.8 \ insmod.8 \ killall5.8 \ + lastlog.8 \ lsmod.8 \ lsusb.8 \ mkswap.8 \ diff --git a/lastlog.8 b/lastlog.8 new file mode 100644 index 0000000..e71f9ea --- /dev/null +++ b/lastlog.8 @@ -0,0 +1,11 @@ +.TH LASTLOG 8 ubase-VERSION +.SH NAME +\fBlastlog\fR - Show last login of users +.SH SYPNOSIS +\fBlastlog\fI [user ...] +.SH DESCRIPTION +\fBlastlog\fR Show time, tty, and host (if it was a remote +connection) of last login of users. If some user names are passed +as parameter then information about last login of these users is +shown, otherwise is shown for all the users in /etc/passwd in the +order they appear in it. diff --git a/lastlog.c b/lastlog.c new file mode 100644 index 0000000..0c3cefa --- /dev/null +++ b/lastlog.c @@ -0,0 +1,75 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include + +#define PASSWD "/etc/passwd" + +static FILE *last; + +static void +lastlog(char *user) +{ + struct passwd *pwd; + struct lastlog ll; + time_t lltime; + + if ((pwd = getpwnam(user)) == NULL) { + fprintf(stderr, "unknown user: %s\n", user); + return; + } + + fseek(last, pwd->pw_uid * sizeof(struct lastlog), 0); + fread(&ll, sizeof(struct lastlog), 1, last); + + if (ferror(last)) { + perror("error reading lastlog"); + exit(EXIT_FAILURE); + } + + /* on glibc `ll_time' can be an int32_t with compat32 + * avoid compiler warning when calling ctime() */ + lltime = ll.ll_time; + printf("%-8.8s %-8.8s %-16.16s %s", + user, ll.ll_line, ll.ll_host, ctime(&lltime)); +} + +int +main(int argc, char **argv) +{ + FILE *fp; + char line[512], *p; + + if ((last = fopen(_PATH_LASTLOG, "r")) == NULL) { + perror(_PATH_LASTLOG); + exit(EXIT_FAILURE); + } + + if (argc > 1) { + while (*++argv) + lastlog(*argv); + } else { + if ((fp = fopen(PASSWD, "r")) == NULL) { + perror(PASSWD); + exit(EXIT_FAILURE); + } + while ((fgets(line, sizeof(line), fp)) != NULL) { + if ((p = strchr(line, ':')) == NULL) { + fputs("incorrect password file", stderr); + exit(-1); + } + *p = '\0'; + lastlog(line); + } + if (fclose(fp)) + perror(PASSWD); + } + + fclose(last); + + return EXIT_SUCCESS; +}