dcavalca / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone
05ad79
diff -up util-linux-2.23.2/include/pathnames.h.kzak util-linux-2.23.2/include/pathnames.h
05ad79
--- util-linux-2.23.2/include/pathnames.h.kzak	2016-03-16 15:17:42.648298525 +0100
05ad79
+++ util-linux-2.23.2/include/pathnames.h	2016-03-16 15:18:13.769055345 +0100
05ad79
@@ -36,6 +36,7 @@
05ad79
 #endif
05ad79
 #define	_PATH_MOTDFILE		"/etc/motd"
05ad79
 #define	_PATH_NOLOGIN		"/etc/nologin"
05ad79
+#define _PATH_VAR_NOLOGIN       "/var/run/nologin"
05ad79
 
05ad79
 #define _PATH_LOGIN		"/bin/login"
05ad79
 #define _PATH_INITTAB		"/etc/inittab"
05ad79
diff -up util-linux-2.23.2/login-utils/lslogins.1.kzak util-linux-2.23.2/login-utils/lslogins.1
05ad79
--- util-linux-2.23.2/login-utils/lslogins.1.kzak	2016-03-16 15:17:42.639298595 +0100
05ad79
+++ util-linux-2.23.2/login-utils/lslogins.1	2016-03-16 15:18:13.769055345 +0100
05ad79
@@ -5,7 +5,10 @@
05ad79
 lslogins \- display information about known users in the system
05ad79
 .SH SYNOPSIS
05ad79
 .B lslogins
05ad79
-[\fIoptions\fR] [\fB-s\fR|\fB-u\fR[=\fIUID\fR]] [\fB-g \fIgroups\fR] [\fB-l \fIlogins\fR]
05ad79
+[options]
05ad79
+.RB [ \-s | \-u [ =\fIUID ]]
05ad79
+.RB [ \-g " \fIgroups\fR]"
05ad79
+.RB [ \-l " \fIlogins\fR]"
05ad79
 .SH DESCRIPTION
05ad79
 .PP
05ad79
 Examine the wtmp and btmp logs, /etc/shadow (if necessary) and /etc/passwd
05ad79
@@ -17,7 +20,7 @@ Mandatory arguments to long options are
05ad79
 .TP
05ad79
 \fB\-a\fR, \fB\-\-acc\-expiration\fR
05ad79
 Display data about the date of last password change and the account expiration
05ad79
-date (see \fBshadow\fR(5) for more info).  (Requires root priviliges.)
05ad79
+date (see \fBshadow\fR(5) for more info).  (Requires root privileges.)
05ad79
 .TP
05ad79
 \fB\-\-btmp\-file \fIpath\fP
05ad79
 Alternate path for btmp.
05ad79
@@ -31,7 +34,7 @@ Output data in the format of NAME=VALUE.
05ad79
 \fB\-f\fR, \fB\-\-failed\fR
05ad79
 Display data about the users' last failed login attempts.
05ad79
 .TP
05ad79
-\fB\-G\fR, \fB\-\-groups\-info\fR
05ad79
+\fB\-G\fR, \fB\-\-supp\-groups\fR
05ad79
 Show information about groups.
05ad79
 .TP
05ad79
 \fB\-g\fR, \fB\-\-groups\fR=\fIgroups\fR
05ad79
@@ -48,9 +51,6 @@ Display data containing information abou
05ad79
 Only show data of users with a login specified in \fIlogins\fR (user names or user
05ad79
 IDS).  More than one login may be specified; the list has to be comma-separated.
05ad79
 .TP
05ad79
-\fB\-m\fR, \fB\-\-supp\-groups\fR
05ad79
-Show supplementary groups.
05ad79
-.TP
05ad79
 \fB\-n\fR, \fB\-\-newline\fR
05ad79
 Display each piece of information on a separate line.
05ad79
 .TP
05ad79
@@ -71,21 +71,21 @@ Display information related to login by
05ad79
 \fB\-r\fR, \fB\-\-raw\fR
05ad79
 Raw output (no columnation).
05ad79
 .TP
05ad79
-\fB\-s\fR, \fB\-\-system\-accs\fR[=\fIthreshold\fR]
05ad79
+\fB\-s\fR, \fB\-\-system\-accs\fR
05ad79
 Show system accounts.  These are by default all accounts with a UID below 1000
05ad79
-(non-inclusive), with the exception of either nobody or nfsnobody (UID 65534).  The UID
05ad79
-threshold can also be specified explicitly (necessary for some distributions that
05ad79
-allocate UIDs starting from 100, 500 - or an entirely different value - rather than 1000).
05ad79
+(non-inclusive), with the exception of either nobody or nfsnobody (UID 65534).
05ad79
+This hardcoded default maybe overwritten by parameters SYS_UID_MIN and SYS_UID_MAX in
05ad79
+the file /etc/login.defs.
05ad79
 .TP
05ad79
-\fB\-\-time-format\fR \fItype\fP
05ad79
+\fB\-\-time\-format\fR \fItype\fP
05ad79
 Display dates in short, full or iso format.  The default is short, this time
05ad79
 format is designed to be space efficient and human readable.
05ad79
 .TP
05ad79
-\fB\-u\fR, \fB\-\-user\-accs\fR[=\fIthreshold\fR]
05ad79
+\fB\-u\fR, \fB\-\-user\-accs\fR
05ad79
 Show user accounts.  These are by default all accounts with UID above 1000
05ad79
-(inclusive), with the exception of either nobody or nfsnobody (UID 65534).  The UID
05ad79
-threshold can also be specified explicitly (necessary for some distributions that
05ad79
-allocate UIDs starting from 100, 500 - or an entirely different value - rather than 1000).
05ad79
+(inclusive), with the exception of either nobody or nfsnobody (UID 65534).
05ad79
+This hardcoded default maybe overwritten by parameters UID_MIN and UID_MAX in
05ad79
+the file /etc/login.defs.
05ad79
 .TP
05ad79
 \fB\-V\fR, \fB\-\-version\fR
05ad79
 Display version information and exit.
05ad79
diff -up util-linux-2.23.2/login-utils/lslogins.c.kzak util-linux-2.23.2/login-utils/lslogins.c
05ad79
--- util-linux-2.23.2/login-utils/lslogins.c.kzak	2016-03-16 15:17:42.639298595 +0100
05ad79
+++ util-linux-2.23.2/login-utils/lslogins.c	2016-03-16 15:22:49.845899268 +0100
05ad79
@@ -144,6 +144,7 @@ enum {
05ad79
 	TIME_SHORT,
05ad79
 	TIME_FULL,
05ad79
 	TIME_ISO,
05ad79
+	TIME_ISO_SHORT,
05ad79
 };
05ad79
 
05ad79
 /*
05ad79
@@ -350,6 +351,9 @@ static char *make_time(int mode, time_t
05ad79
 	case TIME_ISO:
05ad79
 		strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", &tm;;
05ad79
 		break;
05ad79
+	case TIME_ISO_SHORT:
05ad79
+		strftime(buf, sizeof(buf), "%Y-%m-%d", &tm;;
05ad79
+		break;
05ad79
 	default:
05ad79
 		errx(EXIT_FAILURE, _("unsupported time type"));
05ad79
 	}
05ad79
@@ -396,7 +400,7 @@ again:
05ad79
 			x = snprintf(p, len, "%s,", grp->gr_name);
05ad79
 		}
05ad79
 
05ad79
-		if (x < 0 || (size_t) x + 1 > len) {
05ad79
+		if (x < 0 || (size_t) x >= len) {
05ad79
 			size_t cur = p - res;
05ad79
 
05ad79
 			maxlen *= 2;
05ad79
@@ -496,21 +500,24 @@ static int parse_btmp(struct lslogins_co
05ad79
 static int get_sgroups(gid_t **list, size_t *len, struct passwd *pwd)
05ad79
 {
05ad79
 	size_t n = 0;
05ad79
+	int ngroups = 0;
05ad79
 
05ad79
 	*len = 0;
05ad79
 	*list = NULL;
05ad79
 
05ad79
 	/* first let's get a supp. group count */
05ad79
-	getgrouplist(pwd->pw_name, pwd->pw_gid, *list, (int *) len);
05ad79
-	if (!*len)
05ad79
+	getgrouplist(pwd->pw_name, pwd->pw_gid, *list, &ngroups);
05ad79
+	if (!ngroups)
05ad79
 		return -1;
05ad79
 
05ad79
-	*list = xcalloc(1, *len * sizeof(gid_t));
05ad79
+	*list = xcalloc(1, ngroups * sizeof(gid_t));
05ad79
 
05ad79
 	/* now for the actual list of GIDs */
05ad79
-	if (-1 == getgrouplist(pwd->pw_name, pwd->pw_gid, *list, (int *) len))
05ad79
+	if (-1 == getgrouplist(pwd->pw_name, pwd->pw_gid, *list, &ngroups))
05ad79
 		return -1;
05ad79
 
05ad79
+	*len = (size_t) ngroups;
05ad79
+
05ad79
 	/* getgroups also returns the user's primary GID - dispose of it */
05ad79
 	while (n < *len) {
05ad79
 		if ((*list)[n] == pwd->pw_gid)
05ad79
@@ -520,6 +527,7 @@ static int get_sgroups(gid_t **list, siz
05ad79
 
05ad79
 	if (*len)
05ad79
 		(*list)[n] = (*list)[--(*len)];
05ad79
+
05ad79
 	return 0;
05ad79
 }
05ad79
 
05ad79
@@ -685,8 +693,8 @@ static struct lslogins_user *get_user_in
05ad79
 			if (strstr(pwd->pw_shell, "nologin"))
05ad79
 				user->nologin = 1;
05ad79
 			else if (pwd->pw_uid)
05ad79
-				user->nologin = access("/etc/nologin", F_OK) == 0 ||
05ad79
-						access("/var/run/nologin", F_OK) == 0;
05ad79
+				user->nologin = access(_PATH_NOLOGIN, F_OK) == 0 ||
05ad79
+						access(_PATH_VAR_NOLOGIN, F_OK) == 0;
05ad79
 			break;
05ad79
 		case COL_PWD_WARN:
05ad79
 			if (shadow && shadow->sp_warn >= 0)
05ad79
@@ -694,7 +702,8 @@ static struct lslogins_user *get_user_in
05ad79
 			break;
05ad79
 		case COL_PWD_EXPIR:
05ad79
 			if (shadow && shadow->sp_expire >= 0)
05ad79
-				user->pwd_expire = make_time(TIME_SHORT,
05ad79
+				user->pwd_expire = make_time(ctl->time_mode == TIME_ISO ?
05ad79
+						TIME_ISO_SHORT : ctl->time_mode,
05ad79
 						shadow->sp_expire * 86400);
05ad79
 			break;
05ad79
 		case COL_PWD_CTIME:
05ad79
@@ -702,7 +711,8 @@ static struct lslogins_user *get_user_in
05ad79
 			 * (especially in non-GMT timezones) would only serve
05ad79
 			 * to confuse */
05ad79
 			if (shadow)
05ad79
-				user->pwd_ctime = make_time(TIME_SHORT,
05ad79
+				user->pwd_ctime = make_time(ctl->time_mode == TIME_ISO ?
05ad79
+						TIME_ISO_SHORT : ctl->time_mode,
05ad79
 						shadow->sp_lstchg * 86400);
05ad79
 			break;
05ad79
 		case COL_PWD_CTIME_MIN:
05ad79
@@ -852,7 +862,7 @@ static int get_user(struct lslogins_cont
05ad79
 		    const char *username)
05ad79
 {
05ad79
 	*user = get_user_info(ctl, username);
05ad79
-	if (!*user && errno)
05ad79
+	if (!*user)
05ad79
 		if (IS_REAL_ERRNO(errno))
05ad79
 			return -1;
05ad79
 	return 0;
05ad79
@@ -887,33 +897,33 @@ static int create_usertree(struct lslogi
05ad79
 
05ad79
 static struct libscols_table *setup_table(struct lslogins_control *ctl)
05ad79
 {
05ad79
-	struct libscols_table *tb = scols_new_table();
05ad79
+	struct libscols_table *table = scols_new_table();
05ad79
 	int n = 0;
05ad79
 
05ad79
-	if (!tb)
05ad79
+	if (!table)
05ad79
 		errx(EXIT_FAILURE, _("failed to initialize output table"));
05ad79
 	if (ctl->noheadings)
05ad79
-		scols_table_enable_noheadings(tb, 1);
05ad79
+		scols_table_enable_noheadings(table, 1);
05ad79
 
05ad79
 	switch(outmode) {
05ad79
 	case OUT_COLON:
05ad79
-		scols_table_enable_raw(tb, 1);
05ad79
-		scols_table_set_column_separator(tb, ":");
05ad79
+		scols_table_enable_raw(table, 1);
05ad79
+		scols_table_set_column_separator(table, ":");
05ad79
 		break;
05ad79
 	case OUT_NEWLINE:
05ad79
-		scols_table_set_column_separator(tb, "\n");
05ad79
+		scols_table_set_column_separator(table, "\n");
05ad79
 		/* fallthrough */
05ad79
 	case OUT_EXPORT:
05ad79
-		scols_table_enable_export(tb, 1);
05ad79
+		scols_table_enable_export(table, 1);
05ad79
 		break;
05ad79
 	case OUT_NUL:
05ad79
-		scols_table_set_line_separator(tb, "\0");
05ad79
+		scols_table_set_line_separator(table, "\0");
05ad79
 		/* fallthrough */
05ad79
 	case OUT_RAW:
05ad79
-		scols_table_enable_raw(tb, 1);
05ad79
+		scols_table_enable_raw(table, 1);
05ad79
 		break;
05ad79
 	case OUT_PRETTY:
05ad79
-		scols_table_enable_noheadings(tb, 1);
05ad79
+		scols_table_enable_noheadings(table, 1);
05ad79
 	default:
05ad79
 		break;
05ad79
 	}
05ad79
@@ -924,7 +934,7 @@ static struct libscols_table *setup_tabl
05ad79
 		if (ctl->notrunc)
05ad79
 			flags &= ~SCOLS_FL_TRUNC;
05ad79
 
05ad79
-		if (!scols_table_new_column(tb,
05ad79
+		if (!scols_table_new_column(table,
05ad79
 				coldescs[columns[n]].name,
05ad79
 				coldescs[columns[n]].whint,
05ad79
 				flags))
05ad79
@@ -932,9 +942,9 @@ static struct libscols_table *setup_tabl
05ad79
 		++n;
05ad79
 	}
05ad79
 
05ad79
-	return tb;
05ad79
+	return table;
05ad79
 fail:
05ad79
-	scols_unref_table(tb);
05ad79
+	scols_unref_table(table);
05ad79
 	return NULL;
05ad79
 }
05ad79
 
05ad79
@@ -1050,10 +1060,10 @@ static void fill_table(const void *u, co
05ad79
 	return;
05ad79
 }
05ad79
 #ifdef HAVE_LIBSYSTEMD
05ad79
-static void print_journal_tail(const char *journal_path, uid_t uid, size_t len)
05ad79
+static void print_journal_tail(const char *journal_path, uid_t uid, size_t len, int time_mode)
05ad79
 {
05ad79
 	sd_journal *j;
05ad79
-	char *match, *buf;
05ad79
+	char *match, *timestamp;
05ad79
 	uint64_t x;
05ad79
 	time_t t;
05ad79
 	const char *identifier, *pid, *message;
05ad79
@@ -1064,7 +1074,6 @@ static void print_journal_tail(const cha
05ad79
 	else
05ad79
 		sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
05ad79
 
05ad79
-	buf = xmalloc(sizeof(char) * 16);
05ad79
 	xasprintf(&match, "_UID=%d", uid);
05ad79
 
05ad79
 	sd_journal_add_match(j, match, 0);
05ad79
@@ -1074,37 +1083,35 @@ static void print_journal_tail(const cha
05ad79
 	do {
05ad79
 		if (0 > sd_journal_get_data(j, "SYSLOG_IDENTIFIER",
05ad79
 				(const void **) &identifier, &identifier_len))
05ad79
-			return;
05ad79
+			goto done;
05ad79
 		if (0 > sd_journal_get_data(j, "_PID",
05ad79
 				(const void **) &pid, &pid_len))
05ad79
-			return;
05ad79
+			goto done;
05ad79
 		if (0 > sd_journal_get_data(j, "MESSAGE",
05ad79
 				(const void **) &message, &message_len))
05ad79
-			return;
05ad79
+			goto done;
05ad79
 
05ad79
 		sd_journal_get_realtime_usec(j, &x);
05ad79
 		t = x / 1000000;
05ad79
-		strftime(buf, 16, "%b %d %H:%M:%S", localtime(&t);;
05ad79
-
05ad79
-		fprintf(stdout, "%s", buf);
05ad79
-
05ad79
+		timestamp = make_time(time_mode, t);
05ad79
+		/* Get rid of journal entry field identifiers */
05ad79
 		identifier = strchr(identifier, '=') + 1;
05ad79
-		pid = strchr(pid, '=') + 1		;
05ad79
+		pid = strchr(pid, '=') + 1;
05ad79
 		message = strchr(message, '=') + 1;
05ad79
 
05ad79
-		fprintf(stdout, " %s", identifier);
05ad79
-		fprintf(stdout, "[%s]:", pid);
05ad79
-		fprintf(stdout, "%s\n", message);
05ad79
+		fprintf(stdout, "%s %s[%s]: %s\n", timestamp, identifier, pid,
05ad79
+			message);
05ad79
+		free(timestamp);
05ad79
 	} while (sd_journal_next(j));
05ad79
 
05ad79
-	free(buf);
05ad79
+done:
05ad79
 	free(match);
05ad79
 	sd_journal_flush_matches(j);
05ad79
 	sd_journal_close(j);
05ad79
 }
05ad79
 #endif
05ad79
 
05ad79
-static int print_pretty(struct libscols_table *tb)
05ad79
+static int print_pretty(struct libscols_table *table)
05ad79
 {
05ad79
 	struct libscols_iter *itr = scols_new_iter(SCOLS_ITER_FORWARD);
05ad79
 	struct libscols_column *col;
05ad79
@@ -1113,8 +1120,8 @@ static int print_pretty(struct libscols_
05ad79
 	const char *hstr, *dstr;
05ad79
 	int n = 0;
05ad79
 
05ad79
-	ln = scols_table_get_line(tb, 0);
05ad79
-	while (!scols_table_next_column(tb, itr, &col)) {
05ad79
+	ln = scols_table_get_line(table, 0);
05ad79
+	while (!scols_table_next_column(table, itr, &col)) {
05ad79
 
05ad79
 		data = scols_line_get_cell(ln, n);
05ad79
 
05ad79
@@ -1142,7 +1149,7 @@ static int print_user_table(struct lslog
05ad79
 		print_pretty(tb);
05ad79
 #ifdef HAVE_LIBSYSTEMD
05ad79
 		fprintf(stdout, _("\nLast logs:\n"));
05ad79
-		print_journal_tail(ctl->journal_path, ctl->uid, 3);
05ad79
+		print_journal_tail(ctl->journal_path, ctl->uid, 3, ctl->time_mode);
05ad79
 		fputc('\n', stdout);
05ad79
 #endif
05ad79
 	} else
05ad79
@@ -1175,16 +1182,25 @@ static void free_user(void *f)
05ad79
 	free(u);
05ad79
 }
05ad79
 
05ad79
-struct lslogins_timefmt {
05ad79
-	const char *name;
05ad79
-	int val;
05ad79
-};
05ad79
+static int parse_time_mode(const char *optarg)
05ad79
+{
05ad79
+	struct lslogins_timefmt {
05ad79
+		const char *name;
05ad79
+		const int val;
05ad79
+	};
05ad79
+	static const struct lslogins_timefmt timefmts[] = {
05ad79
+		{"iso", TIME_ISO},
05ad79
+		{"full", TIME_FULL},
05ad79
+		{"short", TIME_SHORT},
05ad79
+	};
05ad79
+	size_t i;
05ad79
 
05ad79
-static struct lslogins_timefmt timefmts[] = {
05ad79
-	{ "short", TIME_SHORT },
05ad79
-	{ "full", TIME_FULL },
05ad79
-	{ "iso", TIME_ISO },
05ad79
-};
05ad79
+	for (i = 0; i < ARRAY_SIZE(timefmts); i++) {
05ad79
+		if (strcmp(timefmts[i].name, optarg) == 0)
05ad79
+			return timefmts[i].val;
05ad79
+	}
05ad79
+	errx(EXIT_FAILURE, _("unknown time format: %s"), optarg);
05ad79
+}
05ad79
 
05ad79
 static void __attribute__((__noreturn__)) usage(FILE *out)
05ad79
 {
05ad79
@@ -1193,16 +1209,18 @@ static void __attribute__((__noreturn__)
05ad79
 	fputs(USAGE_HEADER, out);
05ad79
 	fprintf(out, _(" %s [options]\n"), program_invocation_short_name);
05ad79
 
05ad79
+	fputs(USAGE_SEPARATOR, out);
05ad79
+	fputs(_("Display information about known users in the system.\n"), out);
05ad79
+
05ad79
 	fputs(USAGE_OPTIONS, out);
05ad79
 	fputs(_(" -a, --acc-expiration     display info about passwords expiration\n"), out);
05ad79
 	fputs(_(" -c, --colon-separate     display data in a format similar to /etc/passwd\n"), out);
05ad79
 	fputs(_(" -e, --export             display in an export-able output format\n"), out);
05ad79
 	fputs(_(" -f, --failed             display data about the users' last failed logins\n"), out);
05ad79
-	fputs(_(" -G, --groups-info        display information about groups\n"), out);
05ad79
+	fputs(_(" -G, --supp-groups        display information about groups\n"), out);
05ad79
 	fputs(_(" -g, --groups=<groups>    display users belonging to a group in <groups>\n"), out);
05ad79
 	fputs(_(" -L, --last               show info about the users' last login sessions\n"), out);
05ad79
 	fputs(_(" -l, --logins=<logins>    display only users from <logins>\n"), out);
05ad79
-	fputs(_(" -m, --supp-groups        display supplementary groups as well\n"), out);
05ad79
 	fputs(_(" -n, --newline            display each piece of information on a new line\n"), out);
05ad79
 	fputs(_("     --noheadings         don't print headings\n"), out);
05ad79
 	fputs(_("     --notruncate         don't truncate output\n"), out);
05ad79
@@ -1226,7 +1244,7 @@ static void __attribute__((__noreturn__)
05ad79
 		fprintf(out, " %14s  %s\n", coldescs[i].name,
05ad79
 				_(coldescs[i].help));
05ad79
 
05ad79
-	fprintf(out, _("\nFor more details see lslogins(1).\n"));
05ad79
+	fprintf(out, USAGE_MAN_TAIL("lslogins(1)"));
05ad79
 
05ad79
 	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
05ad79
 }
05ad79
@@ -1241,8 +1259,7 @@ int main(int argc, char *argv[])
05ad79
 
05ad79
 	/* long only options. */
05ad79
 	enum {
05ad79
-		OPT_VER = CHAR_MAX + 1,
05ad79
-		OPT_WTMP,
05ad79
+		OPT_WTMP = CHAR_MAX + 1,
05ad79
 		OPT_BTMP,
05ad79
 		OPT_NOTRUNC,
05ad79
 		OPT_NOHEAD,
05ad79
@@ -1300,7 +1317,7 @@ int main(int argc, char *argv[])
05ad79
 	add_column(columns, ncolumns++, COL_UID);
05ad79
 	add_column(columns, ncolumns++, COL_USER);
05ad79
 
05ad79
-	while ((c = getopt_long(argc, argv, "acfGg:hLl:no:prsuVxzZ",
05ad79
+	while ((c = getopt_long(argc, argv, "acefGg:hLl:no:prsuVzZ",
05ad79
 				longopts, NULL)) != -1) {
05ad79
 
05ad79
 		err_exclusive_options(c, longopts, excl, excl_st);
05ad79
@@ -1394,18 +1411,7 @@ int main(int argc, char *argv[])
05ad79
 			ctl->noheadings = 1;
05ad79
 			break;
05ad79
 		case OPT_TIME_FMT:
05ad79
-			{
05ad79
-				size_t i;
05ad79
-
05ad79
-				for (i = 0; i < ARRAY_SIZE(timefmts); i++) {
05ad79
-					if (strcmp(timefmts[i].name, optarg) == 0) {
05ad79
-						ctl->time_mode = timefmts[i].val;
05ad79
-						break;
05ad79
-					}
05ad79
-				}
05ad79
-				if (ctl->time_mode == TIME_INVALID)
05ad79
-					usage(stderr);
05ad79
-			}
05ad79
+			ctl->time_mode = parse_time_mode(optarg);
05ad79
 			break;
05ad79
 		case 'V':
05ad79
 			printf(UTIL_LINUX_VERSION);
05ad79
@@ -1433,7 +1439,7 @@ int main(int argc, char *argv[])
05ad79
 		logins = argv[optind];
05ad79
 		outmode = OUT_PRETTY;
05ad79
 	} else if (argc != optind)
05ad79
-		usage(stderr);
05ad79
+		errx(EXIT_FAILURE, _("Only one user may be specified. Use -l for multiple users."));
05ad79
 
05ad79
 	scols_init_debug(0);
05ad79