summaryrefslogtreecommitdiffstats
path: root/login-utils/lslogins.c
diff options
context:
space:
mode:
authorKarel Zak2014-05-27 17:34:15 +0200
committerKarel Zak2014-05-27 17:34:15 +0200
commitf37b357b47a4329f578722b193d4aa070057a04f (patch)
tree52636257010b137ddcade65262d5c50d5b870e93 /login-utils/lslogins.c
parentbuild_sys: fix default estate usage (diff)
downloadkernel-qcow2-util-linux-f37b357b47a4329f578722b193d4aa070057a04f.tar.gz
kernel-qcow2-util-linux-f37b357b47a4329f578722b193d4aa070057a04f.tar.xz
kernel-qcow2-util-linux-f37b357b47a4329f578722b193d4aa070057a04f.zip
lslogins: print systemd journal logs
Co-Author: Ondrej Oprala <ooprala@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils/lslogins.c')
-rw-r--r--login-utils/lslogins.c84
1 files changed, 77 insertions, 7 deletions
diff --git a/login-utils/lslogins.c b/login-utils/lslogins.c
index 2a1e960b8..62e193122 100644
--- a/login-utils/lslogins.c
+++ b/login-utils/lslogins.c
@@ -43,6 +43,10 @@
# include <selinux/selinux.h>
#endif
+#ifdef HAVE_LIBSYSTEMD
+# include <systemd/sd-journal.h>
+#endif
+
#include "c.h"
#include "nls.h"
#include "closestream.h"
@@ -246,6 +250,7 @@ struct lslogins_control {
void *usertree;
+ uid_t uid;
uid_t UID_MIN;
uid_t UID_MAX;
@@ -260,7 +265,9 @@ struct lslogins_control {
int sel_enabled;
unsigned int time_mode;
+ const char *journal_path;
};
+
/* these have to remain global since there's no other
* reasonable way to pass them for each call of fill_table()
* via twalk() */
@@ -340,6 +347,9 @@ static char *build_sgroups_string(gid_t *sgroups, size_t nsgroups, int want_name
size_t n = 0, maxlen, len;
char *res, *p;
+ if (!nsgroups)
+ return NULL;
+
len = maxlen = nsgroups * 10;
res = p = xmalloc(maxlen);
@@ -461,7 +471,8 @@ static int get_sgroups(gid_t **list, size_t *len, struct passwd *pwd)
++n;
}
- (*list)[n] = (*list)[--(*len)];
+ if (*len)
+ (*list)[n] = (*list)[--(*len)];
return 0;
}
@@ -500,7 +511,8 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c
if (!pwd)
return NULL;
- uid = pwd->pw_uid;
+ ctl->uid = uid = pwd->pw_uid;
+
/* nfsnobody is an exception to the UID_MAX limit.
* This is "nobody" on some systems; the decisive
* point is the UID - 65534 */
@@ -970,11 +982,11 @@ static void fill_table(const void *u, const VISIT which, const int depth __attri
case COL_PWD_CTIME_MAX:
rc = scols_line_set_data(ln, n, user->pwd_ctime_max);
break;
-#ifdef HAVE_LIBSELINUX
case COL_SELINUX:
+#ifdef HAVE_LIBSELINUX
rc = scols_line_set_data(ln, n, user->context);
- break;
#endif
+ break;
case COL_NPROCS:
rc = scols_line_set_data(ln, n, user->nprocs);
break;
@@ -989,6 +1001,60 @@ static void fill_table(const void *u, const VISIT which, const int depth __attri
}
return;
}
+#ifdef HAVE_LIBSYSTEMD
+static void print_journal_tail(const char *journal_path, uid_t uid, size_t len)
+{
+ sd_journal *j;
+ char *match, *buf;
+ uint64_t x;
+ time_t t;
+ const char *identifier, *pid, *message;
+ size_t identifier_len, pid_len, message_len;
+
+ if (journal_path)
+ sd_journal_open_directory(&j, journal_path, 0);
+ else
+ sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
+
+ buf = xmalloc(sizeof(char) * 16);
+ xasprintf(&match, "_UID=%d", uid);
+
+ sd_journal_add_match(j, match, 0);
+ sd_journal_seek_tail(j);
+ sd_journal_previous_skip(j, len);
+
+ do {
+ if (0 > sd_journal_get_data(j, "SYSLOG_IDENTIFIER",
+ (const void **) &identifier, &identifier_len))
+ return;
+ if (0 > sd_journal_get_data(j, "_PID",
+ (const void **) &pid, &pid_len))
+ return;
+ if (0 > sd_journal_get_data(j, "MESSAGE",
+ (const void **) &message, &message_len))
+ return;
+
+ sd_journal_get_realtime_usec(j, &x);
+ t = x / 1000000;
+ strftime(buf, 16, "%b %d %H:%M:%S", localtime(&t));
+
+ fprintf(stdout, "%s", buf);
+
+ identifier = strchr(identifier, '=') + 1;
+ pid = strchr(pid, '=') + 1 ;
+ message = strchr(message, '=') + 1;
+
+ fprintf(stdout, " %s", identifier);
+ fprintf(stdout, "[%s]:", pid);
+ fprintf(stdout, "%s\n", message);
+ } while (sd_journal_next(j));
+
+ free(buf);
+ free(match);
+ sd_journal_flush_matches(j);
+ sd_journal_close(j);
+}
+#endif
static int print_pretty(struct libscols_table *tb)
{
@@ -1024,9 +1090,14 @@ static int print_user_table(struct lslogins_control *ctl)
return -1;
twalk(ctl->usertree, fill_table);
- if (outmode == OUT_PRETTY)
+ if (outmode == OUT_PRETTY) {
print_pretty(tb);
- else
+#ifdef HAVE_LIBSYSTEMD
+ fprintf(stdout, _("\nLast logs:\n"));
+ print_journal_tail(ctl->journal_path, ctl->uid, 3);
+ fputc('\n', stdout);
+#endif
+ } else
scols_print_table(tb);
return 0;
}
@@ -1383,6 +1454,5 @@ int main(int argc, char *argv[])
tdestroy(ctl->usertree, free_user);
free_ctl(ctl);
-
return EXIT_SUCCESS;
}