From ebad4b05134fcf1e7a1a2f4a2f5434ed9284d4e6 Mon Sep 17 00:00:00 2001 From: Jakub Filak 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 --- 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