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

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