From owner-svn-src-all@FreeBSD.ORG Mon Jun 6 18:40:01 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CBB791065672; Mon, 6 Jun 2011 18:40:01 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AA1718FC08; Mon, 6 Jun 2011 18:40:01 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p56Ie1N3043077; Mon, 6 Jun 2011 18:40:01 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p56Ie1FG043075; Mon, 6 Jun 2011 18:40:01 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201106061840.p56Ie1FG043075@svn.freebsd.org> From: Ed Schouten Date: Mon, 6 Jun 2011 18:40:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222767 - head/usr.sbin/lastlogin X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jun 2011 18:40:01 -0000 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); }