Blob Blame History Raw
From ebad4b05134fcf1e7a1a2f4a2f5434ed9284d4e6 Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Thu, 11 Dec 2014 16:15:35 +0100
Subject: [PATCH] dump_dir: add function for creating a dump dir in dump
 location

Related to abrt/abrt#548

Signed-off-by: Jakub Filak <jfilak@redhat.com>
---
 src/include/dump_dir.h     |  11 +++++
 src/include/problem_data.h |   9 ++++
 src/lib/create_dump_dir.c  | 101 +++++++++++++++++++++++++++------------------
 3 files changed, 81 insertions(+), 40 deletions(-)

diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
index ed4c873..fbe2e31 100644
--- a/src/include/dump_dir.h
+++ b/src/include/dump_dir.h
@@ -165,6 +165,17 @@ int dump_dir_stat_for_uid(const char *dirname, uid_t uid);
 */
 int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason);
 
+typedef int (*save_data_call_back)(struct dump_dir *, void *args);
+
+/* Saves data in a new dump directory
+ *
+ * Creates a new dump directory in "problem dump location", adds the basic
+ * information to the new directory, calls given callback to allow callees to
+ * customize the dump dir contents (save problem data) and commits the dump
+ * directory (makes the directory visible for a problem daemon).
+ */
+struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type,
+        uid_t uid, save_data_call_back save_data, void *args);
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/include/problem_data.h b/src/include/problem_data.h
index 7a65d6c..661d31e 100644
--- a/src/include/problem_data.h
+++ b/src/include/problem_data.h
@@ -132,6 +132,15 @@ problem_data_t *create_problem_data_for_reporting(const char *dump_dir_name);
 */
 struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name);
 
+/**
+  @brief Saves the problem data object in opened dump directory
+
+  @param dd Dump directory
+  @param problem_data Problem data object to save
+  @return 0 on success; otherwise non-zero value
+ */
+int save_problem_data_in_dump_dir(struct dump_dir *dd, problem_data_t *problem_data);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c
index 4f67523..9f312e0 100644
--- a/src/lib/create_dump_dir.c
+++ b/src/lib/create_dump_dir.c
@@ -30,36 +30,10 @@ static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir
     return dd;
 }
 
-struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name)
+struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type, uid_t uid, save_data_call_back save_data, void *args)
 {
     INITIALIZE_LIBREPORT();
 
-    char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
-
-    if (!type)
-    {
-        error_msg(_("Missing required item: '%s'"), FILENAME_ANALYZER);
-        return NULL;
-    }
-
-    uid_t uid = (uid_t)-1L;
-    char *uid_str = problem_data_get_content_or_NULL(problem_data, FILENAME_UID);
-
-    if (uid_str)
-    {
-        char *endptr;
-        errno = 0;
-        long val = strtol(uid_str, &endptr, 10);
-
-        if (errno != 0 || endptr == uid_str || *endptr != '\0' || INT_MAX < val)
-        {
-            error_msg(_("uid value is not valid: '%s'"), uid_str);
-            return NULL;
-        }
-
-        uid = (uid_t)val;
-    }
-
     struct timeval tv;
     if (gettimeofday(&tv, NULL) < 0)
     {
@@ -99,6 +73,34 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
     if (!dd) /* try_dd_create() already emitted the error message */
         goto ret;
 
+    if (save_data(dd, args))
+    {
+        dd_delete(dd);
+        dd = NULL;
+        goto ret;
+    }
+
+    /* need to create basic files AFTER we save the pd to dump_dir
+     * otherwise we can't skip already created files like in case when
+     * reporting from anaconda where we can't read /etc/{system,redhat}-release
+     * and os_release is taken from anaconda
+     */
+    dd_create_basic_files(dd, uid, NULL);
+
+    problem_id[strlen(problem_id) - strlen(NEW_PD_SUFFIX)] = '\0';
+    char* new_path = concat_path_file(base_dir_name, problem_id);
+    log_info("Renaming from '%s' to '%s'", dd->dd_dirname, new_path);
+    dd_rename(dd, new_path);
+
+ ret:
+    free(problem_id);
+    return dd;
+}
+
+int save_problem_data_in_dump_dir(struct dump_dir *dd, problem_data_t *problem_data)
+{
+    INITIALIZE_LIBREPORT();
+
     GHashTableIter iter;
     char *name;
     struct problem_item *value;
@@ -129,19 +131,38 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
         dd_save_text(dd, name, value->content);
     }
 
-    /* need to create basic files AFTER we save the pd to dump_dir
-     * otherwise we can't skip already created files like in case when
-     * reporting from anaconda where we can't read /etc/{system,redhat}-release
-     * and os_release is taken from anaconda
-     */
-    dd_create_basic_files(dd, uid, NULL);
+    return 0;
+}
 
-    problem_id[strlen(problem_id) - strlen(NEW_PD_SUFFIX)] = '\0';
-    char* new_path = concat_path_file(base_dir_name, problem_id);
-    log_info("Renaming from '%s' to '%s'", dd->dd_dirname, new_path);
-    dd_rename(dd, new_path);
+struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name)
+{
+    INITIALIZE_LIBREPORT();
 
- ret:
-    free(problem_id);
-    return dd;
+    char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
+
+    if (!type)
+    {
+        error_msg(_("Missing required item: '%s'"), FILENAME_ANALYZER);
+        return NULL;
+    }
+
+    uid_t uid = (uid_t)-1L;
+    char *uid_str = problem_data_get_content_or_NULL(problem_data, FILENAME_UID);
+
+    if (uid_str)
+    {
+        char *endptr;
+        errno = 0;
+        long val = strtol(uid_str, &endptr, 10);
+
+        if (errno != 0 || endptr == uid_str || *endptr != '\0' || INT_MAX < val)
+        {
+            error_msg(_("uid value is not valid: '%s'"), uid_str);
+            return NULL;
+        }
+
+        uid = (uid_t)val;
+    }
+
+    return create_dump_dir(base_dir_name, type, uid, (save_data_call_back)save_problem_data_in_dump_dir, problem_data);
 }
-- 
2.1.0