commit e4677f290b9fbc6feceda0fbe406d19a8881faae
parent 129168715207a4e28cbc276cccdf4c5ff59b2163
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 18 Aug 2014 18:24:29 +0100
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.
Diffstat:
4 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -8,6 +8,7 @@ MIT/X Consortium License
© 2014 Carlos J. Torres <vlaadbrain@gmail.com>
© 2014 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2014 Laslo Hunhold <dev@frign.de>
+© 2014 Roberto E. Vargas Caballero <k0ga@shike2.com>
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
@@ -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
@@ -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
@@ -0,0 +1,75 @@
+/* See LICENSE file for copyright and license details. */
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <utmp.h>
+
+#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;
+}