/* (Re)loads data from /etc/abrt/events/foo.{xml,conf} and ~/.abrt/events/foo.conf */ void load_event_config_data(void) { free_event_config_data(); if (!g_event_config_list) g_event_config_list = g_hash_table_new_full( /*hash_func*/ g_str_hash, /*key_equal_func:*/ g_str_equal, /*key_destroy_func:*/ free, /*value_destroy_func:*/ (GDestroyNotify) free_event_config ); if (!g_event_config_symlinks) g_event_config_symlinks = g_hash_table_new_full( /*hash_func*/ g_str_hash, /*key_equal_func:*/ g_str_equal, /*key_destroy_func:*/ free, /*value_destroy_func:*/ free ); DIR *dir; struct dirent *dent; /* Load .xml files */ dir = opendir(EVENTS_DIR); if (!dir) return; while ((dent = readdir(dir)) != NULL) { char *ext = strrchr(dent->d_name, '.'); if (!ext) continue; if (strcmp(ext + 1, "xml") != 0) continue; char *fullname = concat_path_file(EVENTS_DIR, dent->d_name); *ext = '\0'; struct stat buf; if (0 != lstat(fullname, &buf)) continue; if (S_ISLNK(buf.st_mode)) { GError *error = NULL; gchar *link = g_file_read_link(fullname, &error); if (error != NULL) error_msg_and_die("Error reading symlink '%s': %s", fullname, error->message); gchar *target = g_path_get_basename(link); char *ext = strrchr(target, '.'); if (!ext || 0 != strcmp(ext + 1, "xml")) error_msg_and_die("Invalid event symlink '%s': expected it to" " point to another xml file", fullname); *ext = '\0'; g_hash_table_replace(g_event_config_symlinks, xstrdup(dent->d_name), target); g_free(link); /* don't free target, it is owned by the hash table now */ continue; } event_config_t *event_config = get_event_config(dent->d_name); bool new_config = (!event_config); if (new_config) event_config = new_event_config(); load_event_description_from_file(event_config, fullname); free(fullname); if (new_config) g_hash_table_replace(g_event_config_list, xstrdup(dent->d_name), event_config); } closedir(dir); load_config_files(EVENTS_DIR); char *HOME = getenv("HOME"); if (!HOME || !HOME[0]) return; HOME = concat_path_file(HOME, ".abrt/events"); load_config_files(HOME); free(HOME); }
// Called for character data // text is not nul-terminated static void text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error) { struct my_parse_data *parse_data = user_data; workflow_t *workflow = parse_data->workflow; const gchar *inner_element = g_markup_parse_context_get_element(context); if(parse_data->in_event_list && strcmp(inner_element, EVENT_ELEMENT) == 0) { event_config_t *ec = new_event_config(text); char *subevent_filename = xasprintf(EVENTS_DIR"/%s.xml", text); load_event_description_from_file(ec, subevent_filename); if (ec_get_screen_name(ec)) wf_add_event(workflow, ec); else free_event_config(ec); free(subevent_filename); } if(strcmp(inner_element, NAME_ELEMENT) == 0) { log_debug("workflow name:'%s'", text); if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ { /* set the value only if we found a value for the current locale * OR the description is still not set and we found the default value */ if (parse_data->attribute_lang[0] != '\0' || !wf_get_screen_name(workflow) /* && parse_data->attribute_lang is "" - always true */ ) { if (!parse_data->exact_name) { parse_data->exact_name = (strcmp(parse_data->cur_locale, parse_data->attribute_lang) == 0); wf_set_screen_name(workflow, text); } } } } else if(strcmp(inner_element, DESCRIPTION_ELEMENT) == 0) { log_debug("workflow description:'%s'", text); if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ { /* set the value only if we found a value for the current locale * OR the description is still not set and we found the default value */ if (parse_data->attribute_lang[0] != '\0' || !wf_get_description(workflow) /* && parse_data->attribute_lang is "" - always true */ ) { if (!parse_data->exact_description) { parse_data->exact_description = (strcmp(parse_data->cur_locale, parse_data->attribute_lang) == 0); wf_set_description(workflow, text); } } } } else if(strcmp(inner_element, PRIORITY_ELEMENT) == 0) { log_debug("workflow priority:'%s'", text); char *end = NULL; long long val = strtoll(text, &end, 10); if (text == end || end[0] != '\0' || (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN)) || (val > INT_MAX || val < INT_MIN) || (errno != 0 && val == 0)) { error_msg("Workflow's priority is not a number in range <%d,%d>", INT_MIN, INT_MAX); return; } wf_set_priority(workflow, (int)val); } }