summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-08-05 15:59:27 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-08-05 15:59:27 +0300
commit7ac6f3b717c602175b3a7e8f53983f55ff0e1084 (patch)
tree30ea010fb2c74f03e655fd09fc8b42181342dabd
parent2672842e4f7e34b5ba0f0cd4eb149f22a0e56259 (diff)
downloadmailutils-7ac6f3b717c602175b3a7e8f53983f55ff0e1084.tar.gz
mailutils-7ac6f3b717c602175b3a7e8f53983f55ff0e1084.tar.bz2
logstream: introduce optional prefix.
The prefix, if set, is output at the beginning of each line, after the location and before the severity. It can be used to provide additional information about the diagnostics, such as, e.g. the number or UID of the message. The decodemail utility makes use of the new feature. * include/mailutils/log.h (MU_LOGMODE_PREFIX): New define. * include/mailutils/stream.h (MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE) (MU_IOCTL_LOGSTREAM_SET_PREFIX): New defines. * include/mailutils/sys/logstream.h (_mu_log_stream): New member: prefix. * libmailutils/stream/logstream.c (_log_write): Output the prefix. (_log_done): Dereference the prefix. (_log_ctl): Handle MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE and MU_IOCTL_LOGSTREAM_SET_PREFIX. * libmailutils/tests/logstr.c: New test: prefix. * libmailutils/tests/logstr.at: Test log prefix functionality. * decodemail/decodemail.c: Remove crd_error. Use logstream prefix to display message part locations.
-rw-r--r--decodemail/decodemail.c127
-rw-r--r--include/mailutils/log.h3
-rw-r--r--include/mailutils/stream.h10
-rw-r--r--include/mailutils/sys/logstream.h1
-rw-r--r--libmailutils/stream/logstream.c39
-rw-r--r--libmailutils/tests/logstr.at6
-rw-r--r--libmailutils/tests/logstr.c46
7 files changed, 169 insertions, 63 deletions
diff --git a/decodemail/decodemail.c b/decodemail/decodemail.c
index aa73cdc2f..ea0e981fa 100644
--- a/decodemail/decodemail.c
+++ b/decodemail/decodemail.c
@@ -75,9 +75,33 @@ define_charset (void)
static mu_message_t message_decode (mu_message_t, mu_coord_t *, size_t);
-static void message_store_mbox (mu_message_t, mu_mailbox_t, mu_coord_t);
-static void message_store_stdout (mu_message_t, mu_mailbox_t, mu_coord_t);
-static void crd_error (mu_coord_t crd, size_t n, char const *fmt, ...);
+static void message_store_mbox (mu_message_t, mu_mailbox_t);
+static void message_store_stdout (mu_message_t, mu_mailbox_t);
+
+static void
+enable_log_prefix (int on)
+{
+ int mode;
+
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_GET_MODE, &mode);
+ if (on)
+ mode |= MU_LOGMODE_PREFIX;
+ else
+ mode &= ~MU_LOGMODE_PREFIX;
+
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+}
+
+static void
+set_log_prefix (mu_coord_t crd, size_t dim)
+{
+ char *prefix = mu_coord_part_string (crd, dim);
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_PREFIX, prefix);
+ free (prefix);
+}
int
main (int argc, char **argv)
@@ -85,7 +109,7 @@ main (int argc, char **argv)
int rc;
mu_mailbox_t imbox, ombox = NULL;
char *imbox_name = NULL, *ombox_name = NULL;
- void (*message_store) (mu_message_t, mu_mailbox_t, mu_coord_t);
+ void (*message_store) (mu_message_t, mu_mailbox_t);
mu_iterator_t itr;
unsigned long i;
int err = 0;
@@ -205,7 +229,8 @@ main (int argc, char **argv)
rc = mu_coord_alloc (&crd, 1);
if (rc)
mu_alloc_die ();
-
+
+ enable_log_prefix (1);
for (mu_iterator_first (itr), i = 1; !mu_iterator_is_done (itr);
mu_iterator_next (itr), i++)
{
@@ -221,9 +246,11 @@ main (int argc, char **argv)
}
crd[1] = i;
newmsg = message_decode (msg, &crd, 1);
- message_store (newmsg, ombox, crd);
+ message_store (newmsg, ombox);
mu_message_unref (newmsg);
}
+ enable_log_prefix (0);
+
mu_mailbox_destroy (&imbox);
(truncate_opt ? mu_mailbox_expunge : mu_mailbox_sync) (ombox);
mu_mailbox_destroy (&ombox);
@@ -234,12 +261,12 @@ main (int argc, char **argv)
}
static void
-message_store_mbox (mu_message_t msg, mu_mailbox_t mbx, mu_coord_t crd)
+message_store_mbox (mu_message_t msg, mu_mailbox_t mbx)
{
int rc = mu_mailbox_append_message (mbx, msg);
if (rc)
{
- crd_error (crd, 1, _("cannot store message: %s"), mu_strerror (rc));
+ mu_error (_("cannot store message: %s"), mu_strerror (rc));
switch (rc)
{
case MU_ERR_INVALID_EMAIL:
@@ -313,7 +340,7 @@ body_print (mu_message_t msg)
}
static void
-message_store_stdout (mu_message_t msg, mu_mailbox_t mbx, mu_coord_t crd)
+message_store_stdout (mu_message_t msg, mu_mailbox_t mbx)
{
env_print (msg);
hdr_print (msg);
@@ -321,30 +348,6 @@ message_store_stdout (mu_message_t msg, mu_mailbox_t mbx, mu_coord_t crd)
mu_printf ("\n");
}
-/*
- * Display diagnostics with the location of the message part it
- * belongs to.
- *
- * Arguments:
- * crd - A mu_coord_t object describing the location.
- * dim - Number of significant positions in crd.
- * fmt - Format string
- */
-static void
-crd_error (mu_coord_t crd, size_t n, char const *fmt, ...)
-{
- va_list ap;
- char *pfx = mu_coord_part_string (crd, n);
-
- mu_diag_printf (MU_DIAG_ERROR, "%s: ", pfx);
- free (pfx);
-
- va_start (ap, fmt);
- mu_diag_cont_vprintf (fmt, ap);
- va_end (ap);
- mu_stream_write (mu_strerr, "\n", 1, NULL);
-}
-
static inline int
is_address_header (char const *name)
{
@@ -459,6 +462,8 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
int ismime = 0;
int rc;
+ set_log_prefix (*crd, dim);
+
mu_message_is_multipart (msg, &ismime);
if (!ismime)
{
@@ -489,7 +494,7 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
rc = mu_stream_copy (bstr, str, 0, NULL);
if (rc)
{
- crd_error (*crd, dim, "mu_stream_copy: %s", mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_copy", NULL, rc);
if (mu_stream_err (bstr))
{
exit (EX_IOERR);
@@ -533,9 +538,9 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
&ct);
if (rc)
{
- crd_error (*crd, dim,
- "mu_content_type_parse_ext(%s): %s",
- vc, mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR,
+ "mu_content_type_parse_ext",
+ vc, rc);
free (vc);
continue;
}
@@ -552,8 +557,9 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
break;
default:
- crd_error (*crd, dim, "mu_assoc_install_ref: %s",
- mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR,
+ "mu_assoc_install_ref",
+ NULL, rc);
exit (EX_IOERR);
}
(*pparam)->value = mu_strdup (charset);
@@ -614,8 +620,8 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
rc = mu_header_aget_value_unfold (hdr, MU_HEADER_CONTENT_TYPE, &s);
if (rc)
{
- crd_error (*crd, dim, "mu_header_aget_value_unfold(%s): %s",
- MU_HEADER_CONTENT_TYPE, mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_header_aget_value_unfold",
+ MU_HEADER_CONTENT_TYPE, rc);
mu_message_ref (msg);
return msg;
}
@@ -624,8 +630,7 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
MU_CONTENT_TYPE_PARAM, &ct);
if (rc)
{
- crd_error (*crd, dim, "mu_content_type_parse_ext(%s): %s",
- s, mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_content_type_parse_ext", s, rc);
free (s);
mu_message_ref (msg);
return msg;
@@ -639,26 +644,25 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
return msg;
}
- ++dim;
- if (dim > mu_coord_length (*crd))
- {
- rc = mu_coord_realloc (crd, dim);
- if (rc)
- mu_alloc_die ();
- }
-
mu_mime_create_multipart (&mime, ct->subtype, ct->param);
mu_content_type_destroy (&ct);
rc = mu_message_get_num_parts (msg, &nparts);
if (rc)
{
- crd_error (*crd, dim, "mu_message_get_num_parts(%s): %s",
- MU_HEADER_CONTENT_TYPE, mu_strerror (rc));
- --dim;
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_num_parts",
+ NULL, rc);
mu_message_ref (msg);
return msg;
}
+ ++dim;
+ if (dim > mu_coord_length (*crd))
+ {
+ rc = mu_coord_realloc (crd, dim);
+ if (rc)
+ mu_alloc_die ();
+ }
+
for (i = 1; i <= nparts; i++)
{
mu_message_t msgpart, msgdec;
@@ -670,6 +674,7 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
mu_mime_add_part (mime, msgdec);
mu_message_unref (msgdec);
}
+
--dim;
mu_mime_to_message (mime, &newmsg);
@@ -710,6 +715,8 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
mu_iterator_destroy (&itr);
}
+ set_log_prefix (*crd, dim);
+
if (dim == 1)
{
/* Copy envelope */
@@ -721,15 +728,15 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
char *sender = NULL, *date = NULL;
if ((rc = mu_envelope_aget_sender (env, &sender)) != 0)
{
- crd_error (*crd, dim, "mu_envelope_aget_sender: %s",
- mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_envelope_aget_sender",
+ NULL, rc);
}
else if ((rc = mu_envelope_aget_date (env, &date)) != 0)
{
free (sender);
sender = NULL;
- crd_error (*crd, dim, "mu_envelope_aget_date: %s",
- mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_envelope_aget_date",
+ NULL, rc);
}
if (sender)
@@ -745,8 +752,8 @@ message_decode (mu_message_t msg, mu_coord_t *crd, size_t dim)
{
free (sender);
free (date);
- crd_error (*crd, dim, "mu_envelope_create: %s",
- mu_strerror (rc));
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_envelope_create",
+ NULL, rc);
}
}
}
diff --git a/include/mailutils/log.h b/include/mailutils/log.h
index d4957e361..0d83be66f 100644
--- a/include/mailutils/log.h
+++ b/include/mailutils/log.h
@@ -34,7 +34,8 @@ extern "C" {
#define MU_LOGMODE_SEVERITY 0x0001
#define MU_LOGMODE_LOCUS 0x0002
-
+#define MU_LOGMODE_PREFIX 0x0004
+
int mu_log_stream_create (mu_stream_t *, mu_stream_t);
int mu_syslog_stream_create (mu_stream_t *, int);
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index d58eef474..4843dc178 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -169,6 +169,16 @@ enum mu_buffer_type
Arg: struct mu_locus_range *
*/
#define MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE 16
+
+ /* Get prefix.
+ Arg: char **
+ */
+#define MU_IOCTL_LOGSTREAM_GET_PREFIX 17
+
+ /* Set prefix.
+ Arg: char *
+ */
+#define MU_IOCTL_LOGSTREAM_SET_PREFIX 18
/* Opcodes for MU_IOCTL_XSCRIPTSTREAM */
/* Swap transcript levels.
diff --git a/include/mailutils/sys/logstream.h b/include/mailutils/sys/logstream.h
index cb5b90101..34c4600a4 100644
--- a/include/mailutils/sys/logstream.h
+++ b/include/mailutils/sys/logstream.h
@@ -32,6 +32,7 @@ struct _mu_log_stream
int sevmask; /* Mask out the output of severity level for
these severities. */
struct mu_locus_range locrange; /* Location in the source file */
+ char const *prefix; /* Optinal prefix */
};
void _mu_log_stream_setup (struct _mu_log_stream *sp, mu_stream_t transport);
diff --git a/libmailutils/stream/logstream.c b/libmailutils/stream/logstream.c
index 23b51faf3..38c4b3a27 100644
--- a/libmailutils/stream/logstream.c
+++ b/libmailutils/stream/logstream.c
@@ -272,6 +272,13 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
mu_stream_print_locus_range (sp->transport, &loc);
mu_stream_write (sp->transport, ": ", 2, NULL);
}
+
+ if ((logmode & MU_LOGMODE_PREFIX) && sp->prefix)
+ {
+ mu_stream_write (sp->transport, sp->prefix, strlen (sp->prefix),
+ NULL);
+ mu_stream_write (sp->transport, ": ", 2, NULL);
+ }
if ((logmode & MU_LOGMODE_SEVERITY) &&
!(sp->sevmask & MU_DEBUG_LEVEL_MASK (severity)))
@@ -302,6 +309,7 @@ _log_done (struct _mu_stream *str)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
mu_locus_range_deinit (&sp->locrange);
+ mu_ident_deref (sp->prefix);
mu_stream_destroy (&sp->transport);
}
@@ -548,10 +556,39 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
&sp->locrange.beg.mu_file);
mu_ident_ref (sp->locrange.end.mu_file,
&sp->locrange.end.mu_file);
-
+ mu_ident_ref (sp->prefix, &newp->prefix);
*(mu_stream_t*) arg = str;
}
break;
+
+ case MU_IOCTL_LOGSTREAM_GET_PREFIX:
+ if (!arg)
+ return EINVAL;
+ else
+ {
+ char **ret_ptr = arg;
+
+ if (!sp->prefix)
+ sp->prefix = NULL;
+ else
+ {
+ char *copy = strdup (sp->prefix);
+ if (!copy)
+ return errno;
+ *ret_ptr = copy;
+ }
+ }
+ break;
+
+ case MU_IOCTL_LOGSTREAM_SET_PREFIX:
+ {
+ mu_ident_deref (sp->prefix);
+ if (arg)
+ mu_ident_ref (arg, &sp->prefix);
+ else
+ sp->prefix = NULL;
+ }
+ break;
default:
return EINVAL;
diff --git a/libmailutils/tests/logstr.at b/libmailutils/tests/logstr.at
index 90b404aa8..2c9aa4a38 100644
--- a/libmailutils/tests/logstr.at
+++ b/libmailutils/tests/logstr.at
@@ -73,5 +73,11 @@ input:1.1-next:5.10: default
20. fmt: set locus
a:10.5-b:14.8: one
a:10.5-b:14.8: default
+21. prefix
+LOG1: one
+LOG2: two
+prefix off
+LOG2: prefix on
+three
])
AT_CLEANUP \ No newline at end of file
diff --git a/libmailutils/tests/logstr.c b/libmailutils/tests/logstr.c
index 96d0f8e19..d2f5e0e9f 100644
--- a/libmailutils/tests/logstr.c
+++ b/libmailutils/tests/logstr.c
@@ -624,6 +624,49 @@ fmt_locus6 (mu_stream_t str)
mu_stream_printf (str, "default\n");
}
+/* Check the log prefix
+ Expected output:
+ LOG1: one
+ LOG2: two
+ prefix off
+ LOG2: prefix on
+ three
+ */
+static void
+check_prefix (mu_stream_t str)
+{
+ char *prefix[2] = { "LOG1", "LOG2" };
+ char *s;
+ int mode = MU_LOGMODE_PREFIX;
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_PREFIX, prefix[0]);
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+ mu_stream_printf (str, "one\n");
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_GET_PREFIX, &s);
+ if (!s || strcmp (s, prefix[0]))
+ {
+ mu_error ("%s:%d: wrong prefix returned", __FILE__, __LINE__);
+ }
+ free (s);
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_PREFIX, prefix[1]);
+ mu_stream_printf (str, "two\n");
+
+ mu_stream_printf (str, "\033X<%d>prefix off\n",
+ MU_LOGMODE_PREFIX);
+ mu_stream_printf (str, "prefix on\n");
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_PREFIX, NULL);
+ mu_stream_printf (str, "three\n");
+
+}
+
struct testcase
{
@@ -654,6 +697,7 @@ struct testcase testcases[] = {
{ "fmt: locus; restore defaults", fmt_locus4 },
{ "fmt: locus; restore defaults, display locus", fmt_locus5 },
{ "fmt: set locus", fmt_locus6 },
+ { "prefix", check_prefix },
{ NULL }
};
@@ -722,7 +766,7 @@ main (int argc, char **argv)
log_reset (log);
}
}
-
+ mu_stream_destroy (&log);
return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.