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

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