summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-02-25 14:52:47 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2011-02-25 14:52:47 +0100
commitb7ccdab50f4e6e68f1210092cf12dfdac7297749 (patch)
tree652887af95c81f2718adf8ae089fe54a269e033c /src
parent0ac50cd322082336c6ce5150630240dc757a8665 (diff)
downloadabrt-b7ccdab50f4e6e68f1210092cf12dfdac7297749.tar.gz
abrt-b7ccdab50f4e6e68f1210092cf12dfdac7297749.tar.xz
abrt-b7ccdab50f4e6e68f1210092cf12dfdac7297749.zip
gui-wizard-gtk: implement stealing
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui-wizard-gtk/main.c2
-rw-r--r--src/gui-wizard-gtk/wizard.c87
-rw-r--r--src/lib/steal_directory.c3
3 files changed, 76 insertions, 16 deletions
diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c
index 1d35da82..b109eaa5 100644
--- a/src/gui-wizard-gtk/main.c
+++ b/src/gui-wizard-gtk/main.c
@@ -21,7 +21,7 @@ void reload_crash_data_from_dump_dir(void)
free(g_reanalyze_events);
free(g_report_events);
- struct dump_dir *dd = dd_opendir(g_dump_dir_name, 0);
+ struct dump_dir *dd = dd_opendir(g_dump_dir_name, DD_OPEN_READONLY);
if (!dd)
xfunc_die(); /* dd_opendir already logged error msg */
g_cd = create_crash_data_from_dump_dir(dd);
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,
diff --git a/src/lib/steal_directory.c b/src/lib/steal_directory.c
index 25b84272..409bb9d9 100644
--- a/src/lib/steal_directory.c
+++ b/src/lib/steal_directory.c
@@ -27,12 +27,13 @@ struct dump_dir *steal_directory(const char *base_dir, const char *dump_dir_name
dst_dir_name = xasprintf("%s/%s.%u", base_dir, base_name, (int)tv.tv_usec);
}
- log("Creating copy in '%s'", dd_dst->dd_dir);
+ VERB1 log("Creating copy in '%s'", dd_dst->dd_dir);
if (copy_file_recursive(dump_dir_name, dd_dst->dd_dir) < 0)
{
/* error. copy_file_recursive already emitted error message */
/* Don't leave half-copied dir lying around */
dd_delete(dd_dst);
+//FIXME: return NULL instead? GUI doesn't want to die in this situation!
xfunc_die();
}