summaryrefslogtreecommitdiffstats
path: root/src/daemon/MiddleWare.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/MiddleWare.cpp')
-rw-r--r--src/daemon/MiddleWare.cpp132
1 files changed, 67 insertions, 65 deletions
diff --git a/src/daemon/MiddleWare.cpp b/src/daemon/MiddleWare.cpp
index 22e49620..6abf019e 100644
--- a/src/daemon/MiddleWare.cpp
+++ b/src/daemon/MiddleWare.cpp
@@ -43,8 +43,7 @@ CPluginManager* g_pPluginManager;
* @param pCrashData A crash info.
* @return It return results of operation. See mw_result_t.
*/
-static mw_result_t FillCrashInfo(const char *dump_dir_name,
- map_crash_data_t& pCrashData);
+static crash_data_t *FillCrashInfo(const char *dump_dir_name);
/**
* Transforms a debugdump directory to inner crash
@@ -52,13 +51,13 @@ static mw_result_t FillCrashInfo(const char *dump_dir_name,
* @param dump_dir_name A debugdump dir containing all necessary data.
* @param pCrashData A created crash report.
*/
-static bool DebugDumpToCrashReport(const char *dump_dir_name, map_crash_data_t& pCrashData)
+static crash_data_t *DebugDumpToCrashReport(const char *dump_dir_name)
{
VERB3 log(" DebugDumpToCrashReport('%s')", dump_dir_name);
struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
- return false;
+ return NULL;
static const char *const must_have_files[] = {
FILENAME_ARCHITECTURE,
@@ -76,21 +75,21 @@ static bool DebugDumpToCrashReport(const char *dump_dir_name, map_crash_data_t&
{
dd_close(dd);
log("Important file '%s/%s' is missing", dump_dir_name, *v);
- return false;
+ return NULL;
}
v++;
}
- load_crash_data_from_crash_dump_dir(dd, pCrashData);
+ crash_data_t *crash_data = load_crash_data_from_crash_dump_dir(dd);
char *events = list_possible_events(dd, NULL, "");
dd_close(dd);
- add_to_crash_data_ext(pCrashData, CD_EVENTS, CD_SYS, CD_ISNOTEDITABLE, events);
+ add_to_crash_data_ext(crash_data, CD_EVENTS, events, CD_FLAG_SYS + CD_FLAG_ISNOTEDITABLE);
free(events);
- add_to_crash_data_ext(pCrashData, CD_DUMPDIR, CD_SYS, CD_ISNOTEDITABLE, dump_dir_name);
+ add_to_crash_data_ext(crash_data, CD_DUMPDIR, dump_dir_name, CD_FLAG_SYS + CD_FLAG_ISNOTEDITABLE);
- return true;
+ return crash_data;
}
static char *do_log_and_update_client(char *log_line, void *param)
@@ -118,9 +117,11 @@ static char *do_log_and_update_client(char *log_line, void *param)
static mw_result_t CreateCrashReport(const char *dump_dir_name,
long caller_uid,
int force,
- map_crash_data_t& pCrashData)
+ crash_data_t **crash_data)
{
- VERB2 log("CreateCrashReport('%s',%ld,result)", dump_dir_name, caller_uid);
+ VERB2 log("CreateCrashReport('%s',%ld)", dump_dir_name, caller_uid);
+
+ *crash_data = NULL;
struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
@@ -165,7 +166,8 @@ static mw_result_t CreateCrashReport(const char *dump_dir_name,
/* Do a load_crash_data_from_crash_dump_dir from (possibly updated)
* crash dump dir
*/
- if (!DebugDumpToCrashReport(dump_dir_name, pCrashData))
+ *crash_data = DebugDumpToCrashReport(dump_dir_name);
+ if (!*crash_data)
{
error_msg("Error loading crash data");
r = MW_ERROR;
@@ -224,23 +226,22 @@ static char *do_log_and_save_line(char *log_line, void *param)
// Do not trust client_report here!
// dbus handler passes it from user without checking
-report_status_t Report(const map_crash_data_t& client_report,
+report_status_t Report(crash_data_t *client_report,
const vector_string_t& events,
const map_map_string_t& settings,
long caller_uid)
{
// Get ID fields
- const char *UID = get_crash_data_item_content_or_NULL(client_report, FILENAME_UID);
- const char *dump_dir_name = get_crash_data_item_content_or_NULL(client_report, CD_DUMPDIR);
+ const char *UID = get_crash_item_content_or_NULL(client_report, FILENAME_UID);
+ const char *dump_dir_name = get_crash_item_content_or_NULL(client_report, CD_DUMPDIR);
if (!UID || !dump_dir_name)
{
throw CABRTException(EXCEP_ERROR, "Report(): UID or DUMPDIR is missing in client's report data");
}
// Retrieve corresponding stored record
- map_crash_data_t stored_report;
- mw_result_t r = FillCrashInfo(dump_dir_name, stored_report);
- if (r != MW_OK)
+ crash_data_t *stored_report = FillCrashInfo(dump_dir_name);
+ if (!stored_report)
{
return report_status_t();
}
@@ -249,18 +250,21 @@ report_status_t Report(const map_crash_data_t& client_report,
if (caller_uid != 0 // not called by root
&& strcmp(to_string(caller_uid).c_str(), UID) != 0
) {
- const char *inform_all = get_crash_data_item_content_or_NULL(stored_report, FILENAME_INFORMALL);
+ const char *inform_all = get_crash_item_content_or_NULL(stored_report, FILENAME_INFORMALL);
if (!inform_all || !string_to_bool(inform_all))
+ {
+ free_crash_data(stored_report);
throw CABRTException(EXCEP_ERROR, "Report(): user with uid %ld can't report crash %s",
caller_uid, dump_dir_name);
+ }
}
// Save comment, "how to reproduce", backtrace
//TODO: we should iterate through stored_report and modify all
//modifiable fields which have new data in client_report
- const char *comment = get_crash_data_item_content_or_NULL(client_report, FILENAME_COMMENT);
- const char *reproduce = get_crash_data_item_content_or_NULL(client_report, FILENAME_REPRODUCE);
- const char *backtrace = get_crash_data_item_content_or_NULL(client_report, FILENAME_BACKTRACE);
+ const char *comment = get_crash_item_content_or_NULL(client_report, FILENAME_COMMENT);
+ const char *reproduce = get_crash_item_content_or_NULL(client_report, FILENAME_REPRODUCE);
+ const char *backtrace = get_crash_item_content_or_NULL(client_report, FILENAME_BACKTRACE);
if (comment || reproduce || backtrace)
{
struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
@@ -269,45 +273,47 @@ report_status_t Report(const map_crash_data_t& client_report,
if (comment)
{
dd_save_text(dd, FILENAME_COMMENT, comment);
- add_to_crash_data_ext(stored_report, FILENAME_COMMENT, CD_TXT, CD_ISEDITABLE, comment);
+ add_to_crash_data_ext(stored_report, FILENAME_COMMENT, comment, CD_FLAG_TXT + CD_FLAG_ISEDITABLE);
}
if (reproduce)
{
dd_save_text(dd, FILENAME_REPRODUCE, reproduce);
- add_to_crash_data_ext(stored_report, FILENAME_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce);
+ add_to_crash_data_ext(stored_report, FILENAME_REPRODUCE, reproduce, CD_FLAG_TXT + CD_FLAG_ISEDITABLE);
}
if (backtrace)
{
dd_save_text(dd, FILENAME_BACKTRACE, backtrace);
- add_to_crash_data_ext(stored_report, FILENAME_BACKTRACE, CD_TXT, CD_ISEDITABLE, backtrace);
+ add_to_crash_data_ext(stored_report, FILENAME_BACKTRACE, backtrace, CD_FLAG_TXT + CD_FLAG_ISEDITABLE);
}
dd_close(dd);
}
}
/* Remove BIN filenames from stored_report if they are not present in client's data */
- map_crash_data_t::const_iterator its = stored_report.begin();
- while (its != stored_report.end())
+ GHashTableIter iter;
+ char *name;
+ struct crash_item *value;
+ g_hash_table_iter_init(&iter, stored_report);
+ while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value))
{
- if (its->second[CD_TYPE] == CD_BIN)
+ if (value->flags & CD_FLAG_BIN)
{
- std::string key = its->first;
- if (get_crash_data_item_content_or_NULL(client_report, key.c_str()) == NULL)
+ if (get_crash_item_content_or_NULL(client_report, name) == NULL)
{
/* client does not have it -> does not want it passed to events */
- VERB3 log("Won't report BIN file %s:'%s'", key.c_str(), its->second[CD_CONTENT].c_str());
- its++; /* move off the element we will erase */
- stored_report.erase(key);
+ VERB3 log("Won't report BIN file %s:'%s'", name, value->content);
+ g_hash_table_iter_remove(&iter);
continue;
}
}
- its++;
}
VERB3 {
log_map_crash_data(client_report, " client_report");
log_map_crash_data(stored_report, " stored_report");
}
+ free_crash_data(stored_report);
+#define stored_report stored_report_must_not_be_used_below
#define client_report client_report_must_not_be_used_below
// Export overridden settings as environment variables
@@ -409,6 +415,7 @@ report_status_t Report(const map_crash_data_t& client_report,
}
return ret;
+#undef stored_report
#undef client_report
}
@@ -489,8 +496,7 @@ static char *do_log(char *log_line, void *param)
return log_line;
}
-mw_result_t LoadDebugDump(const char *dump_dir_name,
- map_crash_data_t& pCrashData)
+mw_result_t LoadDebugDump(const char *dump_dir_name, crash_data_t **crash_data)
{
mw_result_t res;
@@ -546,7 +552,7 @@ mw_result_t LoadDebugDump(const char *dump_dir_name,
dump_dir_name = state.crash_dump_dup_name;
}
- /* Loads pCrashData (from the *first debugdump dir* if this one is a dup)
+ /* Loads crash_data (from the *first debugdump dir* if this one is a dup)
* Returns:
* MW_OCCURRED: "crash count is != 1" (iow: it is > 1 - dup)
* MW_OK: "crash count is 1" (iow: this is a new crash, not a dup)
@@ -567,9 +573,10 @@ mw_result_t LoadDebugDump(const char *dump_dir_name,
dd_save_text(dd, FILENAME_COUNT, new_count_str);
dd_close(dd);
- res = FillCrashInfo(dump_dir_name, pCrashData);
- if (res == MW_OK)
+ *crash_data = FillCrashInfo(dump_dir_name);
+ if (*crash_data != NULL)
{
+ res = MW_OK;
if (count > 1)
{
log("Crash dump is a duplicate of %s", dump_dir_name);
@@ -587,28 +594,27 @@ mw_result_t LoadDebugDump(const char *dump_dir_name,
return res;
}
-static mw_result_t FillCrashInfo(const char *dump_dir_name,
- map_crash_data_t& pCrashData)
+static crash_data_t *FillCrashInfo(const char *dump_dir_name)
{
struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
- return MW_ERROR;
+ return NULL;
- load_crash_data_from_crash_dump_dir(dd, pCrashData);
+ crash_data_t *crash_data = load_crash_data_from_crash_dump_dir(dd);
char *events = list_possible_events(dd, NULL, "");
dd_close(dd);
- add_to_crash_data_ext(pCrashData, CD_EVENTS, CD_SYS, CD_ISNOTEDITABLE, events);
+ add_to_crash_data_ext(crash_data, CD_EVENTS, events, CD_FLAG_SYS + CD_FLAG_ISNOTEDITABLE);
free(events);
- add_to_crash_data_ext(pCrashData, CD_DUMPDIR, CD_SYS, CD_ISNOTEDITABLE, dump_dir_name);
+ add_to_crash_data_ext(crash_data, CD_DUMPDIR, dump_dir_name, CD_FLAG_SYS + CD_FLAG_ISNOTEDITABLE);
- return MW_OK;
+ return crash_data;
}
-vector_map_crash_data_t GetCrashInfos(long caller_uid)
+vector_of_crash_data_t *GetCrashInfos(long caller_uid)
{
- vector_map_crash_data_t retval;
+ vector_of_crash_data_t *retval = new_vector_of_crash_data();
log("Getting crash infos...");
DIR *dir = opendir(DEBUG_DUMPS_DIR);
@@ -658,19 +664,15 @@ vector_map_crash_data_t GetCrashInfos(long caller_uid)
}
{
- map_crash_data_t info;
- mw_result_t res = FillCrashInfo(dump_dir_name, info);
- switch (res)
+ crash_data_t *crash_data = FillCrashInfo(dump_dir_name);
+ if (!crash_data)
+ {
+ error_msg("Dump directory %s doesn't exist or misses crucial files, deleting", dump_dir_name);
+ delete_crash_dump_dir(dump_dir_name);
+ }
+ else
{
- case MW_OK:
- retval.push_back(info);
- break;
- case MW_ERROR:
- error_msg("Dump directory %s doesn't exist or misses crucial files, deleting", dump_dir_name);
- delete_crash_dump_dir(dump_dir_name);
- break;
- default:
- break;
+ g_ptr_array_add(retval, crash_data);
}
}
next:
@@ -695,14 +697,14 @@ vector_map_crash_data_t GetCrashInfos(long caller_uid)
* StartJob dbus call already did all the processing, and we just retrieve
* the result from dump directory, which is fast.
*/
-void CreateReport(const char* crash_id, long caller_uid, int force, map_crash_data_t& crashReport)
+void CreateReport(const char* crash_id, long caller_uid, int force, crash_data_t **crash_data)
{
/* FIXME: starting from here, any shared data must be protected with a mutex. */
- mw_result_t res = CreateCrashReport(crash_id, caller_uid, force, crashReport);
+ mw_result_t res = CreateCrashReport(crash_id, caller_uid, force, crash_data);
switch (res)
{
case MW_OK:
- VERB2 log_map_crash_data(crashReport, "crashReport");
+ VERB2 log_map_crash_data(*crash_data, "crashReport");
break;
case MW_NOENT_ERROR:
error_msg("Can't find crash with id '%s'", crash_id);
@@ -737,8 +739,8 @@ static void* create_report(void* arg)
try
{
log("Creating report...");
- map_crash_data_t crashReport;
- CreateReport(thread_data->crash_id, thread_data->caller_uid, thread_data->force, crashReport);
+ crash_data_t *crash_data = NULL;
+ CreateReport(thread_data->crash_id, thread_data->caller_uid, thread_data->force, &crash_data);
g_pCommLayer->JobDone(thread_data->peer);
}
catch (CABRTException& e)