Blame SOURCES/0204-mailx-use-problem-report-api-to-define-an-emais-cont.patch

28bab8
From 07059f936207c33b8aabf356e22dda64fc1050cb Mon Sep 17 00:00:00 2001
28bab8
From: Matej Habrnal <mhabrnal@redhat.com>
28bab8
Date: Fri, 1 Apr 2016 13:23:14 +0200
28bab8
Subject: [PATCH] mailx: use problem report api to define an emais' content
28bab8
28bab8
If formatting file is defined, the reporter-mailx
28bab8
uses the given file to create content of emails. Section summary is used
28bab8
for email's subject. If no formatting file is defined, the default formatting
28bab8
is used and subject can be redefined either by mailx.conf file or by env
28bab8
variable.
28bab8
28bab8
Related to rhbz#1281312
28bab8
28bab8
Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
28bab8
---
28bab8
 doc/reporter-mailx.txt           | 48 ++++++++++++++++++++-
28bab8
 src/include/internal_libreport.h |  2 -
28bab8
 src/lib/make_descr.c             | 56 ------------------------
28bab8
 src/plugins/reporter-mailx.c     | 92 +++++++++++++++++++++++++++++++---------
28bab8
 4 files changed, 119 insertions(+), 79 deletions(-)
28bab8
28bab8
diff --git a/doc/reporter-mailx.txt b/doc/reporter-mailx.txt
28bab8
index bd0c63e..029a3d0 100644
28bab8
--- a/doc/reporter-mailx.txt
28bab8
+++ b/doc/reporter-mailx.txt
28bab8
@@ -7,7 +7,7 @@ reporter-mailx - Sends contents of a problem directory via email.
28bab8
 
28bab8
 SYNOPSIS
28bab8
 --------
28bab8
-'reporter-mailx' [-v] -d DIR [-c CONFFILE]
28bab8
+'reporter-mailx' [-v] -d DIR [-c CONFFILE] [-F FMTFILE]
28bab8
 
28bab8
 DESCRIPTION
28bab8
 -----------
28bab8
@@ -38,6 +38,49 @@ The options are:
28bab8
        directory to the email. This can cause the emails to be very
28bab8
        large.
28bab8
 
28bab8
+Formatting configuration files
28bab8
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28bab8
+Lines starting with # are ignored.
28bab8
+
28bab8
+Lines can be continued on the next line using trailing backslash.
28bab8
+
28bab8
+Format:
28bab8
+
28bab8
+   "%summary:: subject format"
28bab8
+   "section:: element1[,element2]..."
28bab8
+   The literal text line to be added to email. Can be empty.
28bab8
+   (Empty lines are NOT ignored!)
28bab8
+
28bab8
+   Subject format is a line of text, where %element% is replaced by
28bab8
+   text element's content, and [[...%element%...]] block is used only if
28bab8
+   %element% exists. [[...]] blocks can nest.
28bab8
+
28bab8
+   Sections can be:
28bab8
+   - %summary: email subject format string.
28bab8
+   - %attach: a list of elements to attach.
28bab8
+   - text, double colon (::) and the list of comma-separated elements.
28bab8
+
28bab8
+   Elements can be:
28bab8
+   - problem directory element names, which get formatted as
28bab8
+     <element_name>: <contents>
28bab8
+     or
28bab8
+     <element_name>:
28bab8
+     :<contents>
28bab8
+     :<contents>
28bab8
+     :<contents>
28bab8
+   - problem directory element names prefixed by "%bare_",
28bab8
+     which is formatted as-is, without "<element_name>:" and colons
28bab8
+   - %oneline, %multiline, %text wildcards, which select all corresponding
28bab8
+     elements for output or attachment
28bab8
+   - %binary wildcard, valid only for %attach section, instructs to attach
28bab8
+     binary elements
28bab8
+   - problem directory element names prefixed by "-",
28bab8
+     which excludes given element from all wildcards
28bab8
+
28bab8
+     Nonexistent elements are silently ignored.
28bab8
+     If none of elements exists, the section will not be created.
28bab8
+
28bab8
+
28bab8
 Integration with ABRT events
28bab8
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28bab8
 'reporter-mailx' can be used as a reporter, to allow users report
28bab8
@@ -66,6 +109,9 @@ OPTIONS
28bab8
    contains site-wide configuration. Users can change the values via
28bab8
    environment variables.
28bab8
 
28bab8
+-F CONF_FORMAT_FILE
28bab8
+   Formatting file for an email.
28bab8
+
28bab8
 ENVIRONMENT VARIABLES
28bab8
 ---------------------
28bab8
 Environment variables take precedence over values provided in
28bab8
diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
28bab8
index c3b2045..cf5730c 100644
28bab8
--- a/src/include/internal_libreport.h
28bab8
+++ b/src/include/internal_libreport.h
28bab8
@@ -668,8 +668,6 @@ enum {
28bab8
 char *make_description(problem_data_t *problem_data, char **names_to_skip, unsigned max_text_size, unsigned desc_flags);
28bab8
 #define make_description_logger libreport_make_description_logger
28bab8
 char* make_description_logger(problem_data_t *problem_data, unsigned max_text_size);
28bab8
-#define make_description_mailx libreport_make_description_mailx
28bab8
-char* make_description_mailx(problem_data_t *problem_data, unsigned max_text_size);
28bab8
 
28bab8
 /* See man os-release(5) for details */
28bab8
 #define OSINFO_ID "ID"
28bab8
diff --git a/src/lib/make_descr.c b/src/lib/make_descr.c
28bab8
index a16eb98..5a6d9f4 100644
28bab8
--- a/src/lib/make_descr.c
28bab8
+++ b/src/lib/make_descr.c
28bab8
@@ -290,52 +290,6 @@ char *make_description(problem_data_t *problem_data, char **names_to_skip,
28bab8
     return strbuf_free_nobuf(buf_dsc);
28bab8
 }
28bab8
 
28bab8
-#ifdef UNUSED
28bab8
-char* make_description_mailx(problem_data_t *problem_data)
28bab8
-{
28bab8
-    struct strbuf *buf_dsc = strbuf_new();
28bab8
-    struct strbuf *buf_additional_files = strbuf_new();
28bab8
-    struct strbuf *buf_duphash_file = strbuf_new();
28bab8
-    struct strbuf *buf_common_files = strbuf_new();
28bab8
-
28bab8
-    GHashTableIter iter;
28bab8
-    char *name;
28bab8
-    struct problem_item *value;
28bab8
-    g_hash_table_iter_init(&iter, problem_data);
28bab8
-    while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value))
28bab8
-    {
28bab8
-        if (value->flags & CD_FLAG_TXT)
28bab8
-        {
28bab8
-            if ((strcmp(name, FILENAME_DUPHASH) != 0)
28bab8
-             && (strcmp(name, FILENAME_ARCHITECTURE) != 0)
28bab8
-             && (strcmp(name, FILENAME_KERNEL) != 0)
28bab8
-             && (strcmp(name, FILENAME_PACKAGE) != 0)
28bab8
-            ) {
28bab8
-                strbuf_append_strf(buf_additional_files, "%s\n-----\n%s\n\n", name, value->content);
28bab8
-            }
28bab8
-            else if (strcmp(name, FILENAME_DUPHASH) == 0)
28bab8
-                strbuf_append_strf(buf_duphash_file, "%s\n-----\n%s\n\n", name, value->content);
28bab8
-            else
28bab8
-                strbuf_append_strf(buf_common_files, "%s\n-----\n%s\n\n", name, value->content);
28bab8
-        }
28bab8
-    }
28bab8
-
28bab8
-    char *common_files = strbuf_free_nobuf(buf_common_files);
28bab8
-    char *duphash_file = strbuf_free_nobuf(buf_duphash_file);
28bab8
-    char *additional_files = strbuf_free_nobuf(buf_additional_files);
28bab8
-
28bab8
-    strbuf_append_strf(buf_dsc, "Duplicate check\n=====\n%s\n\n", duphash_file);
28bab8
-    strbuf_append_strf(buf_dsc, "Common information\n=====\n%s\n\n", common_files);
28bab8
-    strbuf_append_strf(buf_dsc, "Additional information\n=====\n%s\n", additional_files);
28bab8
-
28bab8
-    free(common_files);
28bab8
-    free(duphash_file);
28bab8
-    free(additional_files);
28bab8
-
28bab8
-    return strbuf_free_nobuf(buf_dsc);
28bab8
-}
28bab8
-#endif
28bab8
-
28bab8
 /* Items we don't want to include to bz / logger */
28bab8
 static const char *const blacklisted_items[] = {
28bab8
     CD_DUMPDIR        ,
28bab8
@@ -365,13 +319,3 @@ char* make_description_logger(problem_data_t *problem_data, unsigned max_text_si
28bab8
                 MAKEDESC_SHOW_FILES | MAKEDESC_SHOW_MULTILINE
28bab8
     );
28bab8
 }
28bab8
-
28bab8
-char* make_description_mailx(problem_data_t *problem_data, unsigned max_text_size)
28bab8
-{
28bab8
-    return make_description(
28bab8
-                problem_data,
28bab8
-                (char**)blacklisted_items_mailx,
28bab8
-                max_text_size,
28bab8
-                MAKEDESC_SHOW_FILES | MAKEDESC_SHOW_MULTILINE
28bab8
-    );
28bab8
-}
28bab8
diff --git a/src/plugins/reporter-mailx.c b/src/plugins/reporter-mailx.c
28bab8
index 54dc82e..a062abd 100644
28bab8
--- a/src/plugins/reporter-mailx.c
28bab8
+++ b/src/plugins/reporter-mailx.c
28bab8
@@ -18,6 +18,25 @@
28bab8
 */
28bab8
 #include "internal_libreport.h"
28bab8
 #include "client.h"
28bab8
+#include "problem_report.h"
28bab8
+
28bab8
+#define PR_DEFAULT_SUBJECT \
28bab8
+    "[abrt] %pkg_name%[[: %crash_function%()]][[: %reason%]][[: TAINTED %tainted_short%]]"
28bab8
+
28bab8
+#define PR_MAILX_TEMPLATE \
28bab8
+    "%%summary:: %s\n" \
28bab8
+    "\n" \
28bab8
+    "::" \
28bab8
+    FILENAME_REASON","FILENAME_CRASH_FUNCTION"," \
28bab8
+    FILENAME_CMDLINE","FILENAME_EXECUTABLE"," \
28bab8
+    FILENAME_PACKAGE","FILENAME_COMPONENT","FILENAME_PID","FILENAME_PWD"," \
28bab8
+    FILENAME_HOSTNAME","FILENAME_COUNT", %%oneline\n" \
28bab8
+    "\n" \
28bab8
+    "::" \
28bab8
+    FILENAME_REPORTED_TO","FILENAME_BACKTRACE","FILENAME_CORE_BACKTRACE \
28bab8
+    ", %%multiline"
28bab8
+
28bab8
+#define PR_ATTACH_BINARY "\n%attach:: %binary"
28bab8
 
28bab8
 static void exec_and_feed_input(const char* text, char **args)
28bab8
 {
28bab8
@@ -79,6 +98,7 @@ static char *ask_email_address(const char *type, const char *def_address)
28bab8
 static void create_and_send_email(
28bab8
                 const char *dump_dir_name,
28bab8
                 map_string_t *settings,
28bab8
+                const char *fmt_file,
28bab8
                 bool notify_only)
28bab8
 {
28bab8
     problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
28bab8
@@ -86,8 +106,6 @@ static void create_and_send_email(
28bab8
         xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
28bab8
 
28bab8
     char* env;
28bab8
-    env = getenv("Mailx_Subject");
28bab8
-    const char *subject = (env ? env : get_map_string_item_or_NULL(settings, "Subject") ? : "[abrt] full crash report");
28bab8
     env = getenv("Mailx_EmailFrom");
28bab8
     char *email_from = (env ? xstrdup(env) : xstrdup(get_map_string_item_or_NULL(settings, "EmailFrom")) ? : ask_email_address("sender", "user@localhost"));
28bab8
     env = getenv("Mailx_EmailTo");
28bab8
@@ -99,22 +117,52 @@ static void create_and_send_email(
28bab8
     unsigned arg_size = 0;
28bab8
     args = append_str_to_vector(args, &arg_size, "/bin/mailx");
28bab8
 
28bab8
-    char *dsc = make_description_mailx(problem_data, CD_TEXT_ATT_SIZE_LOGGER);
28bab8
+    problem_formatter_t *pf = problem_formatter_new();
28bab8
+    /* formatting file is not set */
28bab8
+    if (fmt_file == NULL)
28bab8
+    {
28bab8
+        env = getenv("Mailx_Subject");
28bab8
+        const char *subject = (env ? env : get_map_string_item_or_NULL(settings, "Subject") ? : PR_DEFAULT_SUBJECT);
28bab8
+
28bab8
+        char *format_string = xasprintf(PR_MAILX_TEMPLATE, subject);
28bab8
+
28bab8
+        /* attaching binary file to the email */
28bab8
+        if (send_binary_data)
28bab8
+            format_string = append_to_malloced_string(format_string, PR_ATTACH_BINARY);
28bab8
+
28bab8
+        if (problem_formatter_load_string(pf, format_string))
28bab8
+            error_msg_and_die("BUG: Invalid default problem report format string");
28bab8
 
28bab8
-    if (send_binary_data)
28bab8
+        free(format_string);
28bab8
+    }
28bab8
+    else
28bab8
     {
28bab8
-        GHashTableIter iter;
28bab8
-        char *name;
28bab8
-        struct problem_item *value;
28bab8
-        g_hash_table_iter_init(&iter, problem_data);
28bab8
-        while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value))
28bab8
-        {
28bab8
-            if (value->flags & CD_FLAG_BIN)
28bab8
-            {
28bab8
-                args = append_str_to_vector(args, &arg_size, "-a");
28bab8
-                args = append_str_to_vector(args, &arg_size, value->content);
28bab8
-            }
28bab8
-        }
28bab8
+        if (problem_formatter_load_file(pf, fmt_file))
28bab8
+            error_msg_and_die("Invalid format file: %s", fmt_file);
28bab8
+    }
28bab8
+
28bab8
+    problem_report_t *pr = NULL;
28bab8
+    if (problem_formatter_generate_report(pf, problem_data, &pr))
28bab8
+        error_msg_and_die("Failed to format bug report from problem data");
28bab8
+
28bab8
+    const char *subject = problem_report_get_summary(pr);
28bab8
+    const char *dsc = problem_report_get_description(pr);
28bab8
+
28bab8
+    log_debug("subject: %s\n"
28bab8
+              "\n"
28bab8
+              "%s"
28bab8
+              "\n"
28bab8
+              , subject
28bab8
+              , dsc);
28bab8
+
28bab8
+    /* attaching files to the email */
28bab8
+    for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
28bab8
+    {
28bab8
+        log_debug("Attaching '%s' to the email", (const char *)a->data);
28bab8
+        args = append_str_to_vector(args, &arg_size, "-a");
28bab8
+        char *full_name = concat_path_file(realpath(dump_dir_name, NULL), a->data);
28bab8
+        args = append_str_to_vector(args, &arg_size, full_name);
28bab8
+        free(full_name);
28bab8
     }
28bab8
 
28bab8
     args = append_str_to_vector(args, &arg_size, "-s");
28bab8
@@ -135,7 +183,8 @@ static void create_and_send_email(
28bab8
     log(_("Sending an email..."));
28bab8
     exec_and_feed_input(dsc, args);
28bab8
 
28bab8
-    free(dsc);
28bab8
+    problem_report_free(pr);
28bab8
+    problem_formatter_free(pf);
28bab8
 
28bab8
     while (*args)
28bab8
         free(*args++);
28bab8
@@ -173,10 +222,11 @@ int main(int argc, char **argv)
28bab8
 
28bab8
     const char *dump_dir_name = ".";
28bab8
     const char *conf_file = CONF_DIR"/plugins/mailx.conf";
28bab8
+    const char *fmt_file = NULL;
28bab8
 
28bab8
     /* Can't keep these strings/structs static: _() doesn't support that */
28bab8
     const char *program_usage_string = _(
28bab8
-        "& [-v] -d DIR [-c CONFFILE]"
28bab8
+        "& [-v] -d DIR [-c CONFFILE] [-F FMTFILE]"
28bab8
         "\n"
28bab8
         "\n""Sends contents of a problem directory DIR via email"
28bab8
         "\n"
28bab8
@@ -191,13 +241,15 @@ int main(int argc, char **argv)
28bab8
         OPT_v = 1 << 0,
28bab8
         OPT_d = 1 << 1,
28bab8
         OPT_c = 1 << 2,
28bab8
-        OPT_n = 1 << 3,
28bab8
+        OPT_F = 1 << 3,
28bab8
+        OPT_n = 1 << 4,
28bab8
     };
28bab8
     /* Keep enum above and order of options below in sync! */
28bab8
     struct options program_options[] = {
28bab8
         OPT__VERBOSE(&g_verbose),
28bab8
         OPT_STRING('d', NULL, &dump_dir_name, "DIR"     , _("Problem directory")),
28bab8
         OPT_STRING('c', NULL, &conf_file    , "CONFFILE", _("Config file")),
28bab8
+        OPT_STRING('F', NULL, &fmt_file     , "FILE"    , _("Formatting file for an email")),
28bab8
         OPT_BOOL('n', "notify-only", NULL  , _("Notify only (Do not mark the report as sent)")),
28bab8
         OPT_END()
28bab8
     };
28bab8
@@ -208,7 +260,7 @@ int main(int argc, char **argv)
28bab8
     map_string_t *settings = new_map_string();
28bab8
     load_conf_file(conf_file, settings, /*skip key w/o values:*/ false);
28bab8
 
28bab8
-    create_and_send_email(dump_dir_name, settings, /*notify_only*/(opts & OPT_n));
28bab8
+    create_and_send_email(dump_dir_name, settings, fmt_file, /*notify_only*/(opts & OPT_n));
28bab8
 
28bab8
     free_map_string(settings);
28bab8
     return 0;
28bab8
-- 
28bab8
1.8.3.1
28bab8