1 /*
2  * e-mail-send-account-override.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  *
17  * Copyright (C) 2013 Red Hat, Inc. (www.redhat.com)
18  *
19  */
20 
21 #include "evolution-config.h"
22 
23 #include <string.h>
24 
25 #include <libedataserver/libedataserver.h>
26 
27 #include "e-mail-send-account-override.h"
28 
29 #define E_MAIL_SEND_ACCOUNT_OVERRIDE_GET_PRIVATE(obj) \
30 	(G_TYPE_INSTANCE_GET_PRIVATE \
31 	((obj), E_TYPE_MAIL_SEND_ACCOUNT_OVERRIDE, EMailSendAccountOverridePrivate))
32 
33 #define FOLDERS_SECTION				"Folders"
34 #define FOLDERS_ALIAS_NAME_SECTION		"Folders-Alias-Name"
35 #define FOLDERS_ALIAS_ADDRESS_SECTION		"Folders-Alias-Address"
36 #define RECIPIENTS_SECTION			"Recipients"
37 #define RECIPIENTS_ALIAS_NAME_SECTION		"Recipients-Alias-Name"
38 #define RECIPIENTS_ALIAS_ADDRESS_SECTION	"Recipients-Alias-Address"
39 #define OPTIONS_SECTION				"Options"
40 
41 #define OPTION_PREFER_FOLDER			"PreferFolder"
42 
43 struct _EMailSendAccountOverridePrivate {
44 	GKeyFile *key_file;
45 	gchar *config_filename;
46 	gboolean prefer_folder;
47 
48 	gboolean need_save;
49 	guint save_frozen;
50 
51 	GMutex property_lock;
52 };
53 
54 enum {
55 	PROP_0,
56 	PROP_PREFER_FOLDER
57 };
58 
59 enum {
60 	CHANGED,
61 	LAST_SIGNAL
62 };
63 
64 static guint signals[LAST_SIGNAL];
65 
G_DEFINE_TYPE(EMailSendAccountOverride,e_mail_send_account_override,G_TYPE_OBJECT)66 G_DEFINE_TYPE (
67 	EMailSendAccountOverride,
68 	e_mail_send_account_override,
69 	G_TYPE_OBJECT)
70 
71 static gboolean
72 e_mail_send_account_override_save_locked (EMailSendAccountOverride *override)
73 {
74 	gchar *contents;
75 	GError *error = NULL;
76 
77 	g_return_val_if_fail (override->priv->key_file != NULL, FALSE);
78 
79 	override->priv->need_save = FALSE;
80 
81 	if (override->priv->config_filename == NULL)
82 		return FALSE;
83 
84 	contents = g_key_file_to_data (override->priv->key_file, NULL, NULL);
85 	if (contents == NULL)
86 		return FALSE;
87 
88 	g_file_set_contents (
89 		override->priv->config_filename, contents, -1, &error);
90 
91 	if (error != NULL) {
92 		g_warning ("%s: %s", G_STRFUNC, error->message);
93 		g_clear_error (&error);
94 	}
95 
96 	g_free (contents);
97 
98 	return TRUE;
99 }
100 
101 static gboolean
e_mail_send_account_override_maybe_save_locked(EMailSendAccountOverride * override)102 e_mail_send_account_override_maybe_save_locked (EMailSendAccountOverride *override)
103 {
104 	if (override->priv->save_frozen > 0) {
105 		override->priv->need_save = TRUE;
106 		return FALSE;
107 	}
108 
109 	return e_mail_send_account_override_save_locked (override);
110 }
111 
112 static void
read_alias_info_locked(EMailSendAccountOverride * override,const gchar * alias_name_section,const gchar * alias_address_section,const gchar * key,gchar ** out_alias_name,gchar ** out_alias_address)113 read_alias_info_locked (EMailSendAccountOverride *override,
114 			const gchar *alias_name_section,
115 			const gchar *alias_address_section,
116 			const gchar *key,
117 			gchar **out_alias_name,
118 			gchar **out_alias_address)
119 {
120 	if (out_alias_name) {
121 		gchar *alias_name;
122 
123 		alias_name = g_key_file_get_string (
124 			override->priv->key_file, alias_name_section, key, NULL);
125 
126 		if (alias_name)
127 			g_strchomp (alias_name);
128 
129 		if (alias_name && !*alias_name) {
130 			g_free (alias_name);
131 			alias_name = NULL;
132 		}
133 
134 		*out_alias_name = alias_name;
135 	}
136 
137 	if (out_alias_address) {
138 		gchar *alias_address;
139 
140 		alias_address = g_key_file_get_string (
141 			override->priv->key_file, alias_address_section, key, NULL);
142 
143 		if (alias_address)
144 			g_strchomp (alias_address);
145 
146 		if (alias_address && !*alias_address) {
147 			g_free (alias_address);
148 			alias_address = NULL;
149 		}
150 
151 		*out_alias_address = alias_address;
152 	}
153 }
154 
155 static void
write_alias_info_locked(EMailSendAccountOverride * override,const gchar * alias_name_section,const gchar * alias_address_section,const gchar * key,const gchar * alias_name,const gchar * alias_address)156 write_alias_info_locked (EMailSendAccountOverride *override,
157 			 const gchar *alias_name_section,
158 			 const gchar *alias_address_section,
159 			 const gchar *key,
160 			 const gchar *alias_name,
161 			 const gchar *alias_address)
162 {
163 	if (alias_name && *alias_name) {
164 		g_key_file_set_string (override->priv->key_file, alias_name_section, key, alias_name);
165 	} else {
166 		g_key_file_remove_key (override->priv->key_file, alias_name_section, key, NULL);
167 	}
168 
169 	if (alias_address && *alias_address) {
170 		g_key_file_set_string (override->priv->key_file, alias_address_section, key, alias_address);
171 	} else {
172 		g_key_file_remove_key (override->priv->key_file, alias_address_section, key, NULL);
173 	}
174 }
175 
176 static gchar *
get_override_for_folder_uri_locked(EMailSendAccountOverride * override,const gchar * folder_uri,gchar ** out_alias_name,gchar ** out_alias_address)177 get_override_for_folder_uri_locked (EMailSendAccountOverride *override,
178                                     const gchar *folder_uri,
179 				    gchar **out_alias_name,
180 				    gchar **out_alias_address)
181 {
182 	gchar *account_uid;
183 
184 	if (folder_uri == NULL || *folder_uri == '\0')
185 		return NULL;
186 
187 	account_uid = g_key_file_get_string (
188 		override->priv->key_file, FOLDERS_SECTION, folder_uri, NULL);
189 
190 	if (account_uid != NULL)
191 		g_strchomp (account_uid);
192 
193 	if (account_uid != NULL && *account_uid == '\0') {
194 		g_free (account_uid);
195 		account_uid = NULL;
196 	}
197 
198 	if (account_uid) {
199 		read_alias_info_locked (override,
200 			FOLDERS_ALIAS_NAME_SECTION,
201 			FOLDERS_ALIAS_ADDRESS_SECTION,
202 			folder_uri,
203 			out_alias_name,
204 			out_alias_address);
205 	}
206 
207 	return account_uid;
208 }
209 
210 static gchar *
test_one_recipient(gchar ** keys,GPtrArray * values,const gchar * name,const gchar * address,gint * out_keys_index)211 test_one_recipient (gchar **keys,
212                     GPtrArray *values,
213                     const gchar *name,
214                     const gchar *address,
215 		    gint *out_keys_index)
216 {
217 	gint ii;
218 
219 	g_return_val_if_fail (keys != NULL, NULL);
220 	g_return_val_if_fail (values != NULL, NULL);
221 	g_return_val_if_fail (out_keys_index != NULL, NULL);
222 
223 	if (name != NULL && *name == '\0')
224 		name = NULL;
225 
226 	if (address != NULL && *address == '\0')
227 		address = NULL;
228 
229 	if (name == NULL && address == NULL)
230 		return NULL;
231 
232 	for (ii = 0; keys[ii] && ii < values->len; ii++) {
233 		if (name != NULL && e_util_utf8_strstrcase (name, keys[ii]) != NULL) {
234 			*out_keys_index = ii;
235 
236 			return g_strdup (values->pdata[ii]);
237 		}
238 
239 		if (address != NULL && e_util_utf8_strstrcase (address, keys[ii]) != NULL) {
240 			*out_keys_index = ii;
241 
242 			return g_strdup (values->pdata[ii]);
243 		}
244 	}
245 
246 	return NULL;
247 }
248 
249 static gchar *
get_override_for_recipients_locked(EMailSendAccountOverride * override,CamelAddress * recipients,gchar ** out_alias_name,gchar ** out_alias_address)250 get_override_for_recipients_locked (EMailSendAccountOverride *override,
251                                     CamelAddress *recipients,
252 				    gchar **out_alias_name,
253 				    gchar **out_alias_address)
254 {
255 	CamelInternetAddress *iaddress;
256 	gchar *account_uid = NULL;
257 	GPtrArray *values;
258 	gchar **keys;
259 	gint ii, len;
260 
261 	if (!CAMEL_IS_INTERNET_ADDRESS (recipients))
262 		return NULL;
263 
264 	keys = g_key_file_get_keys (
265 		override->priv->key_file, RECIPIENTS_SECTION, NULL, NULL);
266 	if (keys == NULL)
267 		return NULL;
268 
269 	values = g_ptr_array_new_full (g_strv_length (keys), g_free);
270 	for (ii = 0; keys[ii]; ii++) {
271 		g_ptr_array_add (
272 			values,
273 			g_key_file_get_string (
274 				override->priv->key_file,
275 				RECIPIENTS_SECTION, keys[ii], NULL));
276 	}
277 
278 	iaddress = CAMEL_INTERNET_ADDRESS (recipients);
279 	len = camel_address_length (recipients);
280 	for (ii = 0; ii < len; ii++) {
281 		const gchar *name, *address;
282 
283 		if (camel_internet_address_get (iaddress, ii, &name, &address)) {
284 			gint keys_index = -1;
285 
286 			account_uid = test_one_recipient (keys, values, name, address, &keys_index);
287 
288 			if (account_uid != NULL)
289 				g_strchomp (account_uid);
290 
291 			if (account_uid != NULL && *account_uid == '\0') {
292 				g_free (account_uid);
293 				account_uid = NULL;
294 			}
295 
296 			if (account_uid != NULL) {
297 				g_warn_if_fail (keys_index >= 0 && keys_index < g_strv_length (keys));
298 				read_alias_info_locked (override,
299 					RECIPIENTS_ALIAS_NAME_SECTION,
300 					RECIPIENTS_ALIAS_ADDRESS_SECTION,
301 					keys[keys_index],
302 					out_alias_name,
303 					out_alias_address);
304 				break;
305 			}
306 		}
307 	}
308 
309 	g_ptr_array_free (values, TRUE);
310 	g_strfreev (keys);
311 
312 	return account_uid;
313 }
314 
315 static void
list_overrides_section_for_account_locked(EMailSendAccountOverride * override,const gchar * account_uid,const gchar * alias_name,const gchar * alias_address,const gchar * section,const gchar * alias_name_section,const gchar * alias_address_section,GList ** overrides)316 list_overrides_section_for_account_locked (EMailSendAccountOverride *override,
317                                            const gchar *account_uid,
318 					   const gchar *alias_name,
319 					   const gchar *alias_address,
320                                            const gchar *section,
321 					   const gchar *alias_name_section,
322 					   const gchar *alias_address_section,
323                                            GList **overrides)
324 {
325 	gchar **keys;
326 
327 	g_return_if_fail (account_uid != NULL);
328 	g_return_if_fail (section != NULL);
329 
330 	if (overrides == NULL)
331 		return;
332 
333 	*overrides = NULL;
334 
335 	keys = g_key_file_get_keys (
336 		override->priv->key_file, section, NULL, NULL);
337 	if (keys != NULL) {
338 		gint ii;
339 
340 		for (ii = 0; keys[ii]; ii++) {
341 			const gchar *key = keys[ii];
342 			gchar *value;
343 
344 			value = g_key_file_get_string (
345 				override->priv->key_file, section, key, NULL);
346 			if (g_strcmp0 (value, account_uid) == 0) {
347 				gchar *stored_alias_name = NULL, *stored_alias_address = NULL;
348 
349 				read_alias_info_locked (override, alias_name_section, alias_address_section,
350 					key, &stored_alias_name, &stored_alias_address);
351 
352 				if (g_strcmp0 (stored_alias_name, alias_name) == 0 &&
353 				    g_strcmp0 (stored_alias_address, alias_address) == 0) {
354 					*overrides = g_list_prepend (*overrides, g_strdup (key));
355 				}
356 
357 				g_free (stored_alias_name);
358 				g_free (stored_alias_address);
359 			}
360 			g_free (value);
361 		}
362 	}
363 
364 	g_strfreev (keys);
365 
366 	*overrides = g_list_reverse (*overrides);
367 }
368 
369 static void
list_overrides_for_account_locked(EMailSendAccountOverride * override,const gchar * account_uid,const gchar * alias_name,const gchar * alias_address,GList ** folder_overrides,GList ** recipient_overrides)370 list_overrides_for_account_locked (EMailSendAccountOverride *override,
371                                    const gchar *account_uid,
372 				   const gchar *alias_name,
373 				   const gchar *alias_address,
374                                    GList **folder_overrides,
375                                    GList **recipient_overrides)
376 {
377 	if (account_uid == NULL)
378 		return;
379 
380 	list_overrides_section_for_account_locked (
381 		override, account_uid, alias_name, alias_address, FOLDERS_SECTION, FOLDERS_ALIAS_NAME_SECTION,
382 		FOLDERS_ALIAS_ADDRESS_SECTION, folder_overrides);
383 
384 	list_overrides_section_for_account_locked (
385 		override, account_uid, alias_name, alias_address, RECIPIENTS_SECTION, RECIPIENTS_ALIAS_NAME_SECTION,
386 		RECIPIENTS_ALIAS_ADDRESS_SECTION, recipient_overrides);
387 }
388 
389 static void
mail_send_account_override_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)390 mail_send_account_override_set_property (GObject *object,
391                                          guint property_id,
392                                          const GValue *value,
393                                          GParamSpec *pspec)
394 {
395 	switch (property_id) {
396 		case PROP_PREFER_FOLDER:
397 			e_mail_send_account_override_set_prefer_folder (
398 				E_MAIL_SEND_ACCOUNT_OVERRIDE (object),
399 				g_value_get_boolean (value));
400 			return;
401 	}
402 
403 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
404 }
405 
406 static void
mail_send_account_override_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)407 mail_send_account_override_get_property (GObject *object,
408                                          guint property_id,
409                                          GValue *value,
410                                          GParamSpec *pspec)
411 {
412 	switch (property_id) {
413 		case PROP_PREFER_FOLDER:
414 			g_value_set_boolean (
415 				value,
416 				e_mail_send_account_override_get_prefer_folder (
417 				E_MAIL_SEND_ACCOUNT_OVERRIDE (object)));
418 			return;
419 	}
420 
421 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
422 }
423 
424 static void
mail_send_account_override_finalize(GObject * object)425 mail_send_account_override_finalize (GObject *object)
426 {
427 	EMailSendAccountOverridePrivate *priv;
428 
429 	priv = E_MAIL_SEND_ACCOUNT_OVERRIDE_GET_PRIVATE (object);
430 
431 	g_key_file_free (priv->key_file);
432 	g_free (priv->config_filename);
433 
434 	g_mutex_clear (&priv->property_lock);
435 
436 	/* Chain up to parent's finalize() method. */
437 	G_OBJECT_CLASS (e_mail_send_account_override_parent_class)->
438 		finalize (object);
439 }
440 
441 static void
e_mail_send_account_override_class_init(EMailSendAccountOverrideClass * class)442 e_mail_send_account_override_class_init (EMailSendAccountOverrideClass *class)
443 {
444 	GObjectClass *object_class;
445 
446 	g_type_class_add_private (
447 		class, sizeof (EMailSendAccountOverridePrivate));
448 
449 	object_class = G_OBJECT_CLASS (class);
450 	object_class->set_property = mail_send_account_override_set_property;
451 	object_class->get_property = mail_send_account_override_get_property;
452 	object_class->finalize = mail_send_account_override_finalize;
453 
454 	g_object_class_install_property (
455 		object_class,
456 		PROP_PREFER_FOLDER,
457 		g_param_spec_boolean (
458 			"prefer-folder",
459 			"Prefer Folder",
460 			NULL,
461 			TRUE,
462 			G_PARAM_READWRITE));
463 
464 	signals[CHANGED] = g_signal_new (
465 		"changed",
466 		G_OBJECT_CLASS_TYPE (object_class),
467 		G_SIGNAL_RUN_FIRST,
468 		G_STRUCT_OFFSET (EMailSendAccountOverrideClass, changed),
469 		NULL, NULL, NULL,
470 		G_TYPE_NONE, 0);
471 }
472 
473 static void
e_mail_send_account_override_init(EMailSendAccountOverride * override)474 e_mail_send_account_override_init (EMailSendAccountOverride *override)
475 {
476 	override->priv = E_MAIL_SEND_ACCOUNT_OVERRIDE_GET_PRIVATE (override);
477 
478 	g_mutex_init (&override->priv->property_lock);
479 	override->priv->key_file = g_key_file_new ();
480 	override->priv->prefer_folder = TRUE;
481 }
482 
483 EMailSendAccountOverride *
e_mail_send_account_override_new(const gchar * config_filename)484 e_mail_send_account_override_new (const gchar *config_filename)
485 {
486 	EMailSendAccountOverride *override;
487 
488 	override = g_object_new (E_TYPE_MAIL_SEND_ACCOUNT_OVERRIDE, NULL);
489 
490 	if (config_filename != NULL)
491 		e_mail_send_account_override_set_config_filename (
492 			override, config_filename);
493 
494 	return override;
495 }
496 
497 void
e_mail_send_account_override_set_config_filename(EMailSendAccountOverride * override,const gchar * config_filename)498 e_mail_send_account_override_set_config_filename (EMailSendAccountOverride *override,
499                                                   const gchar *config_filename)
500 {
501 	GError *error = NULL;
502 	gboolean old_prefer_folder, prefer_folder_changed;
503 
504 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
505 	g_return_if_fail (config_filename != NULL);
506 	g_return_if_fail (*config_filename != '\0');
507 
508 	g_mutex_lock (&override->priv->property_lock);
509 
510 	if (g_strcmp0 (config_filename, override->priv->config_filename) == 0) {
511 		g_mutex_unlock (&override->priv->property_lock);
512 		return;
513 	}
514 
515 	g_free (override->priv->config_filename);
516 	override->priv->config_filename = g_strdup (config_filename);
517 
518 	g_key_file_load_from_file (
519 		override->priv->key_file,
520 		override->priv->config_filename, G_KEY_FILE_NONE, NULL);
521 
522 	old_prefer_folder = override->priv->prefer_folder;
523 	override->priv->prefer_folder = g_key_file_get_boolean (
524 		override->priv->key_file,
525 		OPTIONS_SECTION, OPTION_PREFER_FOLDER, &error);
526 
527 	if (error != NULL) {
528 		/* default value is to prefer the folder override over the recipients */
529 		override->priv->prefer_folder = TRUE;
530 		g_clear_error (&error);
531 	}
532 
533 	prefer_folder_changed =
534 		(override->priv->prefer_folder != old_prefer_folder);
535 
536 	g_mutex_unlock (&override->priv->property_lock);
537 
538 	if (prefer_folder_changed)
539 		g_object_notify (G_OBJECT (override), "prefer-folder");
540 }
541 
542 gchar *
e_mail_send_account_override_dup_config_filename(EMailSendAccountOverride * override)543 e_mail_send_account_override_dup_config_filename (EMailSendAccountOverride *override)
544 {
545 	gchar *config_filename;
546 
547 	g_return_val_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override), NULL);
548 
549 	g_mutex_lock (&override->priv->property_lock);
550 	config_filename = g_strdup (override->priv->config_filename);
551 	g_mutex_unlock (&override->priv->property_lock);
552 
553 	return config_filename;
554 }
555 
556 void
e_mail_send_account_override_set_prefer_folder(EMailSendAccountOverride * override,gboolean prefer_folder)557 e_mail_send_account_override_set_prefer_folder (EMailSendAccountOverride *override,
558                                                 gboolean prefer_folder)
559 {
560 	gboolean changed, saved = FALSE;
561 
562 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
563 
564 	g_mutex_lock (&override->priv->property_lock);
565 
566 	changed = (prefer_folder != override->priv->prefer_folder);
567 
568 	if (changed) {
569 		override->priv->prefer_folder = prefer_folder;
570 
571 		g_key_file_set_boolean (
572 			override->priv->key_file,
573 			OPTIONS_SECTION, OPTION_PREFER_FOLDER, prefer_folder);
574 
575 		saved = e_mail_send_account_override_maybe_save_locked (override);
576 	}
577 
578 	g_mutex_unlock (&override->priv->property_lock);
579 
580 	if (changed)
581 		g_object_notify (G_OBJECT (override), "prefer-folder");
582 	if (saved)
583 		g_signal_emit (override, signals[CHANGED], 0);
584 }
585 
586 gboolean
e_mail_send_account_override_get_prefer_folder(EMailSendAccountOverride * override)587 e_mail_send_account_override_get_prefer_folder (EMailSendAccountOverride *override)
588 {
589 	g_return_val_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override), FALSE);
590 
591 	return override->priv->prefer_folder;
592 }
593 
594 /* free returned pointers with g_free() */
595 gchar *
e_mail_send_account_override_get_account_uid(EMailSendAccountOverride * override,const gchar * folder_uri,CamelInternetAddress * recipients_to,CamelInternetAddress * recipients_cc,CamelInternetAddress * recipients_bcc,gchar ** out_alias_name,gchar ** out_alias_address)596 e_mail_send_account_override_get_account_uid (EMailSendAccountOverride *override,
597                                               const gchar *folder_uri,
598                                               CamelInternetAddress *recipients_to,
599                                               CamelInternetAddress *recipients_cc,
600                                               CamelInternetAddress *recipients_bcc,
601 					      gchar **out_alias_name,
602 					      gchar **out_alias_address)
603 {
604 	gchar *account_uid = NULL;
605 
606 	g_return_val_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override), NULL);
607 	g_return_val_if_fail (override->priv->config_filename != NULL, NULL);
608 
609 	g_mutex_lock (&override->priv->property_lock);
610 
611 	if (override->priv->prefer_folder)
612 		account_uid = get_override_for_folder_uri_locked (
613 			override, folder_uri, out_alias_name, out_alias_address);
614 
615 	if (account_uid == NULL)
616 		account_uid = get_override_for_recipients_locked (
617 			override, CAMEL_ADDRESS (recipients_to), out_alias_name, out_alias_address);
618 
619 	if (account_uid == NULL)
620 		account_uid = get_override_for_recipients_locked (
621 			override, CAMEL_ADDRESS (recipients_cc), out_alias_name, out_alias_address);
622 
623 	if (account_uid == NULL)
624 		account_uid = get_override_for_recipients_locked (
625 			override, CAMEL_ADDRESS (recipients_bcc), out_alias_name, out_alias_address);
626 
627 	if (account_uid == NULL && !override->priv->prefer_folder)
628 		account_uid = get_override_for_folder_uri_locked (
629 			override, folder_uri, out_alias_name, out_alias_address);
630 
631 	g_mutex_unlock (&override->priv->property_lock);
632 
633 	return account_uid;
634 }
635 
636 void
e_mail_send_account_override_remove_for_account_uid(EMailSendAccountOverride * override,const gchar * account_uid,const gchar * alias_name,const gchar * alias_address)637 e_mail_send_account_override_remove_for_account_uid (EMailSendAccountOverride *override,
638                                                      const gchar *account_uid,
639 						     const gchar *alias_name,
640 						     const gchar *alias_address)
641 {
642 	GList *folders = NULL, *recipients = NULL;
643 	gboolean saved = FALSE;
644 
645 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
646 	g_return_if_fail (account_uid != NULL);
647 
648 	g_mutex_lock (&override->priv->property_lock);
649 
650 	list_overrides_for_account_locked (
651 		override, account_uid, alias_name, alias_address, &folders, &recipients);
652 
653 	if (folders != NULL || recipients != NULL) {
654 		GList *link;
655 
656 		for (link = folders; link != NULL; link = g_list_next (link)) {
657 			const gchar *key = link->data;
658 
659 			g_key_file_remove_key (
660 				override->priv->key_file,
661 				FOLDERS_SECTION, key, NULL);
662 
663 			write_alias_info_locked (override, FOLDERS_ALIAS_NAME_SECTION,
664 				FOLDERS_ALIAS_ADDRESS_SECTION, key, NULL, NULL);
665 		}
666 
667 		for (link = recipients; link != NULL; link = g_list_next (link)) {
668 			const gchar *key = link->data;
669 
670 			g_key_file_remove_key (
671 				override->priv->key_file,
672 				RECIPIENTS_SECTION, key, NULL);
673 
674 			write_alias_info_locked (override, RECIPIENTS_ALIAS_NAME_SECTION,
675 				RECIPIENTS_ALIAS_ADDRESS_SECTION, key, NULL, NULL);
676 		}
677 
678 		saved = e_mail_send_account_override_maybe_save_locked (override);
679 	}
680 
681 	g_list_free_full (folders, g_free);
682 	g_list_free_full (recipients, g_free);
683 
684 	g_mutex_unlock (&override->priv->property_lock);
685 
686 	if (saved)
687 		g_signal_emit (override, signals[CHANGED], 0);
688 }
689 
690 gchar *
e_mail_send_account_override_get_for_folder(EMailSendAccountOverride * override,const gchar * folder_uri,gchar ** out_alias_name,gchar ** out_alias_address)691 e_mail_send_account_override_get_for_folder (EMailSendAccountOverride *override,
692                                              const gchar *folder_uri,
693 					     gchar **out_alias_name,
694 					     gchar **out_alias_address)
695 {
696 	gchar *account_uid = NULL;
697 
698 	g_return_val_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override), NULL);
699 
700 	g_mutex_lock (&override->priv->property_lock);
701 
702 	account_uid = get_override_for_folder_uri_locked (override, folder_uri, out_alias_name, out_alias_address);
703 
704 	g_mutex_unlock (&override->priv->property_lock);
705 
706 	return account_uid;
707 }
708 
709 void
e_mail_send_account_override_set_for_folder(EMailSendAccountOverride * override,const gchar * folder_uri,const gchar * account_uid,const gchar * alias_name,const gchar * alias_address)710 e_mail_send_account_override_set_for_folder (EMailSendAccountOverride *override,
711                                              const gchar *folder_uri,
712                                              const gchar *account_uid,
713 					     const gchar *alias_name,
714 					     const gchar *alias_address)
715 {
716 	gboolean saved;
717 
718 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
719 	g_return_if_fail (folder_uri != NULL);
720 	g_return_if_fail (account_uid != NULL);
721 
722 	g_mutex_lock (&override->priv->property_lock);
723 
724 	g_key_file_set_string (
725 		override->priv->key_file,
726 		FOLDERS_SECTION, folder_uri, account_uid);
727 
728 	write_alias_info_locked (override, FOLDERS_ALIAS_NAME_SECTION,
729 		FOLDERS_ALIAS_ADDRESS_SECTION, folder_uri, alias_name, alias_address);
730 
731 	saved = e_mail_send_account_override_maybe_save_locked (override);
732 
733 	g_mutex_unlock (&override->priv->property_lock);
734 
735 	if (saved)
736 		g_signal_emit (override, signals[CHANGED], 0);
737 }
738 
739 void
e_mail_send_account_override_remove_for_folder(EMailSendAccountOverride * override,const gchar * folder_uri)740 e_mail_send_account_override_remove_for_folder (EMailSendAccountOverride *override,
741                                                 const gchar *folder_uri)
742 {
743 	gboolean saved;
744 
745 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
746 	g_return_if_fail (folder_uri != NULL);
747 
748 	g_mutex_lock (&override->priv->property_lock);
749 
750 	g_key_file_remove_key (
751 		override->priv->key_file, FOLDERS_SECTION, folder_uri, NULL);
752 
753 	write_alias_info_locked (override, FOLDERS_ALIAS_NAME_SECTION,
754 		FOLDERS_ALIAS_ADDRESS_SECTION, folder_uri, NULL, NULL);
755 
756 	saved = e_mail_send_account_override_maybe_save_locked (override);
757 
758 	g_mutex_unlock (&override->priv->property_lock);
759 
760 	if (saved)
761 		g_signal_emit (override, signals[CHANGED], 0);
762 }
763 
764 gchar *
e_mail_send_account_override_get_for_recipient(EMailSendAccountOverride * override,CamelInternetAddress * recipients,gchar ** out_alias_name,gchar ** out_alias_address)765 e_mail_send_account_override_get_for_recipient (EMailSendAccountOverride *override,
766                                                 CamelInternetAddress *recipients,
767 						gchar **out_alias_name,
768 						gchar **out_alias_address)
769 {
770 	gchar *account_uid;
771 
772 	g_return_val_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override), NULL);
773 	g_return_val_if_fail (recipients != NULL, NULL);
774 
775 	g_mutex_lock (&override->priv->property_lock);
776 
777 	account_uid = get_override_for_recipients_locked (
778 		override, CAMEL_ADDRESS (recipients), out_alias_name, out_alias_address);
779 
780 	g_mutex_unlock (&override->priv->property_lock);
781 
782 	return account_uid;
783 }
784 
785 void
e_mail_send_account_override_set_for_recipient(EMailSendAccountOverride * override,const gchar * recipient,const gchar * account_uid,const gchar * alias_name,const gchar * alias_address)786 e_mail_send_account_override_set_for_recipient (EMailSendAccountOverride *override,
787                                                 const gchar *recipient,
788                                                 const gchar *account_uid,
789 						const gchar *alias_name,
790 						const gchar *alias_address)
791 {
792 	gboolean saved;
793 
794 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
795 	g_return_if_fail (recipient != NULL);
796 	g_return_if_fail (account_uid != NULL);
797 
798 	g_mutex_lock (&override->priv->property_lock);
799 
800 	g_key_file_set_string (
801 		override->priv->key_file,
802 		RECIPIENTS_SECTION, recipient, account_uid);
803 
804 	write_alias_info_locked (override, RECIPIENTS_ALIAS_NAME_SECTION,
805 		RECIPIENTS_ALIAS_ADDRESS_SECTION, recipient, alias_name, alias_address);
806 
807 	saved = e_mail_send_account_override_maybe_save_locked (override);
808 
809 	g_mutex_unlock (&override->priv->property_lock);
810 
811 	if (saved)
812 		g_signal_emit (override, signals[CHANGED], 0);
813 }
814 
815 void
e_mail_send_account_override_remove_for_recipient(EMailSendAccountOverride * override,const gchar * recipient)816 e_mail_send_account_override_remove_for_recipient (EMailSendAccountOverride *override,
817                                                    const gchar *recipient)
818 {
819 	gboolean saved;
820 
821 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
822 	g_return_if_fail (recipient != NULL);
823 
824 	g_mutex_lock (&override->priv->property_lock);
825 
826 	g_key_file_remove_key (
827 		override->priv->key_file, RECIPIENTS_SECTION, recipient, NULL);
828 
829 	write_alias_info_locked (override, RECIPIENTS_ALIAS_NAME_SECTION,
830 		RECIPIENTS_ALIAS_ADDRESS_SECTION, recipient, NULL, NULL);
831 
832 	saved = e_mail_send_account_override_maybe_save_locked (override);
833 
834 	g_mutex_unlock (&override->priv->property_lock);
835 
836 	if (saved)
837 		g_signal_emit (override, signals[CHANGED], 0);
838 }
839 
840 void
e_mail_send_account_override_list_for_account(EMailSendAccountOverride * override,const gchar * account_uid,const gchar * alias_name,const gchar * alias_address,GList ** folder_overrides,GList ** recipient_overrides)841 e_mail_send_account_override_list_for_account (EMailSendAccountOverride *override,
842                                                const gchar *account_uid,
843 					       const gchar *alias_name,
844 					       const gchar *alias_address,
845                                                GList **folder_overrides,
846                                                GList **recipient_overrides)
847 {
848 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
849 	g_return_if_fail (account_uid != NULL);
850 
851 	g_mutex_lock (&override->priv->property_lock);
852 
853 	list_overrides_for_account_locked (
854 		override, account_uid, alias_name, alias_address, folder_overrides, recipient_overrides);
855 
856 	g_mutex_unlock (&override->priv->property_lock);
857 }
858 
859 void
e_mail_send_account_override_freeze_save(EMailSendAccountOverride * override)860 e_mail_send_account_override_freeze_save (EMailSendAccountOverride *override)
861 {
862 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
863 
864 	g_mutex_lock (&override->priv->property_lock);
865 
866 	override->priv->save_frozen++;
867 	if (!override->priv->save_frozen) {
868 		g_warn_if_reached ();
869 	}
870 
871 	g_mutex_unlock (&override->priv->property_lock);
872 }
873 
874 void
e_mail_send_account_override_thaw_save(EMailSendAccountOverride * override)875 e_mail_send_account_override_thaw_save (EMailSendAccountOverride *override)
876 {
877 	gboolean saved = FALSE;
878 
879 	g_return_if_fail (E_IS_MAIL_SEND_ACCOUNT_OVERRIDE (override));
880 
881 	g_mutex_lock (&override->priv->property_lock);
882 
883 	if (!override->priv->save_frozen) {
884 		g_warn_if_reached ();
885 	} else {
886 		override->priv->save_frozen--;
887 		if (!override->priv->save_frozen && override->priv->need_save)
888 			saved = e_mail_send_account_override_save_locked (override);
889 	}
890 
891 	g_mutex_unlock (&override->priv->property_lock);
892 
893 	if (saved)
894 		g_signal_emit (override, signals[CHANGED], 0);
895 }
896 
897