[evolution] Bug #655252 - Need to escape the comp_uid part of a path



commit 8a309aef81ed8364b054e49cfb94908623e2d0d4
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 26 11:02:47 2011 +0200

    Bug #655252 - Need to escape the comp_uid part of a path

 calendar/gui/dialogs/comp-editor.c  |   21 ++++--
 plugins/mail-to-task/mail-to-task.c |   21 ++++--
 widgets/misc/e-attachment-store.c   |  145 +++++++++++++++++++++--------------
 widgets/misc/e-attachment-store.h   |    1 +
 4 files changed, 116 insertions(+), 72 deletions(-)
---
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 5b3b520..172e79a 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -43,6 +43,7 @@
 #include <e-util/gconf-bridge.h>
 #include <shell/e-shell.h>
 
+#include <libedataserver/e-data-server-util.h>
 #include <libecal/e-cal-client.h>
 #include <libecal/e-cal-client-view.h>
 
@@ -300,7 +301,7 @@ get_attachment_list (CompEditor *editor)
 	GSList *list = NULL;
 	const gchar *comp_uid = NULL;
 	const gchar *local_store;
-	gchar *path;
+	gchar *filename_prefix, *tmp;
 	gint ii;
 
 	struct {
@@ -309,6 +310,9 @@ get_attachment_list (CompEditor *editor)
 		GtkWindow *parent;
 	} status;
 
+	e_cal_component_get_uid (editor->priv->comp, &comp_uid);
+	g_return_val_if_fail (comp_uid != NULL, NULL);
+
 	status.uris = NULL;
 	status.done = FALSE;
 	status.parent = g_object_ref (editor);
@@ -316,17 +320,20 @@ get_attachment_list (CompEditor *editor)
 	view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
 	store = e_attachment_view_get_store (view);
 
+	tmp = g_strdup (comp_uid);
+	e_filename_make_safe (tmp);
+	filename_prefix = g_strconcat (tmp, "-", NULL);
+	g_free (tmp);
+
 	local_store = e_cal_client_get_local_attachment_store (editor->priv->cal_client);
-	e_cal_component_get_uid (editor->priv->comp, &comp_uid);
-	path = g_build_path ("/", local_store, comp_uid, NULL);
-	destination = g_file_new_for_path (path);
-	g_free (path);
+	destination = g_file_new_for_path (local_store);
 
 	e_attachment_store_save_async (
-		store, destination, (GAsyncReadyCallback)
-		attachment_save_finished, &status);
+		store, destination, filename_prefix,
+		(GAsyncReadyCallback) attachment_save_finished, &status);
 
 	g_object_unref (destination);
+	g_free (filename_prefix);
 
 	/* We can't return until we have results, so crank
 	 * the main loop until the callback gets triggered. */
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index eb9e762..1d9f1fa 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -37,6 +37,7 @@
 #include <libecal/e-cal-client.h>
 #include <libecal/e-cal-component.h>
 #include <libedataserver/e-account.h>
+#include <libedataserver/e-data-server-util.h>
 #include <libedataserver/e-flag.h>
 #include <libedataserverui/e-source-selector-dialog.h>
 #include <libedataserverui/e-client-utils.h>
@@ -400,8 +401,8 @@ set_attachments (ECalClient *client,
 	GSList *uri_list = NULL;
 	const gchar *comp_uid = NULL;
 	const gchar *local_store;
+	gchar *filename_prefix, *tmp;
 	gint ii, n_parts;
-	gchar *path;
 	struct _att_async_cb_data cb_data;
 
 	cb_data.flag = e_flag_new ();
@@ -416,11 +417,15 @@ set_attachments (ECalClient *client,
 		return;
 
 	e_cal_component_get_uid (comp, &comp_uid);
-	local_store = e_cal_client_get_local_attachment_store (client);
-	path = g_build_path ("/", local_store, comp_uid, NULL);
+	g_return_if_fail (comp_uid != NULL);
 
-	destination = g_file_new_for_path (path);
-	g_free (path);
+	tmp = g_strdup (comp_uid);
+	e_filename_make_safe (tmp);
+	filename_prefix = g_strconcat (tmp, "-", NULL);
+	g_free (tmp);
+
+	local_store = e_cal_client_get_local_attachment_store (client);
+	destination = g_file_new_for_path (local_store);
 
 	/* Create EAttachments from the MIME parts and add them to the
 	 * attachment store. */
@@ -457,8 +462,10 @@ set_attachments (ECalClient *client,
 	e_flag_clear (cb_data.flag);
 
 	e_attachment_store_save_async (
-		store, destination, (GAsyncReadyCallback)
-		attachment_save_finished, &cb_data);
+		store, destination, filename_prefix,
+		(GAsyncReadyCallback) attachment_save_finished, &cb_data);
+
+	g_free (filename_prefix);
 
 	/* We can't return until we have results. */
 	e_flag_wait (cb_data.flag);
diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c
index a1e1fa2..8db9f2a 100644
--- a/widgets/misc/e-attachment-store.c
+++ b/widgets/misc/e-attachment-store.c
@@ -1068,6 +1068,7 @@ typedef struct _SaveContext SaveContext;
 struct _SaveContext {
 	GSimpleAsyncResult *simple;
 	GFile *destination;
+	gchar *filename_prefix;
 	GFile *fresh_directory;
 	GFile *trash_directory;
 	GList *attachment_list;
@@ -1079,6 +1080,7 @@ struct _SaveContext {
 static SaveContext *
 attachment_store_save_context_new (EAttachmentStore *store,
                                    GFile *destination,
+				   const gchar *filename_prefix,
                                    GAsyncReadyCallback callback,
                                    gpointer user_data)
 {
@@ -1101,6 +1103,7 @@ attachment_store_save_context_new (EAttachmentStore *store,
 	save_context = g_slice_new0 (SaveContext);
 	save_context->simple = simple;
 	save_context->destination = g_object_ref (destination);
+	save_context->filename_prefix = g_strdup (filename_prefix);
 	save_context->attachment_list = attachment_list;
 	save_context->uris = uris;
 
@@ -1123,6 +1126,9 @@ attachment_store_save_context_free (SaveContext *save_context)
 		save_context->destination = NULL;
 	}
 
+	g_free (save_context->filename_prefix);
+	save_context->filename_prefix = NULL;
+	
 	if (save_context->fresh_directory) {
 		g_object_unref (save_context->fresh_directory);
 		save_context->fresh_directory = NULL;
@@ -1139,6 +1145,56 @@ attachment_store_save_context_free (SaveContext *save_context)
 }
 
 static void
+attachment_store_move_file (SaveContext *save_context, GFile *source, GFile *destination, GError **error)
+{
+	gchar *tmpl;
+	gchar *path;
+
+	g_return_if_fail (save_context != NULL);
+	g_return_if_fail (source != NULL);
+	g_return_if_fail (destination != NULL);
+	g_return_if_fail (error != NULL);
+
+	/* Attachments are all saved to a temporary directory.
+	 * Now we need to move the existing destination directory
+	 * out of the way (if it exists).  Instead of testing for
+	 * existence we'll just attempt the move and ignore any
+	 * G_IO_ERROR_NOT_FOUND errors. */
+
+	/* First, however, we need another temporary directory to
+	 * move the existing destination directory to.  Note we're
+	 * not actually creating the directory yet, just picking a
+	 * name for it.  The usual raciness with this approach
+	 * applies here (read up on mktemp(3)), but worst case is
+	 * we get a spurious G_IO_ERROR_WOULD_MERGE error and the
+	 * user has to try saving attachments again. */
+	tmpl = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ());
+	path = e_mktemp (tmpl);
+	g_free (tmpl);
+
+	save_context->trash_directory = g_file_new_for_path (path);
+	g_free (path);
+
+	/* XXX No asynchronous move operation in GIO? */
+	g_file_move (
+		destination,
+		save_context->trash_directory,
+		G_FILE_COPY_NONE, NULL, NULL, NULL, error);
+
+	if (*error != NULL && !g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+		return;
+
+	g_clear_error (error);
+
+	/* Now we can move the file from the temporary directory
+	 * to the user-specified destination. */
+	g_file_move (
+		source,
+		destination,
+		G_FILE_COPY_NONE, NULL, NULL, NULL, error);
+}
+
+static void
 attachment_store_save_cb (EAttachment *attachment,
                           GAsyncResult *result,
                           SaveContext *save_context)
@@ -1146,8 +1202,6 @@ attachment_store_save_cb (EAttachment *attachment,
 	GSimpleAsyncResult *simple;
 	GFile *file;
 	gchar **uris;
-	gchar *template;
-	gchar *path;
 	GError *error = NULL;
 
 	file = e_attachment_save_finish (attachment, result, &error);
@@ -1161,18 +1215,35 @@ attachment_store_save_cb (EAttachment *attachment,
 		/* Assemble the file's final URI from its basename. */
 		gchar *basename;
 		gchar *uri;
+		GFile *source = NULL, *destination = NULL;
 
 		basename = g_file_get_basename (file);
 		g_object_unref (file);
 
+		source = g_file_get_child (save_context->fresh_directory, basename);
+
+		if (save_context->filename_prefix && *save_context->filename_prefix) {
+			gchar *tmp = basename;
+
+			basename = g_strconcat (save_context->filename_prefix, basename, NULL);
+			g_free (tmp);
+		}
+
 		file = save_context->destination;
-		file = g_file_get_child (file, basename);
-		uri = g_file_get_uri (file);
-		g_object_unref (file);
+		destination = g_file_get_child (file, basename);
+		uri = g_file_get_uri (destination);
 
-		save_context->uris[save_context->index++] = uri;
+		/* move them file-by-file */
+		attachment_store_move_file (save_context, source, destination, &error);
 
-	} else if (error != NULL) {
+		if (!error)
+			save_context->uris[save_context->index++] = uri;
+
+		g_object_unref (source);
+		g_object_unref (destination);
+	}
+
+	if (error != NULL) {
 		/* If this is the first error, cancel the other jobs. */
 		if (save_context->error == NULL) {
 			g_propagate_error (&save_context->error, error);
@@ -1189,8 +1260,7 @@ attachment_store_save_cb (EAttachment *attachment,
 			g_warning ("%s", error->message);
 	}
 
-	if (error != NULL)
-		g_error_free (error);
+	g_clear_error (&error);
 
 	/* If there's still jobs running, let them finish. */
 	if (save_context->attachment_list != NULL)
@@ -1212,53 +1282,6 @@ attachment_store_save_cb (EAttachment *attachment,
 		return;
 	}
 
-	/* Attachments are all saved to a temporary directory.
-	 * Now we need to move the existing destination directory
-	 * out of the way (if it exists).  Instead of testing for
-	 * existence we'll just attempt the move and ignore any
-	 * G_IO_ERROR_NOT_FOUND errors. */
-
-	/* First, however, we need another temporary directory to
-	 * move the existing destination directory to.  Note we're
-	 * not actually creating the directory yet, just picking a
-	 * name for it.  The usual raciness with this approach
-	 * applies here (read up on mktemp(3)), but worst case is
-	 * we get a spurious G_IO_ERROR_WOULD_MERGE error and the
-	 * user has to try saving attachments again. */
-	template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ());
-	path = e_mktemp (template);
-	g_free (template);
-
-	save_context->trash_directory = g_file_new_for_path (path);
-	g_free (path);
-
-	/* XXX No asynchronous move operation in GIO? */
-	g_file_move (
-		save_context->destination,
-		save_context->trash_directory,
-		G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
-
-	if (error != NULL && !g_error_matches (
-		error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
-
-		simple = save_context->simple;
-		g_simple_async_result_set_from_error (simple, error);
-		g_simple_async_result_complete (simple);
-
-		attachment_store_save_context_free (save_context);
-		g_error_free (error);
-		return;
-	}
-
-	g_clear_error (&error);
-
-	/* Now we can move the first temporary directory containing
-	 * the newly saved files to the user-specified destination. */
-	g_file_move (
-		save_context->fresh_directory,
-		save_context->destination,
-		G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
-
 	if (error != NULL) {
 		simple = save_context->simple;
 		g_simple_async_result_set_from_error (simple, error);
@@ -1269,6 +1292,9 @@ attachment_store_save_cb (EAttachment *attachment,
 		return;
 	}
 
+	/* clean-up left directory */
+	g_file_delete (save_context->fresh_directory, NULL, NULL);
+
 	/* And the URI list. */
 	uris = save_context->uris;
 	save_context->uris = NULL;
@@ -1279,10 +1305,13 @@ attachment_store_save_cb (EAttachment *attachment,
 
 	attachment_store_save_context_free (save_context);
 }
-
+/*
+ * @filename_prefix: prefix to use for a file name; can be %NULL for none
+ **/
 void
 e_attachment_store_save_async (EAttachmentStore *store,
                                GFile *destination,
+			       const gchar *filename_prefix,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
@@ -1296,7 +1325,7 @@ e_attachment_store_save_async (EAttachmentStore *store,
 	g_return_if_fail (G_IS_FILE (destination));
 
 	save_context = attachment_store_save_context_new (
-		store, destination, callback, user_data);
+		store, destination, filename_prefix, callback, user_data);
 
 	attachment_list = save_context->attachment_list;
 
diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h
index a7839ac..cdf33f5 100644
--- a/widgets/misc/e-attachment-store.h
+++ b/widgets/misc/e-attachment-store.h
@@ -128,6 +128,7 @@ gboolean	e_attachment_store_load_finish	(EAttachmentStore *store,
 						 GError **error);
 void		e_attachment_store_save_async	(EAttachmentStore *store,
 						 GFile *destination,
+						 const gchar *filename_prefix,
 						 GAsyncReadyCallback callback,
 						 gpointer user_data);
 gchar **	e_attachment_store_save_finish	(EAttachmentStore *store,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]