FreeBSD Bugzilla – Attachment 14402 Details for
Bug 27050
[PATCH] Add snapshot functionality to last(1)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 11.86 KB, created by
dd
on 2001-05-03 05:00:09 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
dd
Created:
2001-05-03 05:00:09 UTC
Size:
11.86 KB
patch
obsolete
>Index: last.1 >=================================================================== >RCS file: /st/src/FreeBSD/src/usr.bin/last/last.1,v >retrieving revision 1.8 >diff -u -r1.8 last.1 >--- last.1 2001/04/26 06:10:46 1.8 >+++ last.1 2001/05/03 03:34:51 >@@ -32,7 +32,7 @@ > .\" @(#)last.1 8.1 (Berkeley) 6/6/93 > .\" $FreeBSD: src/usr.bin/last/last.1,v 1.8 2001/04/26 06:10:46 dd Exp $ > .\" >-.Dd June 6, 1993 >+.Dd May 2, 2001 > .Dt LAST 1 > .Os BSD 4 > .Sh NAME >@@ -41,6 +41,15 @@ > .Sh SYNOPSIS > .Nm > .Op Fl Ns Ar n >+.Oo >+.Fl d >+.Sm off >+.Op Oo Ar CC Oc Ar YY >+.Op Ar MM DD >+.Ar hh mm >+.Op Ar .SS >+.Sm on >+.Oc > .Op Fl f Ar file > .Op Fl h Ar host > .Op Fl s >@@ -49,12 +58,13 @@ > .Op user ... > .Sh DESCRIPTION > .Nm Last >-will list the sessions of specified >+will either list the sessions of specified > .Ar users , > .Ar ttys , > and > .Ar hosts , >-in reverse time order. >+in reverse time order, >+or list the users logged in at a specified date and time. > Each line of output contains > the user name, the tty from which the session was conducted, any > hostname, the start and stop times for the session, and the duration >@@ -69,6 +79,65 @@ > Limits the report to > .Ar n > lines. >+.It Fl d Ar date >+Specify the snapshot date and time. >+All users logged in at the snapshot date and time will >+be reported. >+This may be used with the >+.Fl f >+option to derive the results from stored wtmp files. >+When this argument is provided, all other options except for >+.Fl f >+and >+.Fl Ar n >+are ignored. >+The argument should be in the form >+.Sm off >+.Op Oo Ar CC Oc Ar YY >+.Op Ar MM DD >+.Ar hh mm >+.Op Ar .SS >+.Sm on >+where each pair of letters represents the following: >+.Pp >+.Bl -tag -width Ds -compact -offset indent >+.It Ar CC >+The first two digits of the year (the century). >+.It Ar YY >+The second two digits of the year. >+If >+.Ar YY >+is specified, but >+.Ar CC >+is not, a value for >+.Ar YY >+between 69 and 99 results in a >+.Ar CC >+value of 19. >+Otherwise, a >+.Ar CC >+value of 20 is used. >+.It Ar MM >+Month of the year, from 1 to 12. >+.It Ar DD >+Day of the month, from 1 to 31. >+.It Ar hh >+Hour of the day, from 0 to 23. >+.It Ar mm >+Minute of the hour, from 0 to 59. >+.It Ar SS >+Second of the minute, from 0 to 61. >+.El >+.Pp >+If the >+.Ar CC >+and >+.Ar YY >+letter pairs are not specified, the values default to the current >+year. >+If the >+.Ar SS >+letter pair is not specified, the value defaults to 0. > .It Fl f Ar file > .Nm Last > reads the file >@@ -94,8 +163,9 @@ > default days, hours and minutes. > .El > .Pp >-If >-multiple arguments are given, the information which applies to any of the >+If multiple arguments are given, >+and a snapshot time is not specified, >+the information which applies to any of the > arguments is printed, e.g., > .Dq Li "last root -t console" > would list all of >Index: last.c >=================================================================== >RCS file: /st/src/FreeBSD/src/usr.bin/last/last.c,v >retrieving revision 1.16 >diff -u -r1.16 last.c >--- last.c 2001/03/21 19:08:01 1.16 >+++ last.c 2001/05/03 03:34:51 >@@ -62,6 +62,7 @@ > > #define NO 0 /* false/no */ > #define YES 1 /* true/yes */ >+#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; > > static struct utmp buf[1024]; /* utmp read buffer */ > >@@ -89,11 +90,16 @@ > static int sflag = 0; /* show delta in seconds */ > static int width = 5; /* show seconds in delta */ > static int d_first; >+static time_t snaptime; /* if != 0, we will only >+ * report users logged in >+ * at this snapshot time >+ */ > > void addarg __P((int, char *)); > void hostconv __P((char *)); > void onintr __P((int)); > char *ttyconv __P((char *)); >+time_t dateconv __P((char *)); > int want __P((struct utmp *)); > void wtmp __P((void)); > >@@ -117,7 +123,8 @@ > d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); > > maxrec = -1; >- while ((ch = getopt(argc, argv, "0123456789f:h:st:w")) != -1) >+ snaptime = 0; >+ while ((ch = getopt(argc, argv, "0123456789d:f:h:st:w")) != -1) > switch (ch) { > case '0': case '1': case '2': case '3': case '4': > case '5': case '6': case '7': case '8': case '9': >@@ -135,6 +142,9 @@ > exit(0); > } > break; >+ case 'd': >+ snaptime = dateconv(optarg); >+ break; > case 'f': > file = optarg; > break; >@@ -189,6 +199,7 @@ > char *crmsg; > char ct[80]; > struct tm *tm; >+ int snapfound = 0; /* found snapshot entry? */ > > LIST_INIT(&ttylist); > >@@ -220,7 +231,19 @@ > currentout = -bp->ut_time; > crmsg = strncmp(bp->ut_name, "shutdown", > UT_NAMESIZE) ? "crash" : "shutdown"; >- if (want(bp)) { >+ /* >+ * if we're in snapshot mode, we want to >+ * exit if this shutdown/reboot appears >+ * while we we are tracking the active >+ * range >+ */ >+ if (snaptime && snapfound) >+ return; >+ /* >+ * don't print shutdown/reboot entries >+ * unless flagged for >+ */ >+ if (!snaptime && want(bp)) { > tm = localtime(&bp->ut_time); > (void) strftime(ct, sizeof(ct), > d_first ? "%a %e %b %R" : >@@ -243,7 +266,7 @@ > */ > if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|') > && !bp->ut_line[1]) { >- if (want(bp)) { >+ if (want(bp) && !snaptime) { > tm = localtime(&bp->ut_time); > (void) strftime(ct, sizeof(ct), > d_first ? "%a %e %b %R" : >@@ -259,77 +282,82 @@ > } > continue; > } >- if (bp->ut_name[0] == '\0' || want(bp)) { >- /* find associated tty */ >- LIST_FOREACH(tt, &ttylist, list) >- if (!strncmp(tt->tty, bp->ut_line, UT_LINESIZE)) >- break; >- >- if (tt == NULL) { >- /* add new one */ >- tt = malloc(sizeof(struct ttytab)); >- if (tt == NULL) >- err(1, "malloc failure"); >- tt->logout = currentout; >- strncpy(tt->tty, bp->ut_line, UT_LINESIZE); >- LIST_INSERT_HEAD(&ttylist, tt, list); >- } >- >- if (bp->ut_name[0]) { >- /* >- * when uucp and ftp log in over a network, the entry in >- * the utmp file is the name plus their process id. See >- * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information. >- */ >- if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1)) >- bp->ut_line[3] = '\0'; >- else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1)) >- bp->ut_line[4] = '\0'; >- tm = localtime(&bp->ut_time); >- (void) strftime(ct, sizeof(ct), >- d_first ? "%a %e %b %R" : >- "%a %b %e %R", >- tm); >- printf("%-*.*s %-*.*s %-*.*s %s ", >- UT_NAMESIZE, UT_NAMESIZE, bp->ut_name, >- UT_LINESIZE, UT_LINESIZE, bp->ut_line, >- UT_HOSTSIZE, UT_HOSTSIZE, bp->ut_host, >- ct); >- if (!tt->logout) >- puts(" still logged in"); >+ /* find associated tty */ >+ LIST_FOREACH(tt, &ttylist, list) >+ if (!strncmp(tt->tty, bp->ut_line, UT_LINESIZE)) >+ break; >+ >+ if (tt == NULL) { >+ /* add new one */ >+ tt = malloc(sizeof(struct ttytab)); >+ if (tt == NULL) >+ err(1, "malloc failure"); >+ tt->logout = currentout; >+ strncpy(tt->tty, bp->ut_line, UT_LINESIZE); >+ LIST_INSERT_HEAD(&ttylist, tt, list); >+ } >+ >+ /* >+ * print record if not in snapshot mode and wanted >+ * or in snapshot mode and in snapshot range >+ */ >+ if (bp->ut_name[0] && (want(bp) || >+ (bp->ut_time < snaptime && >+ (tt->logout > snaptime || tt->logout < 1)))) { >+ snapfound = 1; >+ /* >+ * when uucp and ftp log in over a network, the entry in >+ * the utmp file is the name plus their process id. See >+ * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information. >+ */ >+ if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1)) >+ bp->ut_line[3] = '\0'; >+ else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1)) >+ bp->ut_line[4] = '\0'; >+ tm = localtime(&bp->ut_time); >+ (void) strftime(ct, sizeof(ct), >+ d_first ? "%a %e %b %R" : >+ "%a %b %e %R", >+ tm); >+ printf("%-*.*s %-*.*s %-*.*s %s ", >+ UT_NAMESIZE, UT_NAMESIZE, bp->ut_name, >+ UT_LINESIZE, UT_LINESIZE, bp->ut_line, >+ UT_HOSTSIZE, UT_HOSTSIZE, bp->ut_host, >+ ct); >+ if (!tt->logout) >+ puts(" still logged in"); >+ else { >+ if (tt->logout < 0) { >+ tt->logout = -tt->logout; >+ printf("- %s", crmsg); >+ } > else { >- if (tt->logout < 0) { >- tt->logout = -tt->logout; >- printf("- %s", crmsg); >- } >- else { >- tm = localtime(&tt->logout); >- (void) strftime(ct, sizeof(ct), "%R", tm); >- printf("- %s", ct); >- } >- delta = tt->logout - bp->ut_time; >- if ( sflag ) { >- printf(" (%8lu)\n", >- delta); >- } else { >- tm = gmtime(&delta); >- (void) strftime(ct, sizeof(ct), >- width >= 8 ? "%T" : "%R", >- tm); >- if (delta < 86400) >+ tm = localtime(&tt->logout); >+ (void) strftime(ct, sizeof(ct), "%R", tm); >+ printf("- %s", ct); >+ } >+ delta = tt->logout - bp->ut_time; >+ if ( sflag ) { >+ printf(" (%8lu)\n", >+ delta); >+ } else { >+ tm = gmtime(&delta); >+ (void) strftime(ct, sizeof(ct), >+ width >= 8 ? "%T" : "%R", >+ tm); >+ if (delta < 86400) > printf(" (%s)\n", ct); >- else >+ else > printf(" (%ld+%s)\n", > delta / 86400, ct); >- } > } >- LIST_REMOVE(tt, list); >- free(tt); >- if (maxrec != -1 && !--maxrec) >- return; >- } else { >- tt->logout = bp->ut_time; > } >+ LIST_REMOVE(tt, list); >+ free(tt); >+ if (maxrec != -1 && !--maxrec) >+ return; >+ } else { >+ tt->logout = bp->ut_time; > } > } > } >@@ -348,6 +376,9 @@ > { > ARG *step; > >+ if (snaptime) >+ return (NO); >+ > if (!arglist) > return (YES); > >@@ -444,6 +475,80 @@ > return (arg + 5); > return (arg); > } >+ >+/* >+ * dateconv -- >+ * Convert the snapshot time in command line given in the format >+ * [[CC]YY]MMDDhhmm[.SS]] to a time_t. >+ * Derived from atime_arg1() in usr.bin/touch/touch.c >+ */ >+time_t >+dateconv(arg) >+ char *arg; >+{ >+ time_t timet; >+ struct tm *t; >+ int yearset; >+ char *p; >+ >+ /* Start with the current time. */ >+ if (time(&timet) < 0) >+ err(1, "time"); >+ if ((t = localtime(&timet)) == NULL) >+ err(1, "localtime"); >+ >+ /* [[CC]YY]MMDDhhmm[.SS] */ >+ if ((p = strchr(arg, '.')) == NULL) >+ t->tm_sec = 0; /* Seconds defaults to 0. */ >+ else { >+ if (strlen(p + 1) != 2) >+ goto terr; >+ *p++ = '\0'; >+ t->tm_sec = ATOI2(p); >+ } >+ >+ yearset = 0; >+ switch (strlen(arg)) { >+ case 12: /* CCYYMMDDhhmm */ >+ t->tm_year = ATOI2(arg); >+ t->tm_year *= 100; >+ yearset = 1; >+ /* FALLTHOUGH */ >+ case 10: /* YYMMDDhhmm */ >+ if (yearset) { >+ yearset = ATOI2(arg); >+ t->tm_year += yearset; >+ } else { >+ yearset = ATOI2(arg); >+ if (yearset < 69) >+ t->tm_year = yearset + 2000; >+ else >+ t->tm_year = yearset + 1900; >+ } >+ t->tm_year -= 1900; /* Convert to UNIX time. */ >+ /* FALLTHROUGH */ >+ case 8: /* MMDDhhmm */ >+ t->tm_mon = ATOI2(arg); >+ --t->tm_mon; /* Convert from 01-12 to 00-11 */ >+ t->tm_mday = ATOI2(arg); >+ t->tm_hour = ATOI2(arg); >+ t->tm_min = ATOI2(arg); >+ break; >+ case 4: /* hhmm */ >+ t->tm_hour = ATOI2(arg); >+ t->tm_min = ATOI2(arg); >+ break; >+ default: >+ goto terr; >+ } >+ t->tm_isdst = -1; /* Figure out DST. */ >+ timet = mktime(t); >+ if (timet == -1) >+terr: errx(1, >+ "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]"); >+ return timet; >+} >+ > > /* > * onintr --
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 27050
: 14402