summaryrefslogtreecommitdiffstats
path: root/src/gui-wizard-gtk/wizard.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui-wizard-gtk/wizard.c')
-rw-r--r--src/gui-wizard-gtk/wizard.c87
1 files changed, 73 insertions, 14 deletions
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 756f199e..3b5a4a1c 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -114,6 +114,55 @@ static void remove_child_widget(GtkWidget *widget, gpointer container)
gtk_widget_destroy(widget);
}
+static void save_dialog_response(GtkDialog *dialog, gint response_id, gpointer user_data)
+{
+ *(gint*)user_data = response_id;
+}
+
+struct dump_dir *steal_if_needed(struct dump_dir *dd)
+{
+//FIXME: show error dialog?
+ if (!dd)
+ xfunc_die();
+
+ if (dd->locked)
+ return dd;
+
+ dd_close(dd);
+
+ char *HOME = getenv("HOME");
+ if (HOME && HOME[0])
+ HOME = concat_path_file(HOME, ".abrt");
+ else
+ HOME = xstrdup("/tmp");
+
+ GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(g_assistant),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_OK_CANCEL,
+ _("Need writable directory, but '%s' is not writable."
+ " Create a copy in '%s' and operate on the copy?"),
+ g_dump_dir_name, HOME
+ );
+ gint response = GTK_RESPONSE_CANCEL;
+ g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(save_dialog_response), &response);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+
+ if (response != GTK_RESPONSE_OK)
+ return NULL;
+
+ dd = steal_directory(HOME, g_dump_dir_name);
+ if (!dd)
+//FIXME: show error dialog?
+ return NULL;
+
+ g_dump_dir_name = xstrdup(dd->dd_dir);
+ gtk_window_set_title(GTK_WINDOW(g_assistant), g_dump_dir_name);
+
+ return dd;
+}
+
static void load_text_to_text_view(GtkTextView *tv, const char *name)
{
const char *str = g_cd ? get_crash_item_content_or_NULL(g_cd, name) : NULL;
@@ -137,13 +186,14 @@ static void save_text_if_changed(const char *name, const char *new_value)
old_value = "";
if (strcmp(new_value, old_value) != 0)
{
- add_to_crash_data_ext(g_cd, name, new_value, CD_FLAG_TXT | CD_FLAG_ISEDITABLE);
-
- struct dump_dir *dd = dd_opendir(g_dump_dir_name, 0);
-//FIXME: (1) stealing? (2) better handling if directory was deleted?
- if (!dd)
- xfunc_die();
- dd_save_text(dd, name, new_value);
+ struct dump_dir *dd = dd_opendir(g_dump_dir_name, DD_OPEN_READONLY);
+ dd = steal_if_needed(dd);
+ if (dd && dd->locked)
+ {
+ dd_save_text(dd, name, new_value);
+ add_to_crash_data_ext(g_cd, name, new_value, CD_FLAG_TXT | CD_FLAG_ISEDITABLE);
+ }
+//FIXME: else: what to do with still-unsaved data in the widget??
dd_close(dd);
}
}
@@ -450,9 +500,9 @@ static void start_event_run(const char *event_name,
*/
struct run_event_state *state = new_run_event_state();
- if (prepare_commands(state, g_dump_dir_name, event_name) == 0
- || spawn_next_command(state, g_dump_dir_name, event_name) < 0
- ) {
+ if (prepare_commands(state, g_dump_dir_name, event_name) == 0)
+ {
+ no_cmds:
/* No commands needed?! (This is untypical) */
free_run_event_state(state);
//TODO: better msg?
@@ -462,11 +512,21 @@ static void start_event_run(const char *event_name,
return;
}
- /* At least one command is needed, and we started first one.
- * Hook its output fd up to the main loop.
- */
+ struct dump_dir *dd = dd_opendir(g_dump_dir_name, DD_OPEN_READONLY);
+ dd = steal_if_needed(dd);
+ int locked = (dd && dd->locked);
+ dd_close(dd);
+ if (!locked)
+ return; /* user refused to steal, or write error, etc... */
+
+ if (spawn_next_command(state, g_dump_dir_name, event_name) < 0)
+ goto no_cmds;
+
VERB1 log("running event '%s' on '%s'", event_name, g_dump_dir_name);
+ /* At least one command is needed, and we started first one.
+ * Hook its output fd to the main loop.
+ */
struct analyze_event_data *evd = xzalloc(sizeof(*evd));
evd->run_state = state;
evd->event_name = event_name;
@@ -478,7 +538,6 @@ static void start_event_run(const char *event_name,
evd->fd = state->command_out_fd;
ndelay_on(evd->fd);
evd->channel = g_io_channel_unix_new(evd->fd);
-
/*evd->event_source_id = */ g_io_add_watch(evd->channel,
G_IO_IN | G_IO_ERR | G_IO_HUP, /* need HUP to detect EOF w/o any data */
consume_cmd_output,