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

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