No issues found
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 |
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 }