last - add forgotten files
authorAlex Hornung <ahornung@gmail.com>
Thu, 16 Dec 2010 17:35:43 +0000 (17:35 +0000)
committerAlex Hornung <ahornung@gmail.com>
Thu, 16 Dec 2010 17:35:43 +0000 (17:35 +0000)
usr.bin/last/last.1
usr.bin/last/want.c

index 0bb1b93..ec90a5d 100644 (file)
@@ -1,3 +1,5 @@
+.\"    $NetBSD: last.1,v 1.9 2002/09/30 11:09:04 grant Exp $
+.\"
 .\" Copyright (c) 1980, 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)last.1     8.1 (Berkeley) 6/6/93
-.\" $FreeBSD: src/usr.bin/last/last.1,v 1.6.2.8 2003/02/25 20:31:18 trhodes Exp $
-.\" $DragonFly: src/usr.bin/last/last.1,v 1.3 2006/02/17 19:39:09 swildner Exp $
 .\"
-.Dd March 1, 2002
+.Dd June 6, 1993
 .Dt LAST 1
 .Os
 .Sh NAME
 .Sh SYNOPSIS
 .Nm
 .Op Fl Ns Ar n
-.Op Fl y
-.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 T
 .Op Fl f Ar file
 .Op Fl h Ar host
-.Op Fl s
 .Op Fl t Ar tty
-.Op Fl w
-.Op Ar user ...
+.Op Fl L Ar linesize
+.Op Fl N Ar namesize
+.Op Fl H Ar hostsize
+.Op user ...
 .Sh DESCRIPTION
-The
 .Nm
-utility will either list the sessions of specified
+will list the sessions of specified
 .Ar users ,
 .Ar ttys ,
 and
 .Ar hosts ,
-in reverse time order,
-or list the users logged in at a specified date and time.
+in reverse time order.
 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
@@ -77,84 +67,24 @@ a crash or shutdown,
 .Nm
 will so indicate.
 .Pp
-The following options are available:
 .Bl -tag -width indent-two
-.It Fl Ar n
-Limit 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
-.Pa 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
-Read the file
+.Nm
+reads the file
 .Ar file
 instead of the default,
+.Pa /var/log/wtmpx
+or
 .Pa /var/log/wtmp .
-.It Fl h Ar host
-.Ar Host
-names may be names or internet numbers.
-.It Fl s
-Report the duration of the login session in seconds, instead of the
-default days, hours and minutes.
+If the file ends with `x', it is treated as a
+.Xr utmpx 5
+format file, else it is treated as a
+.Xr utmp 5
+format file.
+.It Fl Ar n
+Limits the report to
+.Ar n
+lines.
 .It Fl t Ar tty
 Specify the
 .Ar tty .
@@ -163,23 +93,27 @@ Tty names may be given fully or abbreviated, for example,
 is
 equivalent to
 .Dq Li "last -t tty03" .
-.It Fl w
-Widen the duration field to show seconds, as well as the
-default days, hours and minutes.
-.It Fl y
-Report the year in the session start time.
+.It Fl h Ar host
+.Ar Host
+names may be names or internet numbers.
+.It Fl T
+Display better time information, including the year and seconds.
+.It Fl L Ar linesize
+Use the provided linesize as the width to format the tty field.
+.It Fl N Ar namesize
+Use the provided namesize as the width to format the login name field.
+.It Fl H Ar hostsize
+Use the provided hostsize as the width to format the host name field.
 .El
 .Pp
-If multiple arguments are given,
-and a snapshot time is not specified,
-the information which applies to any of the
+If
+multiple arguments are given, the information which applies to any of the
 arguments is printed, e.g.,
 .Dq Li "last root -t console"
 would list all of
 .Dq Li root Ns 's
 sessions as well as all sessions on the console terminal.
-If no
-users, hostnames or terminals are specified,
+If no users, hostnames or terminals are specified,
 .Nm
 prints a record of
 all logins and logouts.
@@ -199,24 +133,18 @@ If interrupted with a quit signal
 indicates how
 far the search has progressed and then continues.
 .Sh FILES
-.Bl -tag -width /var/log/wtmp -compact
+.Bl -tag -width /var/log/wtmpx -compact
+.It Pa /var/log/wtmpx
+login data base
 .It Pa /var/log/wtmp
 login data base
 .El
 .Sh SEE ALSO
 .Xr lastcomm 1 ,
+.Xr utmpx 5 ,
 .Xr utmp 5 ,
 .Xr ac 8
 .Sh HISTORY
-A
 .Nm
-utility appeared in
+appeared in
 .Bx 3.0 .
-.Sh BUGS
-If a login shell should terminate abnormally for some reason, it is likely
-that a logout record won't be written to the
-.Pa wtmp
-file.
-In this case,
-.Nm
-will indicate the logout time as "shutdown".
index 8a23949..091c972 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: want.c,v 1.13 2009/04/12 13:07:21 lukem Exp $  */
+/*     $NetBSD: last.c,v 1.15 2000/06/30 06:19:58 simonb Exp $ */
 
 /*
  * Copyright (c) 1987, 1993, 1994
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -32,149 +36,58 @@ static struct utmp *buf;
 
 static void onintr(int);
 static int want(struct utmp *, int);
-static const char *gethost(struct utmp *, const char *, int);
-
-static const char *
-/*ARGSUSED*/
-gethost(struct utmp *ut, const char *host, int numeric)
-{
-#if FIRSTVALID == 0
-       return numeric ? "" : host;
-#else
-       if (numeric) {
-               static char hbuf[512];
-               hbuf[0] = '\0';
-               (void)sockaddr_snprintf(hbuf, sizeof(hbuf), "%a",
-                   (struct sockaddr *)&ut->ut_ss);
-               return hbuf;
-       } else
-               return host;
-#endif
-}
-
-#define NULTERM(what) \
-       if (check ## what) \
-               (void)strlcpy(what ## p = what ## buf, bp->ut_ ## what, \
-                   sizeof(what ## buf)); \
-       else \
-               what ## p = bp->ut_ ## what
 
 /*
  * wtmp --
  *     read through the wtmp file
  */
 void
-wtmp(const char *file, int namesz, int linesz, int hostsz, int numeric)
+wtmp(const char *file, int namesz, int linesz, int hostsz)
 {
        struct utmp     *bp;            /* current structure */
        TTY     *T;                     /* tty list entry */
        struct stat     stb;            /* stat of file for sz */
-       off_t   offset;
-       int     wfd;
-       char    *ct;
-       const char *crmsg;
+       time_t  delta;                  /* time difference */
+       off_t   bl;
+       int     bytes, wfd;
+       char    *ct, *crmsg;
        size_t  len = sizeof(*buf) * MAXUTMP;
-       char namebuf[sizeof(bp->ut_name) + 1], *namep;
-       char linebuf[sizeof(bp->ut_line) + 1], *linep;
-       char hostbuf[sizeof(bp->ut_host) + 1], *hostp;
-       int checkname = namesz > (int)sizeof(bp->ut_name);
-       int checkline = linesz > (int)sizeof(bp->ut_line);
-       int checkhost = hostsz > (int)sizeof(bp->ut_host);
 
        if ((buf = malloc(len)) == NULL)
-               err(EXIT_FAILURE, "Cannot allocate utmp buffer");
+               err(1, "Cannot allocate utmp buffer");
 
        crmsg = NULL;
 
-       if (!strcmp(file, "-")) {
-               wfd = STDIN_FILENO;
-               file = "<stdin>";
-       } else if ((wfd = open(file, O_RDONLY, 0)) < 0) {
-               err(EXIT_FAILURE, "%s", file);
-       }
-
-       if (lseek(wfd, 0, SEEK_CUR) < 0) {
-               const char *dir;
-               char *tfile;
-               int tempfd;
-               ssize_t tlen;
-
-               if (ESPIPE != errno) {
-                       err(EXIT_FAILURE, "lseek");
-               }
-               dir = getenv("TMPDIR");
-               if (asprintf(&tfile, "%s/last.XXXXXX", dir ? dir : _PATH_TMP) == -1)
-                       err(EXIT_FAILURE, "asprintf");
-               tempfd = mkstemp(tfile);
-               if (tempfd < 0) {
-                       err(EXIT_FAILURE, "mkstemp");
-               }
-               unlink(tfile);
-               for (;;) {
-                       tlen = read(wfd, buf, len);
-                       if (tlen < 0) {
-                               err(1, "%s: read", file);
-                       }
-                       if (tlen == 0) {
-                               break;
-                       }
-                       if (write(tempfd, buf, tlen) != tlen) {
-                               err(1, "%s: write", tfile);
-                       }
-               }
-               wfd = tempfd;
-       }
-
-       if (fstat(wfd, &stb) == -1)
-               err(EXIT_FAILURE, "%s: fstat", file);
-       if (!S_ISREG(stb.st_mode))
-               errx(EXIT_FAILURE, "%s: Not a regular file", file);
+       if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
+               err(1, "%s", file);
+       bl = (stb.st_size + len - 1) / len;
 
        buf[FIRSTVALID].ut_timefld = time(NULL);
        (void)signal(SIGINT, onintr);
        (void)signal(SIGQUIT, onintr);
 
-       offset = stb.st_size;
-       /* Ignore trailing garbage or partial record */
-       offset -= offset % (off_t) sizeof(*buf);
-
-       while (offset >= (off_t) sizeof(*buf)) {
-               ssize_t ret, i;
-               size_t size;
-
-               size = MIN((off_t)len, offset);
-               offset -= size; /* Always a multiple of sizeof(*buf) */
-               ret = pread(wfd, buf, size, offset);
-               if (ret < 0) {
-                       err(EXIT_FAILURE, "%s: pread", file);
-               } else if ((size_t) ret < size) {
-                       err(EXIT_FAILURE, "%s: Unexpected end of file", file);
-               }
-
-               for (i = ret / sizeof(*buf) - 1; i >= 0; i--) {
-                       bp = &buf[i];
-
-                       NULTERM(name);
-                       NULTERM(line);
-                       NULTERM(host);
+       while (--bl >= 0) {
+               if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
+                   (bytes = read(wfd, buf, len)) == -1)
+                       err(1, "%s", file);
+               for (bp = &buf[bytes / sizeof(*buf) - 1]; bp >= buf; --bp) {
                        /*
                         * if the terminal line is '~', the machine stopped.
                         * see utmp(5) for more info.
                         */
-                       if (linep[0] == '~' && !linep[1]) {
+                       if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
                                /* everybody just logged out */
                                for (T = ttylist; T; T = T->next)
                                        T->logout = -bp->ut_timefld;
                                currentout = -bp->ut_timefld;
-                               crmsg = strncmp(namep, "shutdown",
+                               crmsg = strncmp(bp->ut_name, "shutdown",
                                    namesz) ? "crash" : "shutdown";
                                if (want(bp, NO)) {
                                        ct = fmttime(bp->ut_timefld, fulltime);
                                        printf("%-*.*s  %-*.*s %-*.*s %s\n",
-                                           namesz, namesz, namep,
-                                           linesz, linesz, linep,
-                                           hostsz, hostsz,
-                                           gethost(bp, hostp, numeric), ct);
+                                           namesz, namesz, bp->ut_name,
+                                           linesz, linesz, bp->ut_line,
+                                           hostsz, hostsz, bp->ut_host, ct);
                                        if (maxrec != -1 && !--maxrec)
                                                return;
                                }
@@ -184,15 +97,18 @@ wtmp(const char *file, int namesz, int linesz, int hostsz, int numeric)
                         * if the line is '{' or '|', date got set; see
                         * utmp(5) for more info.
                         */
-                       if ((linep[0] == '{' || linep[0] == '|') && !linep[1]) {
+                       if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
+                           && !bp->ut_line[1]) {
                                if (want(bp, NO)) {
                                        ct = fmttime(bp->ut_timefld, fulltime);
-                                       printf("%-*.*s  %-*.*s %-*.*s %s\n",
-                                           namesz, namesz, namep,
-                                           linesz, linesz, linep,
-                                           hostsz, hostsz,
-                                           gethost(bp, hostp, numeric),
-                                           ct);
+                               printf("%-*.*s  %-*.*s %-*.*s %s\n",
+                                   namesz, namesz,
+                                   bp->ut_name,
+                                   linesz, linesz,
+                                   bp->ut_line,
+                                   hostsz, hostsz,
+                                   bp->ut_host,
+                                   ct);
                                        if (maxrec && !--maxrec)
                                                return;
                                }
@@ -202,27 +118,24 @@ wtmp(const char *file, int namesz, int linesz, int hostsz, int numeric)
                        for (T = ttylist;; T = T->next) {
                                if (!T) {
                                        /* add new one */
-                                       T = addtty(linep);
+                                       T = addtty(bp->ut_line);
                                        break;
                                }
-                               if (!strncmp(T->tty, linep, LINESIZE))
+                               if (!strncmp(T->tty, bp->ut_line, LINESIZE))
                                        break;
                        }
                        if (TYPE(bp) == SIGNATURE)
                                continue;
-                       if (namep[0] && want(bp, YES)) {
+                       if (bp->ut_name[0] && want(bp, YES)) {
                                ct = fmttime(bp->ut_timefld, fulltime);
                                printf("%-*.*s  %-*.*s %-*.*s %s ",
-                                   namesz, namesz, namep,
-                                   linesz, linesz, linep,
-                                   hostsz, hostsz,
-                                   gethost(bp, hostp, numeric),
+                                   namesz, namesz, bp->ut_name,
+                                   linesz, linesz, bp->ut_line,
+                                   hostsz, hostsz, bp->ut_host,
                                    ct);
                                if (!T->logout)
                                        puts("  still logged in");
                                else {
-                                       time_t  delta;                  /* time difference */
-
                                        if (T->logout < 0) {
                                                T->logout = -T->logout;
                                                printf("- %s", crmsg);
@@ -237,8 +150,7 @@ wtmp(const char *file, int namesz, int linesz, int hostsz, int numeric)
                                                    fmttime(delta,
                                                    fulltime | TIMEONLY | GMT));
                                        else
-                                               printf(" (%lld+%s)\n",
-                                                   (long long)
+                                               printf(" (%ld+%s)\n",
                                                    delta / SECSPERDAY,
                                                    fmttime(delta,
                                                    fulltime | TIMEONLY | GMT));
@@ -304,12 +216,10 @@ want(struct utmp *bp, int check)
 static void
 onintr(int signo)
 {
-       /* FIXME: None of this is allowed in a signal handler */
+
        printf("\ninterrupted %s\n", fmttime(buf[FIRSTVALID].ut_timefld,
            FULLTIME));
-       if (signo == SIGINT) {
-               (void)raise_default_signal(signo);
-               exit(EXIT_FAILURE);
-       }
+       if (signo == SIGINT)
+               exit(1);
        (void)fflush(stdout);           /* fix required for rsh */
 }