lslogins: cleanup -a output
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
d4aa0ff138
commit
ed374569ae
|
@ -192,6 +192,13 @@ enum {
|
||||||
COL_NPROCS,
|
COL_NPROCS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define is_wtmp_col(x) ((x) == COL_LAST_LOGIN || \
|
||||||
|
(x) == COL_LAST_TTY || \
|
||||||
|
(x) == COL_LAST_HOSTNAME)
|
||||||
|
|
||||||
|
#define is_btmp_col(x) ((x) == COL_FAILED_LOGIN || \
|
||||||
|
(x) == COL_FAILED_TTY)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STATUS_FALSE = 0,
|
STATUS_FALSE = 0,
|
||||||
STATUS_TRUE,
|
STATUS_TRUE,
|
||||||
|
@ -233,11 +240,11 @@ static struct lslogins_coldesc coldescs[] =
|
||||||
[COL_FAILED_LOGIN] = { "FAILED-LOGIN", N_("date of last failed login"), N_("Failed login"), 0.1 },
|
[COL_FAILED_LOGIN] = { "FAILED-LOGIN", N_("date of last failed login"), N_("Failed login"), 0.1 },
|
||||||
[COL_FAILED_TTY] = { "FAILED-TTY", N_("where did the login fail?"), N_("Failed login terminal"), 0.05 },
|
[COL_FAILED_TTY] = { "FAILED-TTY", N_("where did the login fail?"), N_("Failed login terminal"), 0.05 },
|
||||||
[COL_HUSH_STATUS] = { "HUSHED", N_("user's hush settings"), N_("Hushed"), 1, SCOLS_FL_RIGHT },
|
[COL_HUSH_STATUS] = { "HUSHED", N_("user's hush settings"), N_("Hushed"), 1, SCOLS_FL_RIGHT },
|
||||||
[COL_PWD_WARN] = { "PWD-WARN", N_("days user is warned of password expiration"), N_("Password expiration warn interval"), 0.1 },
|
[COL_PWD_WARN] = { "PWD-WARN", N_("days user is warned of password expiration"), N_("Password expiration warn interval"), 0.1, SCOLS_FL_RIGHT },
|
||||||
[COL_PWD_EXPIR] = { "PWD-EXPIR", N_("password expiration date"), N_("Password expiration"), 0.1 },
|
[COL_PWD_EXPIR] = { "PWD-EXPIR", N_("password expiration date"), N_("Password expiration"), 0.1, SCOLS_FL_RIGHT },
|
||||||
[COL_PWD_CTIME] = { "PWD-CHANGE", N_("date of last password change"), N_("Password changed"), 0.1 },
|
[COL_PWD_CTIME] = { "PWD-CHANGE", N_("date of last password change"), N_("Password changed"), 0.1, SCOLS_FL_RIGHT},
|
||||||
[COL_PWD_CTIME_MIN] = { "PWD-MIN", N_("number of days required between changes"), N_("Minimal change time"), 0.1 },
|
[COL_PWD_CTIME_MIN] = { "PWD-MIN", N_("number of days required between changes"), N_("Minimal change time"), 0.1, SCOLS_FL_RIGHT },
|
||||||
[COL_PWD_CTIME_MAX] = { "PWD-MAX", N_("max number of days a password may remain unchanged"), N_("Maximal change time"), 0.1 },
|
[COL_PWD_CTIME_MAX] = { "PWD-MAX", N_("max number of days a password may remain unchanged"), N_("Maximal change time"), 0.1, SCOLS_FL_RIGHT },
|
||||||
[COL_SELINUX] = { "CONTEXT", N_("the user's security context"), N_("Selinux context"), 0.1 },
|
[COL_SELINUX] = { "CONTEXT", N_("the user's security context"), N_("Selinux context"), 0.1 },
|
||||||
[COL_NPROCS] = { "PROC", N_("number of processes run by the user"), N_("Running process"), 1, SCOLS_FL_RIGHT },
|
[COL_NPROCS] = { "PROC", N_("number of processes run by the user"), N_("Running process"), 1, SCOLS_FL_RIGHT },
|
||||||
};
|
};
|
||||||
|
@ -273,11 +280,20 @@ static struct libscols_table *tb;
|
||||||
static int columns[ARRAY_SIZE(coldescs)];
|
static int columns[ARRAY_SIZE(coldescs)];
|
||||||
static int ncolumns;
|
static int ncolumns;
|
||||||
|
|
||||||
|
static struct timeval now;
|
||||||
|
|
||||||
static int date_is_today(time_t t)
|
static int date_is_today(time_t t)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
if (now.tv_sec == 0)
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&now, NULL);
|
||||||
return t / 86400 == tv.tv_sec / 86400;
|
return t / (3600 * 24) == now.tv_sec / (3600 * 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int date_is_thisyear(time_t t)
|
||||||
|
{
|
||||||
|
if (now.tv_sec == 0)
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
return t / (3600 * 24 * 365) == now.tv_sec / (3600 * 24 * 365);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int column_name_to_id(const char *name, size_t namesz)
|
static int column_name_to_id(const char *name, size_t namesz)
|
||||||
|
@ -293,6 +309,7 @@ static int column_name_to_id(const char *name, size_t namesz)
|
||||||
warnx(_("unknown column: %s"), name);
|
warnx(_("unknown column: %s"), name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *make_time(int mode, time_t time)
|
static char *make_time(int mode, time_t time)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -310,8 +327,10 @@ static char *make_time(int mode, time_t time)
|
||||||
case TIME_SHORT:
|
case TIME_SHORT:
|
||||||
if (date_is_today(time))
|
if (date_is_today(time))
|
||||||
strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
|
strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
|
||||||
else
|
else if (date_is_thisyear(time))
|
||||||
strftime(buf, sizeof(buf), "%b%d/%H:%M", &tm);
|
strftime(buf, sizeof(buf), "%b%d/%H:%M", &tm);
|
||||||
|
else
|
||||||
|
strftime(buf, sizeof(buf), "%Y-%b%d", &tm);
|
||||||
break;
|
break;
|
||||||
case TIME_ISO:
|
case TIME_ISO:
|
||||||
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", &tm);
|
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", &tm);
|
||||||
|
@ -402,6 +421,24 @@ static struct utmp *get_last_wtmp(struct lslogins_control *ctl, const char *user
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int require_wtmp(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < (size_t) ncolumns; i++)
|
||||||
|
if (is_wtmp_col(columns[i]))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int require_btmp(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < (size_t) ncolumns; i++)
|
||||||
|
if (is_btmp_col(columns[i]))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct utmp *get_last_btmp(struct lslogins_control *ctl, const char *username)
|
static struct utmp *get_last_btmp(struct lslogins_control *ctl, const char *username)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -652,20 +689,12 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c
|
||||||
shadow->sp_lstchg * 86400);
|
shadow->sp_lstchg * 86400);
|
||||||
break;
|
break;
|
||||||
case COL_PWD_CTIME_MIN:
|
case COL_PWD_CTIME_MIN:
|
||||||
if (shadow) {
|
if (shadow && shadow->sp_min > 0)
|
||||||
if (shadow->sp_min <= 0)
|
xasprintf(&user->pwd_ctime_min, "%ld", shadow->sp_min);
|
||||||
user->pwd_ctime_min = xstrdup("unlimited");
|
|
||||||
else
|
|
||||||
xasprintf(&user->pwd_ctime_min, "%ld", shadow->sp_min);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case COL_PWD_CTIME_MAX:
|
case COL_PWD_CTIME_MAX:
|
||||||
if (shadow) {
|
if (shadow && shadow->sp_max > 0)
|
||||||
if (shadow->sp_max <= 0)
|
xasprintf(&user->pwd_ctime_max, "%ld", shadow->sp_max);
|
||||||
user->pwd_ctime_max = xstrdup("unlimited");
|
|
||||||
else
|
|
||||||
xasprintf(&user->pwd_ctime_max, "%ld", shadow->sp_max);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case COL_SELINUX:
|
case COL_SELINUX:
|
||||||
{
|
{
|
||||||
|
@ -1166,10 +1195,11 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c, want_wtmp = 0, want_btmp = 0;
|
int c, opt_o = 0;
|
||||||
char *logins = NULL, *groups = NULL;
|
char *logins = NULL, *groups = NULL;
|
||||||
char *path_wtmp = _PATH_WTMP, *path_btmp = _PATH_BTMP;
|
char *path_wtmp = _PATH_WTMP, *path_btmp = _PATH_BTMP;
|
||||||
struct lslogins_control *ctl = xcalloc(1, sizeof(struct lslogins_control));
|
struct lslogins_control *ctl = xcalloc(1, sizeof(struct lslogins_control));
|
||||||
|
size_t i;
|
||||||
|
|
||||||
/* long only options. */
|
/* long only options. */
|
||||||
enum {
|
enum {
|
||||||
|
@ -1225,6 +1255,10 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
ctl->time_mode = TIME_SHORT;
|
ctl->time_mode = TIME_SHORT;
|
||||||
|
|
||||||
|
/* very basic default */
|
||||||
|
columns[ncolumns++] = COL_UID;
|
||||||
|
columns[ncolumns++] = COL_USER;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "acefg:hl:mno:rsuxzZ",
|
while ((c = getopt_long(argc, argv, "acefg:hl:mno:rsuxzZ",
|
||||||
longopts, NULL)) != -1) {
|
longopts, NULL)) != -1) {
|
||||||
|
|
||||||
|
@ -1232,7 +1266,11 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
lslogins_flag |= F_EXPIR;
|
columns[ncolumns++] = COL_PWD_WARN;
|
||||||
|
columns[ncolumns++] = COL_PWD_CTIME_MIN;
|
||||||
|
columns[ncolumns++] = COL_PWD_CTIME_MAX;
|
||||||
|
columns[ncolumns++] = COL_PWD_CTIME;
|
||||||
|
columns[ncolumns++] = COL_PWD_EXPIR;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
outmode = OUT_COLON;
|
outmode = OUT_COLON;
|
||||||
|
@ -1268,6 +1306,7 @@ int main(int argc, char *argv[])
|
||||||
if (ncolumns < 0)
|
if (ncolumns < 0)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
opt_o = 1;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
outmode = OUT_RAW;
|
outmode = OUT_RAW;
|
||||||
|
@ -1344,21 +1383,18 @@ int main(int argc, char *argv[])
|
||||||
lslogins_flag &= ~(F_USRAC | F_SYSAC);
|
lslogins_flag &= ~(F_USRAC | F_SYSAC);
|
||||||
|
|
||||||
if (!ncolumns && outmode == OUT_PRETTY) {
|
if (!ncolumns && outmode == OUT_PRETTY) {
|
||||||
size_t i;
|
|
||||||
want_wtmp = 1;
|
|
||||||
want_btmp = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(coldescs); i++)
|
for (i = 0; i < ARRAY_SIZE(coldescs); i++)
|
||||||
columns[ncolumns++] = i;
|
columns[ncolumns++] = i;
|
||||||
|
|
||||||
} else if (!ncolumns) {
|
} else if (ncolumns == 2 && !opt_o) {
|
||||||
columns[ncolumns++] = COL_UID;
|
/* default colummns */
|
||||||
columns[ncolumns++] = COL_USER;
|
columns[ncolumns++] = COL_NPROCS;
|
||||||
columns[ncolumns++] = COL_PGRP;
|
columns[ncolumns++] = COL_PWDLOCK;
|
||||||
columns[ncolumns++] = COL_PGID;
|
columns[ncolumns++] = COL_PWDDENY;
|
||||||
columns[ncolumns++] = COL_LAST_LOGIN;
|
columns[ncolumns++] = COL_LAST_LOGIN;
|
||||||
|
columns[ncolumns++] = COL_GECOS;
|
||||||
want_wtmp = 1;
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
if (lslogins_flag & F_NOPWD)
|
if (lslogins_flag & F_NOPWD)
|
||||||
columns[ncolumns++] = COL_PWDEMPTY;
|
columns[ncolumns++] = COL_PWDEMPTY;
|
||||||
|
@ -1375,7 +1411,6 @@ int main(int argc, char *argv[])
|
||||||
if (lslogins_flag & F_FAIL) {
|
if (lslogins_flag & F_FAIL) {
|
||||||
columns[ncolumns++] = COL_FAILED_LOGIN;
|
columns[ncolumns++] = COL_FAILED_LOGIN;
|
||||||
columns[ncolumns++] = COL_FAILED_TTY;
|
columns[ncolumns++] = COL_FAILED_TTY;
|
||||||
want_btmp = 1;
|
|
||||||
}
|
}
|
||||||
if (lslogins_flag & F_EXTRA) {
|
if (lslogins_flag & F_EXTRA) {
|
||||||
columns[ncolumns++] = COL_HOME;
|
columns[ncolumns++] = COL_HOME;
|
||||||
|
@ -1386,26 +1421,18 @@ int main(int argc, char *argv[])
|
||||||
columns[ncolumns++] = COL_PWDLOCK;
|
columns[ncolumns++] = COL_PWDLOCK;
|
||||||
columns[ncolumns++] = COL_HUSH_STATUS;
|
columns[ncolumns++] = COL_HUSH_STATUS;
|
||||||
columns[ncolumns++] = COL_PWD_WARN;
|
columns[ncolumns++] = COL_PWD_WARN;
|
||||||
columns[ncolumns++] = COL_PWD_CTIME_MIN; /*?*/
|
columns[ncolumns++] = COL_PWD_CTIME_MIN;
|
||||||
columns[ncolumns++] = COL_PWD_CTIME_MAX; /*?*/
|
columns[ncolumns++] = COL_PWD_CTIME_MAX;
|
||||||
columns[ncolumns++] = COL_NPROCS;
|
columns[ncolumns++] = COL_NPROCS;
|
||||||
}
|
}
|
||||||
if (lslogins_flag & F_SELINUX)
|
if (lslogins_flag & F_SELINUX)
|
||||||
columns[ncolumns++] = COL_SELINUX;
|
columns[ncolumns++] = COL_SELINUX;
|
||||||
} else {
|
|
||||||
int n = 0, i;
|
|
||||||
while (n < ncolumns) {
|
|
||||||
i = columns[n++];
|
|
||||||
if (i <= COL_LAST_HOSTNAME && i >= COL_LAST_LOGIN)
|
|
||||||
want_wtmp = 1;
|
|
||||||
if (i == COL_FAILED_TTY && i >= COL_FAILED_LOGIN)
|
|
||||||
want_btmp = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (want_wtmp)
|
*/
|
||||||
|
|
||||||
|
if (require_wtmp())
|
||||||
parse_wtmp(ctl, path_wtmp);
|
parse_wtmp(ctl, path_wtmp);
|
||||||
if (want_btmp)
|
if (require_btmp())
|
||||||
parse_btmp(ctl, path_btmp);
|
parse_btmp(ctl, path_btmp);
|
||||||
|
|
||||||
get_ulist(ctl, logins, groups);
|
get_ulist(ctl, logins, groups);
|
||||||
|
|
Loading…
Reference in New Issue