evolution-3.6.4/shell/e-convert-local-mail.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-convert-local-mail.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * e-convert-local-mail.c
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  */
 18 
 19 #include <config.h>
 20 
 21 #include <glib/gstdio.h>
 22 #include <camel/camel.h>
 23 
 24 #include <shell/e-shell.h>
 25 #include <libevolution-utils/e-alert-dialog.h>
 26 
 27 /* Forward Declarations */
 28 void e_convert_local_mail (EShell *shell);
 29 
 30 static gboolean
 31 mail_to_maildir_migration_needed (const gchar *mail_data_dir)
 32 {
 33 	gchar *local_store;
 34 	gchar *local_outbox;
 35 	gboolean migration_needed = FALSE;
 36 
 37 	local_store = g_build_filename (mail_data_dir, "local", NULL);
 38 	local_outbox = g_build_filename (local_store, ".Outbox", NULL);
 39 
 40 	/* If this is a fresh install (no local store exists yet)
 41 	 * then obviously there's nothing to migrate to Maildir. */
 42 	if (!g_file_test (local_store, G_FILE_TEST_IS_DIR))
 43 		migration_needed = FALSE;
 44 
 45 	/* Look for a Maildir Outbox folder. */
 46 	else if (!g_file_test (local_outbox, G_FILE_TEST_IS_DIR))
 47 		migration_needed = TRUE;
 48 
 49 	g_free (local_store);
 50 	g_free (local_outbox);
 51 
 52 	return migration_needed;
 53 }
 54 
 55 /* Folder names with '.' are converted to '_' */
 56 static gchar *
 57 sanitize_maildir_folder_name (gchar *folder_name)
 58 {
 59 	gchar *maildir_folder_name;
 60 
 61 	maildir_folder_name = g_strdup (folder_name);
 62 	g_strdelimit (maildir_folder_name, ".", '_');
 63 
 64 	 return maildir_folder_name;
 65 }
 66 
 67 static void
 68 copy_folder (CamelStore *mail_store,
 69              CamelStore *maildir_store,
 70              const gchar *mail_fname,
 71              const gchar *maildir_fname)
 72 {
 73 	CamelFolder *fromfolder, *tofolder;
 74 	GPtrArray *uids;
 75 
 76 	fromfolder = camel_store_get_folder_sync (
 77 		mail_store, mail_fname, 0, NULL, NULL);
 78 	if (fromfolder == NULL) {
 79 		g_warning ("Cannot find mail folder %s \n", mail_fname);
 80 		return;
 81 	}
 82 
 83 	tofolder = camel_store_get_folder_sync (
 84 		maildir_store, maildir_fname,
 85 		CAMEL_STORE_FOLDER_CREATE, NULL, NULL);
 86 	if (tofolder == NULL) {
 87 		g_warning ("Cannot create maildir folder %s \n", maildir_fname);
 88 		g_object_unref (fromfolder);
 89 		return;
 90 	}
 91 
 92 	uids = camel_folder_get_uids (fromfolder);
 93 	camel_folder_transfer_messages_to_sync (
 94 		fromfolder, uids, tofolder, FALSE, NULL, NULL, NULL);
 95 	camel_folder_free_uids (fromfolder, uids);
 96 
 97 	g_object_unref (fromfolder);
 98 	g_object_unref (tofolder);
 99 }
100 
101 static void
102 copy_folders (CamelStore *mail_store,
103               CamelStore *maildir_store,
104               CamelFolderInfo *fi,
105               CamelSession *session)
106 {
107 	if (fi) {
108 		if (!g_str_has_prefix (fi->full_name, ".#evolution")) {
109 			gchar *maildir_folder_name;
110 
111 			/* sanitize folder names and copy folders */
112 			maildir_folder_name = sanitize_maildir_folder_name (fi->full_name);
113 			copy_folder (
114 				mail_store, maildir_store,
115 				fi->full_name, maildir_folder_name);
116 			g_free (maildir_folder_name);
117 		}
118 
119 		if (fi->child)
120 			copy_folders (mail_store, maildir_store, fi->child, session);
121 
122 		copy_folders (mail_store, maildir_store, fi->next, session);
123 	}
124 }
125 
126 struct MigrateStore {
127 	CamelSession *session;
128 	CamelStore *mail_store;
129 	CamelStore *maildir_store;
130 	gboolean complete;
131 };
132 
133 static void
134 migrate_stores (struct MigrateStore *ms)
135 {
136 	CamelFolderInfo *mail_fi;
137 	CamelStore *mail_store = ms->mail_store;
138 	CamelStore *maildir_store = ms->maildir_store;
139 
140 	mail_fi = camel_store_get_folder_info_sync (
141 		mail_store, NULL,
142 		CAMEL_STORE_FOLDER_INFO_RECURSIVE |
143 		CAMEL_STORE_FOLDER_INFO_FAST |
144 		CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
145 		NULL, NULL);
146 
147 	/* FIXME progres dialog */
148 	copy_folders (mail_store, maildir_store, mail_fi, ms->session);
149 	ms->complete = TRUE;
150 }
151 
152 static void
153 rename_mbox_dir (ESource *mbox_source,
154                  const gchar *mail_data_dir)
155 {
156 	gchar *old_mail_dir;
157 	gchar *new_mail_dir;
158 	gboolean need_rename;
159 	const gchar *mbox_uid;
160 
161 	mbox_uid = e_source_get_uid (mbox_source);
162 
163 	old_mail_dir = g_build_filename (mail_data_dir, "local", NULL);
164 	new_mail_dir = g_build_filename (mail_data_dir, mbox_uid, NULL);
165 
166 	/* Rename if old directory exists and new directory does not. */
167 	need_rename =
168 		g_file_test (old_mail_dir, G_FILE_TEST_EXISTS) &&
169 		!g_file_test (new_mail_dir, G_FILE_TEST_EXISTS);
170 
171 	if (need_rename)
172 		g_rename (old_mail_dir, new_mail_dir);
173 
174 	g_free (old_mail_dir);
175 	g_free (new_mail_dir);
176 }
177 
178 static gboolean
179 migrate_mbox_to_maildir (EShell *shell,
180                          CamelSession *session,
181                          ESource *mbox_source)
182 {
183 	ESourceRegistry *registry;
184 	ESourceExtension *extension;
185 	const gchar *extension_name;
186 	CamelService *mbox_service = NULL;
187 	CamelService *maildir_service = NULL;
188 	CamelSettings *settings;
189 	const gchar *data_dir;
190 	const gchar *mbox_uid;
191 	gchar *path;
192 	struct MigrateStore ms;
193 	GError *error = NULL;
194 
195 	registry = e_shell_get_registry (shell);
196 
197 	data_dir = camel_session_get_user_data_dir (session);
198 
199 	mbox_uid = e_source_get_uid (mbox_source);
200 	e_source_set_display_name (mbox_source, "local_mbox");
201 
202 	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
203 	extension = e_source_get_extension (mbox_source, extension_name);
204 
205 	e_source_backend_set_backend_name (
206 		E_SOURCE_BACKEND (extension), "mbox");
207 
208 	extension_name = e_source_camel_get_extension_name ("mbox");
209 	extension = e_source_get_extension (mbox_source, extension_name);
210 	settings = e_source_camel_get_settings (E_SOURCE_CAMEL (extension));
211 
212 	path = g_build_filename (data_dir, mbox_uid, NULL);
213 	g_object_set (settings, "path", path, NULL);
214 	g_free (path);
215 
216 	e_source_registry_commit_source_sync (
217 		registry, mbox_source, NULL, &error);
218 
219 	if (error == NULL)
220 		mbox_service = camel_session_add_service (
221 			session, mbox_uid, "mbox",
222 			CAMEL_PROVIDER_STORE, &error);
223 
224 	if (error == NULL)
225 		maildir_service = camel_session_add_service (
226 			session, "local", "maildir",
227 			CAMEL_PROVIDER_STORE, &error);
228 
229 	if (error != NULL) {
230 		if (mbox_service != NULL)
231 			g_object_unref (mbox_service);
232 		if (maildir_service != NULL)
233 			g_object_unref (maildir_service);
234 		g_warning ("%s: %s", G_STRFUNC, error->message);
235 		g_error_free (error);
236 		return FALSE;
237 	}
238 
239 	g_return_val_if_fail (CAMEL_IS_STORE (mbox_service), FALSE);
240 	g_return_val_if_fail (CAMEL_IS_STORE (maildir_service), FALSE);
241 
242 	camel_service_set_settings (mbox_service, settings);
243 
244 	settings = camel_service_ref_settings (maildir_service);
245 
246 	path = g_build_filename (data_dir, "local", NULL);
247 	g_object_set (settings, "path", path, NULL);
248 	g_mkdir (path, 0700);
249 	g_free (path);
250 
251 	g_object_unref (settings);
252 
253 	ms.mail_store = CAMEL_STORE (mbox_service);
254 	ms.maildir_store = CAMEL_STORE (maildir_service);
255 	ms.session = session;
256 	ms.complete = FALSE;
257 
258 	g_thread_create ((GThreadFunc) migrate_stores, &ms, TRUE, NULL);
259 	while (!ms.complete)
260 		g_main_context_iteration (NULL, TRUE);
261 
262 	g_object_unref (mbox_service);
263 	g_object_unref (maildir_service);
264 
265 	return TRUE;
266 }
267 
268 void
269 e_convert_local_mail (EShell *shell)
270 {
271 	CamelSession *session;
272 	ESource *mbox_source;
273 	const gchar *user_data_dir;
274 	const gchar *user_cache_dir;
275 	gchar *mail_data_dir;
276 	gchar *mail_cache_dir;
277 	gchar *local_store;
278 	gint response;
279 
280 	user_data_dir = e_get_user_data_dir ();
281 	user_cache_dir = e_get_user_cache_dir ();
282 
283 	mail_data_dir = g_build_filename (user_data_dir, "mail", NULL);
284 	mail_cache_dir = g_build_filename (user_cache_dir, "mail", NULL);
285 
286 	if (!mail_to_maildir_migration_needed (mail_data_dir))
287 		goto exit;
288 
289 	response = e_alert_run_dialog_for_args (
290 		e_shell_get_active_window (NULL),
291 		"mail:ask-migrate-store", NULL);
292 
293 	if (response == GTK_RESPONSE_CANCEL)
294 		exit (EXIT_SUCCESS);
295 
296 	mbox_source = e_source_new (NULL, NULL, NULL);
297 
298 	rename_mbox_dir (mbox_source, mail_data_dir);
299 
300 	local_store = g_build_filename (mail_data_dir, "local", NULL);
301 
302 	if (!g_file_test (local_store, G_FILE_TEST_EXISTS))
303 		g_mkdir_with_parents (local_store, 0700);
304 
305 	g_free (local_store);
306 
307 	session = g_object_new (
308 		CAMEL_TYPE_SESSION,
309 		"online", FALSE,
310 		"user-data-dir", mail_data_dir,
311 		"user-cache-dir", mail_cache_dir,
312 		NULL);
313 
314 	migrate_mbox_to_maildir (shell, session, mbox_source);
315 
316 	g_object_unref (session);
317 
318 	g_object_unref (mbox_source);
319 
320 exit:
321 	g_free (mail_data_dir);
322 	g_free (mail_cache_dir);
323 }