Author: ed
Date: Mon Jun  6 18:40:01 2011
New Revision: 222767
URL: http://svn.freebsd.org/changeset/base/222767

Log:
  Allow custom files to be opened and allow sorting by timestamp.
  
  While implementing a tool to import lastlog entries into utmpx, I
  noticed lastlogin doesn't allow custom database files to be opened. Add
  a -f switch to support this. Also, add -r and -t similar to ls(1),
  ruptime(1), etc. where you can sort entries by timestamp and reverse
  them. This allows you to spot active/idle users more easily.

Modified:
  head/usr.sbin/lastlogin/lastlogin.8
  head/usr.sbin/lastlogin/lastlogin.c

Modified: head/usr.sbin/lastlogin/lastlogin.8
==============================================================================
--- head/usr.sbin/lastlogin/lastlogin.8 Mon Jun  6 18:25:11 2011        
(r222766)
+++ head/usr.sbin/lastlogin/lastlogin.8 Mon Jun  6 18:40:01 2011        
(r222767)
@@ -31,7 +31,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 11, 1996
+.Dd June 6, 2011
 .Dt LASTLOGIN 8
 .Os
 .Sh NAME
@@ -39,6 +39,8 @@
 .Nd indicate last login time of users
 .Sh SYNOPSIS
 .Nm
+.Op Fl f Ar file
+.Op Fl rt
 .Op Ar user ...
 .Sh DESCRIPTION
 The
@@ -54,8 +56,8 @@ If more than one
 .Ar user
 is given, the session information for each user is printed in
 the order given on the command line.
-Otherwise, information
-for all users is printed, sorted by name.
+Otherwise, information for all users is printed.
+By default, the entries are sorted by user name.
 .Pp
 The
 .Nm
@@ -63,6 +65,18 @@ utility differs from
 .Xr last 1
 in that it only prints information regarding the very last login session.
 The last login database is never turned over or deleted in standard usage.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl f Ar file
+Open last login database
+.Ar file
+instead of the system-wide database.
+.It Fl r
+Print the entries in reverse sorted order.
+.It Fl t
+Sort the elements by last login time, instead of user name.
+.El
 .Sh FILES
 .Bl -tag -width /var/log/utx.lastlogin -compact
 .It Pa /var/log/utx.lastlogin

Modified: head/usr.sbin/lastlogin/lastlogin.c
==============================================================================
--- head/usr.sbin/lastlogin/lastlogin.c Mon Jun  6 18:25:11 2011        
(r222766)
+++ head/usr.sbin/lastlogin/lastlogin.c Mon Jun  6 18:40:01 2011        
(r222767)
@@ -47,30 +47,59 @@ __RCSID("$NetBSD: lastlogin.c,v 1.4 1998
        int     main(int, char **);
 static void    output(struct utmpx *);
 static void    usage(void);
+static int     utcmp_user(const void *, const void *);
+
+static int     order = 1;
+static const char *file = NULL;
+static int     (*utcmp)(const void *, const void *) = utcmp_user;
 
 static int
-utcmp(const void *u1, const void *u2)
+utcmp_user(const void *u1, const void *u2)
 {
 
-       return (strcmp(((const struct utmpx *)u1)->ut_user,
+       return (order * strcmp(((const struct utmpx *)u1)->ut_user,
            ((const struct utmpx *)u2)->ut_user));
 }
 
+static int
+utcmp_time(const void *u1, const void *u2)
+{
+       time_t t1, t2;
+
+       t1 = ((const struct utmpx *)u1)->ut_tv.tv_sec;
+       t2 = ((const struct utmpx *)u2)->ut_tv.tv_sec;
+       return (t1 < t2 ? order : t1 > t2 ? -order : 0);
+}
+
 int
 main(int argc, char *argv[])
 {
        int     ch, i, ulistsize;
        struct utmpx *u, *ulist;
 
-       while ((ch = getopt(argc, argv, "")) != -1) {
-               usage();
+       while ((ch = getopt(argc, argv, "f:rt")) != -1) {
+               switch (ch) {
+               case 'f':
+                       file = optarg;
+                       break;
+               case 'r':
+                       order = -1;
+                       break;
+               case 't':
+                       utcmp = utcmp_time;
+                       break;
+               default:
+                       usage();
+               }
        }
+       argc -= optind;
+       argv += optind;
 
-       /* Process usernames given on the command line. */
-       if (argc > 1) {
-               for (i = 1; i < argc; ++i) {
-                       if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0)
-                               errx(1, "failed to open lastlog database");
+       if (argc > 0) {
+               /* Process usernames given on the command line. */
+               for (i = 0; i < argc; i++) {
+                       if (setutxdb(UTXDB_LASTLOGIN, file) != 0)
+                               err(1, "failed to open lastlog database");
                        if ((u = getutxuser(argv[i])) == NULL) {
                                warnx("user '%s' not found", argv[i]);
                                continue;
@@ -78,11 +107,10 @@ main(int argc, char *argv[])
                        output(u);
                        endutxent();
                }
-       }
-       /* Read all lastlog entries, looking for active ones */
-       else {
-               if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0)
-                       errx(1, "failed to open lastlog database");
+       } else {
+               /* Read all lastlog entries, looking for active ones. */
+               if (setutxdb(UTXDB_LASTLOGIN, file) != 0)
+                       err(1, "failed to open lastlog database");
                ulist = NULL;
                ulistsize = 0;
                while ((u = getutxent()) != NULL) {
@@ -119,6 +147,6 @@ output(struct utmpx *u)
 static void
 usage(void)
 {
-       fprintf(stderr, "usage: lastlogin [user ...]\n");
+       fprintf(stderr, "usage: lastlogin [-f file] [-rt] [user ...]\n");
        exit(1);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to