int show_event_config_dialog(const char *event_name, GtkWindow *parent) { event_config_t *event = get_event_config(event_name); GtkWindow *parent_window = parent ? parent : g_event_list_window; GtkWidget *dialog = gtk_dialog_new_with_buttons( /*title:*/ec_get_screen_name(event) ? ec_get_screen_name(event) : event_name, parent_window, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_APPLY, NULL); /* Allow resize? * W/o resize, e.g. upload configuration hint looks awfully * line wrapped. * With resize, there are some somewhat not nice effects: * for one, opening an expander will enlarge window, * but won't contract it back when expander is closed. */ gtk_window_set_resizable(GTK_WINDOW(dialog), true); gtk_window_set_default_size(GTK_WINDOW(dialog), 450, -1); if (parent_window != NULL) { gtk_window_set_icon_name(GTK_WINDOW(dialog), gtk_window_get_icon_name(parent_window)); } GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); content = cdialog_get_widget(create_event_config_dialog_content(event, content)); gtk_widget_show_all(content); int result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_APPLY) { dehydrate_config_dialog(g_option_list); const char *const store_passwords_s = get_user_setting("store_passwords"); save_event_config_data_to_user_storage(event_name, get_event_config(event_name), !(store_passwords_s && !strcmp(store_passwords_s, "no"))); } //else if (result == GTK_RESPONSE_CANCEL) // log("log"); gtk_widget_destroy(dialog); return result; }
config_dialog_t *create_event_config_dialog(const char *event_name, GtkWindow *parent) { event_config_t *event = get_event_config(event_name); if(!ec_is_configurable(event)) return NULL; GtkWindow *parent_window = parent ? parent : g_event_list_window; GtkWidget *dialog = gtk_dialog_new_with_buttons( /*title:*/ec_get_screen_name(event) ? ec_get_screen_name(event) : event_name, parent_window, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_APPLY, NULL); /* Allow resize? * W/o resize, e.g. upload configuration hint looks awfully * line wrapped. * With resize, there are some somewhat not nice effects: * for one, opening an expander will enlarge window, * but won't contract it back when expander is closed. */ gtk_window_set_resizable(GTK_WINDOW(dialog), true); gtk_window_set_default_size(GTK_WINDOW(dialog), 450, -1); if (parent_window != NULL) { gtk_window_set_icon_name(GTK_WINDOW(dialog), gtk_window_get_icon_name(parent_window)); } GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); config_dialog_t *cdialog = create_event_config_dialog_content(event, content); cdialog_set_widget(cdialog, dialog); return cdialog; }
GList *export_event_config(const char *event_name) { GList *env_list = NULL; event_config_t *config = get_event_config(event_name); if (config) { GList *lopt; for (lopt = config->options; lopt; lopt = lopt->next) { event_option_t *opt = lopt->data; if (!opt->eo_value) continue; char *var_val = xasprintf("%s=%s", opt->eo_name, opt->eo_value); VERB3 log("Exporting '%s'", var_val); env_list = g_list_prepend(env_list, var_val); putenv(var_val); } } return env_list; }
GHashTable *validate_event(const char *event_name) { event_config_t *config = get_event_config(event_name); if (!config) return NULL; GHashTable *errors = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); GList *li; for (li = config->options; li; li = li->next) { event_option_t *opt = (event_option_t *)li->data; char *err = validate_event_option(opt); if (err) g_hash_table_insert(errors, xstrdup(opt->eo_name), err); } if (g_hash_table_size(errors)) return errors; g_hash_table_destroy(errors); return NULL; }
static void load_config_files(const char *dir_path) { DIR *dir; struct dirent *dent; /* Load .conf files */ dir = opendir(dir_path); if (!dir) return; while ((dent = readdir(dir)) != NULL) { char *ext = strrchr(dent->d_name, '.'); if (!ext) continue; if (strcmp(ext + 1, "conf") != 0) continue; char *fullname = concat_path_file(dir_path, dent->d_name); *ext = '\0'; event_config_t *event_config = get_event_config(dent->d_name); bool new_config = (!event_config); if (new_config) event_config = new_event_config(); map_string_h *keys_and_values = new_map_string(); load_conf_file(fullname, keys_and_values, /*skipKeysWithoutValue:*/ false); free(fullname); /* Insert or replace every key/value from keys_and_values to event_config->option */ GHashTableIter iter; char *name; char *value; g_hash_table_iter_init(&iter, keys_and_values); while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) { event_option_t *opt; GList *elem = g_list_find_custom(event_config->options, name, cmp_event_option_name_with_string); if (elem) { opt = elem->data; // log("conf: replacing '%s' value:'%s'->'%s'", name, opt->value, value); free(opt->eo_value); } else { // log("conf: new value %s='%s'", name, value); opt = new_event_option(); opt->eo_name = xstrdup(name); } opt->eo_value = xstrdup(value); if (!elem) event_config->options = g_list_append(event_config->options, opt); } free_map_string(keys_and_values); if (new_config) g_hash_table_replace(g_event_config_list, xstrdup(dent->d_name), event_config); } closedir(dir); }
/* (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); }
static void save_data_from_event_dialog_name(GList *widgets, const char *name) { event_config_t *ec = get_event_config(name); save_data_from_event_config_dialog(widgets, ec); }