diff options
author | Karel Zak | 2014-05-27 17:34:15 +0200 |
---|---|---|
committer | Karel Zak | 2014-05-27 17:34:15 +0200 |
commit | f37b357b47a4329f578722b193d4aa070057a04f (patch) | |
tree | 52636257010b137ddcade65262d5c50d5b870e93 /login-utils/lslogins.c | |
parent | build_sys: fix default estate usage (diff) | |
download | kernel-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.c | 84 |
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; } |