diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Makefile.am | 3 | ||||
-rw-r--r-- | src/lib/abrt_dbus.c | 218 | ||||
-rw-r--r-- | src/lib/abrt_dbus.h | 4 | ||||
-rw-r--r-- | src/lib/crash_dump.cpp | 170 | ||||
-rw-r--r-- | src/lib/create_crash_dump_dir.cpp | 24 | ||||
-rw-r--r-- | src/lib/make_descr.cpp | 98 |
6 files changed, 371 insertions, 146 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index a17df28e..cfcb9947 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -91,6 +91,7 @@ libabrt_daemon_la_CPPFLAGS = \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ -DCONF_DIR=\"$(CONF_DIR)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ + $(GLIB_CFLAGS) \ -D_GNU_SOURCE libabrt_daemon_la_LDFLAGS = \ -version-info 0:1:0 @@ -108,6 +109,7 @@ libabrt_web_la_CPPFLAGS = \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ -DCONF_DIR=\"$(CONF_DIR)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ + $(GLIB_CFLAGS) \ $(CURL_CFLAGS) \ $(LIBXML_CFLAGS) \ $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ @@ -115,6 +117,7 @@ libabrt_web_la_CPPFLAGS = \ libabrt_web_la_LDFLAGS = \ -version-info 0:1:0 libabrt_web_la_LIBADD = \ + $(GLIB_LIBS) \ $(CURL_LIBS) \ $(LIBXML_LIBS) \ $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) diff --git a/src/lib/abrt_dbus.c b/src/lib/abrt_dbus.c index 6bc155e3..2ba5fa12 100644 --- a/src/lib/abrt_dbus.c +++ b/src/lib/abrt_dbus.c @@ -156,6 +156,70 @@ void store_string(DBusMessageIter* iter, const char* val) free((char*)sanitized); } +/* Helpers for storing crash_data */ + +static void store_crash_item(DBusMessageIter* iter, struct crash_item *val) +{ + DBusMessageIter sub_iter; + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &sub_iter)) + die_out_of_memory(); + + /* Compat with python/cli: + * Crash item is represented in dbus as 3-element vector of strings: + * type, editable, content. + * This doesn't match daemon-side representation: { content, flags } struct + */ + store_string(&sub_iter, (val->flags & CD_FLAG_SYS ? "s" : (val->flags & CD_FLAG_BIN ? "b" : "t"))); + store_string(&sub_iter, (val->flags & CD_FLAG_ISEDITABLE ? "y" : "n")); + store_string(&sub_iter, val->content); + + if (!dbus_message_iter_close_container(iter, &sub_iter)) + die_out_of_memory(); +} +void store_crash_data(DBusMessageIter* dbus_iter, crash_data_t *val) +{ + DBusMessageIter sub_iter; + /* crash_data is a map. map in dbus is an array of two element structs "({...})": + * "s" (string) for key and "as" for value (in this case, array of strings) */ + if (!dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY, "{sas}", &sub_iter)) + die_out_of_memory(); + + GHashTableIter iter; + char *name; + struct crash_item *value; + g_hash_table_iter_init(&iter, val); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) + { + DBusMessageIter sub_sub_iter; + if (!dbus_message_iter_open_container(&sub_iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub_sub_iter)) + die_out_of_memory(); + store_string(&sub_sub_iter, name); + store_crash_item(&sub_sub_iter, value); + if (!dbus_message_iter_close_container(&sub_iter, &sub_sub_iter)) + die_out_of_memory(); + } + + if (!dbus_message_iter_close_container(dbus_iter, &sub_iter)) + die_out_of_memory(); +} +void store_vector_of_crash_data(DBusMessageIter* iter, vector_of_crash_data_t *val) +{ + DBusMessageIter sub_iter; + /* "array of maps". map in dbus is an array ("a") of two element structs "({...})": + * "s" (string) for key and "as" for value (in this case, array of strings) */ + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "a{sas}", &sub_iter)) + die_out_of_memory(); + + for (unsigned i = 0; i < val->len; i++) + { + crash_data_t *crash_data = get_crash_data(val, i); + store_crash_data(&sub_iter, crash_data); + } + + if (!dbus_message_iter_close_container(iter, &sub_iter)) + die_out_of_memory(); +} + /* * Helpers for parsing DBus messages @@ -217,6 +281,8 @@ int load_uint64(DBusMessageIter* iter, uint64_t *val) } int load_charp(DBusMessageIter* iter, const char** val) { + *val = NULL; + int type = dbus_message_iter_get_arg_type(iter); if (type != DBUS_TYPE_STRING) { @@ -228,6 +294,158 @@ int load_charp(DBusMessageIter* iter, const char** val) return dbus_message_iter_next(iter); } +/* Helpers for loading crash_data */ + +static int load_crash_item(DBusMessageIter* iter, struct crash_item *item) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_ARRAY) + { + error_msg("array expected in dbus message, but not found ('%c')", type); + return -1; + } + + /* Compat with python/cli: + * Crash item is represented in dbus as 3-element vector of strings: + * type, editable, content. + * This doesn't match daemon-side representation: { content, flags } struct + */ + + DBusMessageIter sub_iter; + dbus_message_iter_recurse(iter, &sub_iter); + + const char *typestr; + int r = load_charp(&sub_iter, &typestr); + if (r != ABRT_DBUS_MORE_FIELDS) + { + error_msg("malformed crash_item element in dbus message"); + return -1; + } + const char *editable; + r = load_charp(&sub_iter, &editable); + if (r != ABRT_DBUS_MORE_FIELDS) + { + error_msg("malformed crash_item element in dbus message"); + return -1; + } + const char *content; + r = load_charp(&sub_iter, &content); + if (r != ABRT_DBUS_LAST_FIELD) + { + error_msg("malformed crash_item element in dbus message"); + return -1; + } + item->flags = 0; + if (typestr[0] == 's') item->flags |= CD_FLAG_SYS; + if (typestr[0] == 'b') item->flags |= CD_FLAG_BIN; + if (typestr[0] == 't') item->flags |= CD_FLAG_TXT; + if (editable[0] == 'y') item->flags |= CD_FLAG_ISEDITABLE; + if (editable[0] == 'n') item->flags |= CD_FLAG_ISNOTEDITABLE; + item->content = xstrdup(content); + return 0; +} +int load_crash_data(DBusMessageIter* iter, crash_data_t **val) +{ + *val = NULL; + + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_ARRAY) + { + error_msg("array expected in dbus message, but not found ('%c')", type); + return -1; + } + + crash_data_t *result = new_crash_data(); + + DBusMessageIter sub_iter; + dbus_message_iter_recurse(iter, &sub_iter); + + bool next_exists; + int r; +//int cnt = 0; + do { + type = dbus_message_iter_get_arg_type(&sub_iter); + if (type != DBUS_TYPE_DICT_ENTRY) + { + /* When the map has 0 elements, we see DBUS_TYPE_INVALID (on the first iteration) */ + if (type == DBUS_TYPE_INVALID) + break; + error_msg("sub_iter type is not DBUS_TYPE_DICT_ENTRY (%c)!", type); + free_crash_data(result); + return -1; + } + + DBusMessageIter sub_sub_iter; + dbus_message_iter_recurse(&sub_iter, &sub_sub_iter); + + const char *key; + r = load_charp(&sub_sub_iter, &key); + if (r != ABRT_DBUS_MORE_FIELDS) + { + if (r == ABRT_DBUS_LAST_FIELD) + error_msg("malformed map element in dbus message"); + free_crash_data(result); + return -1; + } + struct crash_item *value = xzalloc(sizeof(*value)); + r = load_crash_item(&sub_sub_iter, value); + if (r != ABRT_DBUS_LAST_FIELD) + { + if (r == ABRT_DBUS_MORE_FIELDS) + error_msg("malformed map element in dbus message"); + free(value); + free_crash_data(result); + return -1; + } + g_hash_table_replace(result, xstrdup(key), value); +//cnt++; + next_exists = dbus_message_iter_next(&sub_iter); + } while (next_exists); +//log("%s: %d elems", __func__, cnt); + + *val = result; + return dbus_message_iter_next(iter); /* note: this can't fail (returns bool, thus never < 0) */ +} +int load_vector_of_crash_data(DBusMessageIter* iter, vector_of_crash_data_t **val) +{ + *val = NULL; + + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_ARRAY) + { + error_msg("array expected in dbus message, but not found ('%c')", type); + return -1; + } + + DBusMessageIter sub_iter; + dbus_message_iter_recurse(iter, &sub_iter); + + vector_of_crash_data_t *result = new_vector_of_crash_data(); + + int r; +//int cnt = 0; + /* When the vector has 0 elements, we see DBUS_TYPE_INVALID here */ + type = dbus_message_iter_get_arg_type(&sub_iter); + if (type != DBUS_TYPE_INVALID) + { + do { + crash_data_t *cd = NULL; +//cnt++; + r = load_crash_data(&sub_iter, &cd); + if (r < 0) + { + free_vector_of_crash_data(result); + return r; + } + g_ptr_array_add(result, cd); + } while (r == ABRT_DBUS_MORE_FIELDS); + } +//log("%s: %d elems", __func__, cnt); + + *val = result; + return dbus_message_iter_next(iter); /* note: this can't fail (returns bool, thus never < 0) */ +} + /* * Glib integration machinery diff --git a/src/lib/abrt_dbus.h b/src/lib/abrt_dbus.h index 16b91d5b..b971280c 100644 --- a/src/lib/abrt_dbus.h +++ b/src/lib/abrt_dbus.h @@ -83,6 +83,8 @@ void store_uint32(DBusMessageIter* iter, uint32_t val); void store_int64(DBusMessageIter* iter, int64_t val); void store_uint64(DBusMessageIter* iter, uint64_t val); void store_string(DBusMessageIter* iter, const char* val); +void store_crash_data(DBusMessageIter* iter, crash_data_t *val); +void store_vector_of_crash_data(DBusMessageIter* iter, vector_of_crash_data_t *val); /* * Helpers for parsing DBus messages @@ -104,6 +106,8 @@ int load_uint32(DBusMessageIter* iter, uint32_t *val); int load_int64(DBusMessageIter* iter, int64_t *val); int load_uint64(DBusMessageIter* iter, uint64_t *val); int load_charp(DBusMessageIter* iter, const char **val); +int load_crash_data(DBusMessageIter* iter, crash_data_t **val); +int load_vector_of_crash_data(DBusMessageIter* iter, vector_of_crash_data_t **val); #ifdef __cplusplus } diff --git a/src/lib/crash_dump.cpp b/src/lib/crash_dump.cpp index cca28021..73181c72 100644 --- a/src/lib/crash_dump.cpp +++ b/src/lib/crash_dump.cpp @@ -19,6 +19,70 @@ #include "abrtlib.h" #include "abrt_crash_dump.h" +static void free_crash_item(void *ptr) +{ + if (ptr) + { + struct crash_item *item = (struct crash_item *)ptr; + free(item->content); + free(item); + } +} + + +/* crash_data["name"] = { "content", CD_FLAG_foo_bits } */ + +crash_data_t *new_crash_data(void) +{ + return g_hash_table_new_full(g_str_hash, g_str_equal, + free, free_crash_item); +} + +void add_to_crash_data_ext(crash_data_t *crash_data, + const char *name, + const char *content, + unsigned flags) +{ + struct crash_item *item = (struct crash_item *)xzalloc(sizeof(*item)); + item->content = xstrdup(content); + item->flags = flags; + g_hash_table_replace(crash_data, xstrdup(name), item); +} + +void add_to_crash_data(crash_data_t *crash_data, + const char *name, + const char *content) +{ + add_to_crash_data_ext(crash_data, name, content, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE); +} + +const char *get_crash_item_content_or_die(crash_data_t *crash_data, const char *key) +{ + struct crash_item *item = get_crash_data_item_or_NULL(crash_data, key); + if (!item) + error_msg_and_die("Error accessing crash data: no ['%s']", key); + return item->content; +} + +const char *get_crash_item_content_or_NULL(crash_data_t *crash_data, const char *key) +{ + struct crash_item *item = get_crash_data_item_or_NULL(crash_data, key); + if (!item) + return NULL; + return item->content; +} + + +/* crash_data_vector[i] = { "name" = { "content", CD_FLAG_foo_bits } } */ + +vector_of_crash_data_t *new_vector_of_crash_data(void) +{ + return g_ptr_array_new_with_free_func((void (*)(void*)) &free_crash_data); +} + + +/* Miscellaneous helpers */ + static const char *const editable_files[] = { FILENAME_DESCRIPTION, FILENAME_COMMENT , @@ -42,36 +106,6 @@ bool is_editable_file(const char *file_name) return is_editable(file_name, editable_files); } - -void add_to_crash_data_ext(map_crash_data_t& pCrashData, - const char *pItem, - const char *pType, - const char *pEditable, - const char *pContent) -{ - map_crash_data_t::iterator it = pCrashData.find(pItem); - if (it == pCrashData.end()) { - vector_string_t& v = pCrashData[pItem]; /* create empty vector */ - v.push_back(pType); - v.push_back(pEditable); - v.push_back(pContent); - return; - } - vector_string_t& v = it->second; - while (v.size() < 3) - v.push_back(""); - v[CD_TYPE] = pType; - v[CD_EDITABLE] = pEditable; - v[CD_CONTENT] = pContent; -} - -void add_to_crash_data(map_crash_data_t& pCrashData, - const char *pItem, - const char *pContent) -{ - add_to_crash_data_ext(pCrashData, pItem, CD_TXT, CD_ISNOTEDITABLE, pContent); -} - static char* is_text_file(const char *name, ssize_t *sz) { /* We were using magic.h API to check for file being text, but it thinks @@ -146,10 +180,11 @@ static char* is_text_file(const char *name, ssize_t *sz) return NULL; /* it's binary */ } -void load_crash_data_from_crash_dump_dir(struct dump_dir *dd, map_crash_data_t& data) +crash_data_t *load_crash_data_from_crash_dump_dir(struct dump_dir *dd) { char *short_name; char *full_name; + crash_data_t *crash_data = new_crash_data(); dd_init_next_file(dd); while (dd_get_next_file(dd, &short_name, &full_name)) @@ -163,11 +198,10 @@ void load_crash_data_from_crash_dump_dir(struct dump_dir *dd, map_crash_data_t& text = is_text_file(full_name, &sz); if (!text) { - add_to_crash_data_ext(data, + add_to_crash_data_ext(crash_data, short_name, - CD_BIN, - CD_ISNOTEDITABLE, - full_name + full_name, + CD_FLAG_BIN + CD_FLAG_ISNOTEDITABLE ); free(short_name); @@ -183,62 +217,30 @@ void load_crash_data_from_crash_dump_dir(struct dump_dir *dd, map_crash_data_t& content = dd_load_text(dd, short_name); free(text); - add_to_crash_data_ext(data, + add_to_crash_data_ext(crash_data, short_name, - CD_TXT, - editable ? CD_ISEDITABLE : CD_ISNOTEDITABLE, - content + content, + (editable ? CD_FLAG_TXT + CD_FLAG_ISEDITABLE : CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE) ); free(short_name); free(full_name); free(content); } + return crash_data; } -static const std::string* helper_get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) +void log_map_crash_data(crash_data_t *crash_data, const char *pfx) { - map_crash_data_t::const_iterator it = crash_data.find(key); - if (it == crash_data.end()) { - return NULL; - } - if (it->second.size() <= CD_CONTENT) { - return NULL; - } - return &it->second[CD_CONTENT]; -} - -const std::string& get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) -{ - const std::string* sp = helper_get_crash_data_item_content(crash_data, key); - if (sp == NULL) { - if (crash_data.find(key) == crash_data.end()) - error_msg_and_die("Error accessing crash data: no ['%s']", key); - error_msg_and_die("Error accessing crash data: no ['%s'][%d]", key, CD_CONTENT); - } - return *sp; -} - -const char *get_crash_data_item_content_or_NULL(const map_crash_data_t& crash_data, const char *key) -{ - const std::string* sp = helper_get_crash_data_item_content(crash_data, key); - if (!sp) { - return NULL; - } - return sp->c_str(); -} - -void log_map_crash_data(const map_crash_data_t& data, const char *name) -{ - map_crash_data_t::const_iterator it = data.begin(); - while (it != data.end()) - { - ssize_t sz = it->second.size(); - log("%s[%s]:%s/%s/'%.20s'", - name, it->first.c_str(), - sz > 0 ? it->second[0].c_str() : "<NO [0]>", - sz > 1 ? it->second[1].c_str() : "<NO [1]>", - sz > 2 ? it->second[2].c_str() : "<NO [2]>" - ); - it++; - } + GHashTableIter iter; + char *name; + struct crash_item *value; + g_hash_table_iter_init(&iter, crash_data); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) + { + log("%s[%s]:'%s' 0x%x", + pfx, name, + value->content, + value->flags + ); + } } diff --git a/src/lib/create_crash_dump_dir.cpp b/src/lib/create_crash_dump_dir.cpp index 0a74411b..c3125db6 100644 --- a/src/lib/create_crash_dump_dir.cpp +++ b/src/lib/create_crash_dump_dir.cpp @@ -21,7 +21,7 @@ using namespace std; -struct dump_dir *create_crash_dump_dir(const map_crash_data_t& crash_data) +struct dump_dir *create_crash_dump_dir(crash_data_t *crash_data) { char *path = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%lu-%lu", (long)getpid(), (long)time(NULL)); struct dump_dir *dd = dd_create(path, getuid()); @@ -29,28 +29,24 @@ struct dump_dir *create_crash_dump_dir(const map_crash_data_t& crash_data) if (!dd) return NULL; - map_crash_data_t::const_iterator its = crash_data.begin(); - while (its != crash_data.end()) + GHashTableIter iter; + char *name; + struct crash_item *value; + g_hash_table_iter_init(&iter, crash_data); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) { - const char *name, *value; - name = its->first.c_str(); - if (name[0] == '.' || strchr(name, '/')) { error_msg("Crash data field name contains disallowed chars: '%s'", name); goto next; } -//FIXME: what to do with CD_BINs?? - /* Fields: CD_TYPE (is CD_SYS, CD_BIN or CD_TXT), - * CD_EDITABLE, CD_CONTENT */ - if (its->second[CD_TYPE] == CD_BIN) +//FIXME: what to do with CD_FLAG_BINs?? + if (value->flags & CD_FLAG_BIN) goto next; - value = its->second[CD_CONTENT].c_str(); - dd_save_text(dd, name, value); - next: - its++; + dd_save_text(dd, name, value->content); + next: ; } return dd; diff --git a/src/lib/make_descr.cpp b/src/lib/make_descr.cpp index 5502b581..9234fc98 100644 --- a/src/lib/make_descr.cpp +++ b/src/lib/make_descr.cpp @@ -75,30 +75,32 @@ static const char *const blacklisted_items[] = { NULL }; -char* make_description_mailx(const map_crash_data_t & crash_data) +char* make_description_mailx(crash_data_t *crash_data) { struct strbuf *buf_dsc = strbuf_new(); struct strbuf *buf_additional_files = strbuf_new(); struct strbuf *buf_duphash_file = strbuf_new(); struct strbuf *buf_common_files = strbuf_new(); - map_crash_data_t::const_iterator it; - for (it = crash_data.begin(); it != crash_data.end(); it++) + GHashTableIter iter; + char *name; + struct crash_item *value; + g_hash_table_iter_init(&iter, crash_data); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) { - if (it->second[CD_TYPE] == CD_TXT) + if (value->flags & CD_FLAG_TXT) { - const char *itemname = it->first.c_str(); - if ((strcmp(itemname, FILENAME_DUPHASH) != 0) - && (strcmp(itemname, FILENAME_ARCHITECTURE) != 0) - && (strcmp(itemname, FILENAME_KERNEL) != 0) - && (strcmp(itemname, FILENAME_PACKAGE) != 0) + if ((strcmp(name, FILENAME_DUPHASH) != 0) + && (strcmp(name, FILENAME_ARCHITECTURE) != 0) + && (strcmp(name, FILENAME_KERNEL) != 0) + && (strcmp(name, FILENAME_PACKAGE) != 0) ) { - strbuf_append_strf(buf_additional_files, "%s\n-----\n%s\n\n", itemname, it->second[CD_CONTENT].c_str()); + strbuf_append_strf(buf_additional_files, "%s\n-----\n%s\n\n", name, value->content); } - else if (strcmp(itemname, FILENAME_DUPHASH) == 0) - strbuf_append_strf(buf_duphash_file, "%s\n-----\n%s\n\n", itemname, it->second[CD_CONTENT].c_str()); + else if (strcmp(name, FILENAME_DUPHASH) == 0) + strbuf_append_strf(buf_duphash_file, "%s\n-----\n%s\n\n", name, value->content); else - strbuf_append_strf(buf_common_files, "%s\n-----\n%s\n\n", itemname, it->second[CD_CONTENT].c_str()); + strbuf_append_strf(buf_common_files, "%s\n-----\n%s\n\n", name, value->content); } } @@ -117,24 +119,26 @@ char* make_description_mailx(const map_crash_data_t & crash_data) return strbuf_free_nobuf(buf_dsc); } -char* make_description_bz(const map_crash_data_t& pCrashData) +char* make_description_bz(crash_data_t *crash_data) { struct strbuf *buf_dsc = strbuf_new(); struct strbuf *buf_long_dsc = strbuf_new(); - map_crash_data_t::const_iterator it = pCrashData.begin(); - for (; it != pCrashData.end(); it++) + GHashTableIter iter; + char *name; + struct crash_item *value; + g_hash_table_iter_init(&iter, crash_data); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) { - const char *itemname = it->first.c_str(); - const char *type = it->second[CD_TYPE].c_str(); - const char *content = it->second[CD_CONTENT].c_str(); - if (strcmp(type, CD_TXT) == 0) + unsigned flags = value->flags; + const char *content = value->content; + if (flags & CD_FLAG_TXT) { /* Skip items we are not interested in */ const char *const *bl = blacklisted_items; while (*bl) { - if (strcmp(itemname, *bl) == 0) + if (strcmp(name, *bl) == 0) break; bl++; } @@ -151,7 +155,7 @@ char* make_description_bz(const map_crash_data_t& pCrashData) add_content(&was_multiline, &tmp, /* "reproduce: blah" looks ugly, fixing: */ - (strcmp(itemname, FILENAME_REPRODUCE) == 0) ? "How to reproduce" : itemname, + (strcmp(name, FILENAME_REPRODUCE) == 0) ? "How to reproduce" : name, content ); @@ -170,7 +174,7 @@ char* make_description_bz(const map_crash_data_t& pCrashData) } else { bool was_multiline = 0; char *dsc = NULL; - add_content(&was_multiline, &dsc, "Attached file", itemname); + add_content(&was_multiline, &dsc, "Attached file", name); strbuf_append_str(buf_dsc, dsc); free(dsc); } @@ -189,25 +193,25 @@ char* make_description_bz(const map_crash_data_t& pCrashData) return strbuf_free_nobuf(buf_dsc); } -char* make_description_logger(const map_crash_data_t& pCrashData) +char* make_description_logger(crash_data_t *crash_data) { struct strbuf *buf_dsc = strbuf_new(); struct strbuf *buf_long_dsc = strbuf_new(); - map_crash_data_t::const_iterator it = pCrashData.begin(); - for (; it != pCrashData.end(); it++) + GHashTableIter iter; + char *name; + struct crash_item *value; + g_hash_table_iter_init(&iter, crash_data); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) { - const char *filename = it->first.c_str(); - const char *type = it->second[CD_TYPE].c_str(); - const char *content = it->second[CD_CONTENT].c_str(); - if ((strcmp(type, CD_TXT) == 0) - || (strcmp(type, CD_BIN) == 0) - ) { + const char *content = value->content; + if (value->flags & (CD_FLAG_TXT|CD_FLAG_BIN)) + { /* Skip items we are not interested in */ const char *const *bl = blacklisted_items; while (*bl) { - if (filename == *bl) + if (name == *bl) break; bl++; } @@ -218,7 +222,7 @@ char* make_description_logger(const map_crash_data_t& pCrashData) bool was_multiline = 0; char *tmp = NULL; - add_content(&was_multiline, &tmp, filename, content); + add_content(&was_multiline, &tmp, name, content); if (was_multiline) { @@ -242,29 +246,27 @@ char* make_description_logger(const map_crash_data_t& pCrashData) return strbuf_free_nobuf(buf_dsc); } -char* make_description_reproduce_comment(const map_crash_data_t& pCrashData) +char* make_description_reproduce_comment(crash_data_t *crash_data) { char *repro = NULL; char *comment = NULL; + struct crash_item *value; - map_crash_data_t::const_iterator end = pCrashData.end(); - map_crash_data_t::const_iterator it; - - it = pCrashData.find(FILENAME_REPRODUCE); - if (it != end) + value = get_crash_data_item_or_NULL(crash_data, FILENAME_REPRODUCE); + if (value) { - if ((it->second[CD_CONTENT].size() > 0) - && (it->second[CD_CONTENT] != "1.\n2.\n3.\n")) - { - repro = xasprintf("\n\nHow to reproduce\n-----\n%s", it->second[CD_CONTENT].c_str()); + if (value->content[0] + && strcmp(value->content, "1.\n2.\n3.\n") != 0 + ) { + repro = xasprintf("\n\nHow to reproduce\n-----\n%s", value->content); } } - it = pCrashData.find(FILENAME_COMMENT); - if (it != end) + value = get_crash_data_item_or_NULL(crash_data, FILENAME_COMMENT); + if (value) { - if (it->second[CD_CONTENT].size() > 0) - comment = xasprintf("\n\nComment\n-----\n%s", it->second[CD_CONTENT].c_str()); + if (value->content[0]) + comment = xasprintf("\n\nComment\n-----\n%s", value->content); } if (!repro && !comment) |