[Libguestfs] [PATCH v4 1/2] cat: move get_journal_field to fish/journal.c
Pino Toscano
ptoscano at redhat.com
Thu Aug 27 17:23:13 UTC 2015
In data giovedì 27 agosto 2015 15:18:24, Maros Zatko ha scritto:
> ---
> cat/Makefile.am | 1 +
> cat/log.c | 113 ++-----------------------------------------
> fish/Makefile.am | 1 +
> fish/journal.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 147 insertions(+), 110 deletions(-)
> create mode 100644 fish/journal.c
>
> diff --git a/cat/Makefile.am b/cat/Makefile.am
> index d0db6fa..d472100 100644
> --- a/cat/Makefile.am
> +++ b/cat/Makefile.am
> @@ -38,6 +38,7 @@ bin_PROGRAMS = virt-cat virt-filesystems virt-log virt-ls
> SHARED_SOURCE_FILES = \
> ../fish/domain.c \
> ../fish/inspect.c \
> + ../fish/journal.c \
> ../fish/keys.c \
> ../fish/options.h \
> ../fish/options.c \
> diff --git a/cat/log.c b/cat/log.c
> index 616baed..c72946b 100644
> --- a/cat/log.c
> +++ b/cat/log.c
> @@ -36,6 +36,7 @@
>
> #include "guestfs.h"
> #include "options.h"
> +#include "fish.h"
The change for this is in patch #2, while it needs to be part of this
(otherwise it won't build alone).
Also, I'd say to create a new own journal.h, so the global fish.h of
guestfish is not pulled when using this shared code; see also
fish/windows.{c,h}.
>
> /* Currently open libguestfs handle. */
> guestfs_h *g;
> @@ -273,128 +274,20 @@ do_log (void)
> return 0;
> }
>
> -/* Find the value of the named field from the list of attributes. If
> - * not found, returns NULL (not an error). If found, returns a
> - * pointer to the field, and the length of the field. NOTE: The field
> - * is NOT \0-terminated, so you have to print it using "%.*s".
> - *
> - * There may be multiple fields with the same name. In this case, the
> - * function returns the first entry.
> - */
> -static const char *
> -get_journal_field (const struct guestfs_xattr_list *xattrs, const char *name,
> - size_t *len_rtn)
> -{
> - uint32_t i;
> -
> - for (i = 0; i < xattrs->len; ++i) {
> - if (STREQ (name, xattrs->val[i].attrname)) {
> - *len_rtn = xattrs->val[i].attrval_len;
> - return xattrs->val[i].attrval;
> - }
> - }
> -
> - return NULL; /* not found */
> -}
> -
> -static const char *const log_level_table[] = {
> - [LOG_EMERG] = "emerg",
> - [LOG_ALERT] = "alert",
> - [LOG_CRIT] = "crit",
> - [LOG_ERR] = "err",
> - [LOG_WARNING] = "warning",
> - [LOG_NOTICE] = "notice",
> - [LOG_INFO] = "info",
> - [LOG_DEBUG] = "debug"
> -};
> -
> static int
> do_log_journal (void)
> {
> int r;
> - unsigned errors = 0;
> -
> if (guestfs_journal_open (g, JOURNAL_DIR) == -1)
> return -1;
>
> - while ((r = guestfs_journal_next (g)) > 0) {
> - CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
> - const char *priority_str, *identifier, *comm, *pid, *message;
> - size_t priority_len, identifier_len, comm_len, pid_len, message_len;
> - int priority = LOG_INFO;
> - int64_t ts;
> -
> - /* The question is what fields to display. We should probably
> - * make this configurable, but for now use the "short" format from
> - * journalctl. (XXX)
> - */
> -
> - xattrs = guestfs_journal_get (g);
> - if (xattrs == NULL)
> - return -1;
> -
> - ts = guestfs_journal_get_realtime_usec (g); /* error checked below */
> -
> - priority_str = get_journal_field (xattrs, "PRIORITY", &priority_len);
> - //hostname = get_journal_field (xattrs, "_HOSTNAME", &hostname_len);
> - identifier = get_journal_field (xattrs, "SYSLOG_IDENTIFIER",
> - &identifier_len);
> - comm = get_journal_field (xattrs, "_COMM", &comm_len);
> - pid = get_journal_field (xattrs, "_PID", &pid_len);
> - message = get_journal_field (xattrs, "MESSAGE", &message_len);
> -
> - /* Timestamp. */
> - if (ts >= 0) {
> - char buf[64];
> - time_t t = ts / 1000000;
> - struct tm tm;
> -
> - if (strftime (buf, sizeof buf, "%b %d %H:%M:%S",
> - localtime_r (&t, &tm)) <= 0) {
> - fprintf (stderr, _("%s: could not format journal entry timestamp\n"),
> - guestfs_int_program_name);
> - errors++;
> - continue;
> - }
> - fputs (buf, stdout);
> - }
> -
> - /* Hostname. */
> - /* We don't print this because it is assumed each line from the
> - * guest will have the same hostname. (XXX)
> - */
> - //if (hostname)
> - // printf (" %.*s", (int) hostname_len, hostname);
> -
> - /* Identifier. */
> - if (identifier)
> - printf (" %.*s", (int) identifier_len, identifier);
> - else if (comm)
> - printf (" %.*s", (int) comm_len, comm);
> -
> - /* PID */
> - if (pid)
> - printf ("[%.*s]", (int) pid_len, pid);
> -
> - /* Log level. */
> - if (priority_str && *priority_str >= '0' && *priority_str <= '7')
> - priority = *priority_str - '0';
> -
> - printf (" %s:", log_level_table[priority]);
> -
> - /* Message. */
> - if (message)
> - printf (" %.*s", (int) message_len, message);
> -
> - printf ("\n");
> - }
> - if (r == -1) /* error from guestfs_journal_next */
> + if ((r = journal_view ("~3axv")) == -1)
Considering that journal_view just returns 0 for success and -1 for
failure, there isn't even need to set its return value to r; just check
for -1 as error condition.
> return -1;
>
> if (guestfs_journal_close (g) == -1)
> return -1;
>
> - return errors > 0 ? -1 : 0;
> + return r;
> }
>
> static int
> diff --git a/fish/Makefile.am b/fish/Makefile.am
> index c4b82ae..e4b4fcf 100644
> --- a/fish/Makefile.am
> +++ b/fish/Makefile.am
> @@ -94,6 +94,7 @@ guestfish_SOURCES = \
> glob.c \
> help.c \
> hexedit.c \
> + journal.c \
> lcd.c \
> man.c \
> more.c \
> diff --git a/fish/journal.c b/fish/journal.c
> new file mode 100644
> index 0000000..9afdf60
> --- /dev/null
> +++ b/fish/journal.c
> @@ -0,0 +1,142 @@
> +/* guestfish - guest filesystem shell
> + * Copyright (C) 2009-2015 Red Hat Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <inttypes.h>
> +#include <libintl.h>
> +#include <time.h>
> +#include <syslog.h>
> +
> +#include "fish.h"
> +#include "journal.h"
> +
> +/* Find the value of the named field from the list of attributes. If
> + * not found, returns NULL (not an error). If found, returns a
> + * pointer to the field, and the length of the field. NOTE: The field
> + * is NOT \0-terminated, so you have to print it using "%.*s".
> + *
> + * There may be multiple fields with the same name. In this case, the
> + * function returns the first entry.
> + */
> +static const char *
> +get_journal_field (const struct guestfs_xattr_list *xattrs, const char *name,
> + size_t *len_rtn)
> +{
> + uint32_t i;
> +
> + for (i = 0; i < xattrs->len; ++i) {
> + if (STREQ (name, xattrs->val[i].attrname)) {
> + *len_rtn = xattrs->val[i].attrval_len;
> + return xattrs->val[i].attrval;
> + }
> + }
> +
> + return NULL; /* not found */
> +}
> +
> +static const char *const log_level_table[] = {
> + [LOG_EMERG] = "emerg",
> + [LOG_ALERT] = "alert",
> + [LOG_CRIT] = "crit",
> + [LOG_ERR] = "err",
> + [LOG_WARNING] = "warning",
> + [LOG_NOTICE] = "notice",
> + [LOG_INFO] = "info",
> + [LOG_DEBUG] = "debug"
> +};
> +
> +static const char *
> +lookup_field (char field)
> +{
> + size_t i = 0;
> + for (i = 0; i < sizeof journal_fields / sizeof *journal_fields; i += 2) {
> + if (field == journal_fields[i][0])
> + return journal_fields[i+1];
> + }
> + return NULL;
> +}
> +
> +/* Fetch and print journal fields in specified order
> + * default is '~3axv'
> + */
> +int
> +journal_view (const char *fields)
> +{
> + int r;
> + int errors = 0;
> + while ((r = guestfs_journal_next(g)) > 0) {
r seems unused here.
> + CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
> + int64_t ts;
> + int priority = LOG_INFO;
> +
> + xattrs = guestfs_journal_get (g);
> + if (xattrs == NULL)
> + return -1;
> +
> + size_t f_id = 0;
> + for (f_id = 0; f_id < strlen (fields); ++f_id) {
> + if (fields[f_id] == '~') {
> + ts = guestfs_journal_get_realtime_usec (g);
> + /* Timestamp. */
> + if (ts >= 0) {
> + char buf[64];
> + time_t t = ts / 1000000;
> + struct tm tm;
> +
> + if (strftime (buf, sizeof buf, "%b %d %H:%M:%S",
> + localtime_r (&t, &tm)) <= 0) {
> + fprintf (stderr, _("could not format journal entry timestamp\n"));
> + errors++;
> + continue;
> + }
> + fputs (buf, stdout);
> + }
> + }
> +
> + const char *field_name, *field_val;
> + size_t field_len;
> + if ((field_name = lookup_field (fields[f_id]))) {
> + field_val = get_journal_field (xattrs, field_name, &field_len);
> + if (STREQ (field_name, "PRIORITY")) {
> + if (field_val && *field_val >= '0' && *field_val <= '7')
> + priority = *field_val - '0';
> + printf (" %s:", log_level_table[priority]);
> + } else if (field_val) {
> + printf (" %.*s", (int)field_len, field_val);
> + }
> + }
> + }
> + printf ("\n");
> + }
> +
> + return errors > 0 ? -1 : 0;
> +}
> +
> +int
> +run_journal_view (const char *cmd, size_t argc, char *argv[])
> +{
> + if (argc > 0)
> + return journal_view (argv[0]);
> + return journal_view ("~3axv");
> +}
>
Thanks,
--
Pino Toscano
More information about the Libguestfs
mailing list