Hi sysvinit Developers,

I had a requirement to check for accounts which had not been used in a given time period; last seemed to be a useful tool to do that, but of course its output is in human-readable format and not easily parsed (or at least, not accurately).

I have therefore created the attached patch to src/last.c, against sysvinit-2.88dsf, which adds a "-e" (epoch) switch.

$ ./last -n5
steve    pts/4        :0.0             Tue Jan 22   still    logged in
steve    pts/4        hp               Tue Jan 22 - 17:15     (00:09)
steve    pts/4        hp               Tue Jan 22 - 16:31     (00:06)
steve    pts/4        :0.0             Mon Jan 21 - 23:34     (00:05)
steve    pts/5        :0.0             Mon Jan 21 - 23:34     (00:05)

wtmp begins Wed Jan  2 12:35:41 2013
$ ./last -n5 -e
steve    pts/4        :0.0             1358883350   still    logged in
steve    pts/4        hp               1358874384 1358874925  (00:09)
steve    pts/4        hp               1358871905 1358872289  (00:06)
steve    pts/4        :0.0             1358810967 1358811276  (00:05)
steve    pts/5        :0.0             1358810944 1358811276  (00:05)

wtmp begins Wed Jan  2 12:35:41 2013
$

Comments appreciated, particularly any thoughts about a better way to do the %-10.10s vs %-7.7s sprintf reformatting, and about -F being incompatible with -e - worth testing for?

Steve Parker
st...@steve-parker.org
--- lastepoch.c	2013-01-22 20:28:45.927834372 +0000
+++ last.c	2010-02-19 15:51:36.000000000 +0000
@@ -83,7 +83,6 @@
 int name_len = 8;	/* Default print 8 characters of name */
 int domain_len = 16;	/* Default print 16 characters of domain */
 int oldfmt = 0;		/* Use old libc5 format? */
-int epochfmt = 0;       /* Use epoch output format? */
 char **show = NULL;	/* What do they want us to show */
 char *ufile;		/* Filename of this file */
 time_t lastdate;	/* Last date we've seen */
@@ -133,7 +132,6 @@
 			uconv(&uto, u);
 		} else
 			r = fread(u, sizeof(struct utmp), 1, fp);
-
 		return r;
 	}
 
@@ -406,20 +404,13 @@
 	 *	Calculate times
 	 */
 	tmp = (time_t)p->ut_time;
-	if (epochfmt) 
-          sprintf(logintime, "%d", (int)tmp);
-        else
-          strcpy(logintime, ctime(&tmp));
+	strcpy(logintime, ctime(&tmp));
 	if (fulltime)
 		sprintf(logouttime, "- %s", ctime(&t));
 	else {
-             if (epochfmt) {
-                sprintf(logouttime, "%d", (int)t);
-             } else {
 		logintime[16] = 0;
 		sprintf(logouttime, "- %s", ctime(&t) + 11);
 		logouttime[7] = 0;
-             }
 	}
 	secs = t - p->ut_time;
 	mins  = (secs / 60) % 60;
@@ -490,7 +481,7 @@
 			len = snprintf(final, sizeof(final),
 				fulltime ?
 				"%-8.*s %-12.12s %-16.*s %-24.24s %-26.26s %-12.12s\n" :
-				"%-8.*s %-12.12s %-16.*s %-10.10s %-10.10s %-12.12s\n",
+				"%-8.*s %-12.12s %-16.*s %-16.16s %-7.7s %-12.12s\n",
 				name_len, p->ut_name, utline,
 				domain_len, domain, logintime, logouttime, length);
 		} else {
@@ -505,7 +496,7 @@
 		len = snprintf(final, sizeof(final),
 			fulltime ?
 			"%-8.*s %-12.12s %-24.24s %-26.26s %-12.12s\n" :
-			"%-8.*s %-12.12s %-16.16s %-10.10s %-12.12s\n",
+			"%-8.*s %-12.12s %-16.16s %-7.7s %-12.12s\n",
 			name_len, p->ut_name, utline,
 			logintime, logouttime, length);
 
@@ -543,7 +534,7 @@
 {
 	fprintf(stderr, "Usage: %s [-num | -n num] [-f file] "
 			"[-t YYYYMMDDHHMMSS] "
-			"[-R] [-adeioxFw] [username..] [tty..]\n", s);
+			"[-R] [-adioxFw] [username..] [tty..]\n", s);
 	exit(1);
 }
 
@@ -614,7 +605,7 @@
   progname = mybasename(argv[0]);
 
   /* Process the arguments. */
-  while((c = getopt(argc, argv, "ef:n:RxadFiot:0123456789w")) != EOF)
+  while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789w")) != EOF)
     switch(c) {
 	case 'R':
 		showhost = 0;
@@ -628,9 +619,6 @@
 	case 'o':
 		oldfmt = 1;
 		break;
-	case 'e': 
-	        epochfmt = 1;
-	        break;
 	case 'f':
 		if((altufile = malloc(strlen(optarg)+1)) == NULL) {
 			fprintf(stderr, "%s: out of memory\n",

Reply via email to