1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <modest-account-mgr-helpers.h>
31 #include <modest-account-mgr-priv.h>
32 #include <tny-simple-list.h>
33 #include <modest-runtime.h>
37 modest_account_mgr_set_enabled (ModestAccountMgr *self, const gchar* name,
40 return modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_ENABLED, enabled,FALSE);
45 modest_account_mgr_get_enabled (ModestAccountMgr *self, const gchar* name)
47 return modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_ENABLED, FALSE);
50 gboolean modest_account_mgr_set_signature (ModestAccountMgr *self, const gchar* name,
51 const gchar* signature, gboolean use_signature)
53 gboolean result = modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE,
54 use_signature, FALSE);
55 result = result && modest_account_mgr_set_string (self, name, MODEST_ACCOUNT_SIGNATURE,
61 gchar* modest_account_mgr_get_signature (ModestAccountMgr *self, const gchar* name,
62 gboolean* use_signature)
66 modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, FALSE);
69 return modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SIGNATURE, FALSE);
74 #if 0 /* Not needed, but works. */
76 compare_option_strings_for_name (const gchar* a, const gchar* b)
78 /* printf(" debug: compare_option_strings_for_name():a=%s, b=%s\n", a, b); */
79 const gchar* sep = strchr(a, '=');
87 /* Get the part of the string before the =.
88 * Note that this allocation is inefficient just so we can do a strcmp. */
89 gchar* name = g_malloc (len+1);
91 name[len] = 0; /* Null-termination. */
93 /* printf(" debug: name=%s\n", name); */
95 gint result = strcmp (name, b);
103 modest_server_account_data_get_option_string (GSList* options_list, const gchar* option_name)
108 gchar *result = NULL;
109 GSList* option = g_slist_find_custom(options_list, option_name, (GCompareFunc)compare_option_strings_for_name);
111 /* Get the value part of the key=value pair: */
112 const gchar* pair = (const gchar*)option->data;
114 const gchar* sep = strchr(pair, '=');
116 gint len = sep - pair;
118 result = g_strdup(sep+1);
120 /* Avoid returning an empty string instead of NULL. */
121 if(result && strlen(result) == 0) {
133 modest_server_account_data_get_option_bool (GSList* options_list, const gchar* option_name)
138 gboolean result = FALSE;
139 GSList* option = g_slist_find_custom(options_list, option_name, (GCompareFunc)strcmp);
149 gboolean modest_account_mgr_set_connection_specific_smtp (ModestAccountMgr *self,
150 const gchar* account_name,
151 const gchar* connection_name, const gchar* server_account_name)
153 modest_account_mgr_remove_connection_specific_smtp (self, account_name, connection_name);
155 GSList *list = modest_account_mgr_get_list (self, account_name,
156 MODEST_ACCOUNT_CONNECTION_SPECIFIC_SMTP_LIST,
157 MODEST_CONF_VALUE_STRING, TRUE);
159 /* The server account is in the item after the connection name: */
160 GSList *list_connection = g_slist_append (list, (gpointer)connection_name);
161 list_connection = g_slist_append (list_connection, (gpointer)server_account_name);
163 /* Reset the changed list: */
164 modest_account_mgr_set_list (self, account_name,
165 MODEST_ACCOUNT_CONNECTION_SPECIFIC_SMTP_LIST, list,
166 MODEST_CONF_VALUE_STRING, TRUE);
168 /* TODO: Should we free the items too, or just the list? */
175 * modest_account_mgr_remove_connection_specific_smtp
176 * @self: a ModestAccountMgr instance
177 * @name: the account name
178 * @connection_name: A libconic IAP connection name
180 * Disassacoiate a server account to use with the specific connection for this account.
182 * Returns: TRUE if it worked, FALSE otherwise
184 gboolean modest_account_mgr_remove_connection_specific_smtp (ModestAccountMgr *self,
185 const gchar* account_name, const gchar* connection_name)
187 GSList *list = modest_account_mgr_get_list (self, account_name,
188 MODEST_ACCOUNT_CONNECTION_SPECIFIC_SMTP_LIST,
189 MODEST_CONF_VALUE_STRING, TRUE);
193 /* The server account is in the item after the connection name: */
194 GSList *list_connection = g_slist_find_custom (list, connection_name, (GCompareFunc)strcmp);
195 if (list_connection) {
196 /* remove both items: */
197 GSList *temp = g_slist_delete_link(list_connection, list_connection);
198 temp = g_slist_delete_link(temp, g_slist_next(temp));
201 /* Reset the changed list: */
202 modest_account_mgr_set_list (self, account_name,
203 MODEST_ACCOUNT_CONNECTION_SPECIFIC_SMTP_LIST, list,
204 MODEST_CONF_VALUE_STRING, TRUE);
206 /* TODO: Should we free the items too, or just the list? */
213 * modest_account_mgr_get_connection_specific_smtp
214 * @self: a ModestAccountMgr instance
215 * @name: the account name
216 * @connection_name: A libconic IAP connection name
218 * Retrieve a server account to use with this specific connection for this account.
220 * Returns: a server account name to use for this connection, or NULL if none is specified.
222 gchar* modest_account_mgr_get_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name,
223 const gchar* connection_name)
225 gchar *result = NULL;
227 GSList *list = modest_account_mgr_get_list (self, account_name,
228 MODEST_ACCOUNT_CONNECTION_SPECIFIC_SMTP_LIST,
229 MODEST_CONF_VALUE_STRING, TRUE);
233 /* The server account is in the item after the connection name: */
234 GSList *list_connection = g_slist_find_custom (list, connection_name, (GCompareFunc)strcmp);
235 if (list_connection) {
236 GSList * list_server_account = g_slist_next(list_connection);
237 if (list_server_account)
238 result = g_strdup ((gchar*)(list_server_account->data));
241 /* TODO: Should we free the items too, or just the list? */
249 static ModestProtocol
250 get_secure_auth_for_conf_string(const gchar* value)
252 ModestProtocol result = MODEST_PROTOCOL_AUTH_NONE;
254 if (strcmp(value, MODEST_ACCOUNT_AUTH_MECH_VALUE_NONE) == 0)
255 result = MODEST_PROTOCOL_AUTH_NONE;
256 else if (strcmp(value, MODEST_ACCOUNT_AUTH_MECH_VALUE_PASSWORD) == 0)
257 result = MODEST_PROTOCOL_AUTH_PASSWORD;
258 else if (strcmp(value, MODEST_ACCOUNT_AUTH_MECH_VALUE_CRAMMD5) == 0)
259 result = MODEST_PROTOCOL_AUTH_CRAMMD5;
266 modest_server_account_get_secure_auth (ModestAccountMgr *self,
267 const gchar* account_name)
269 ModestProtocol result = MODEST_PROTOCOL_AUTH_NONE;
270 gchar* value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH,
271 TRUE /* server account */);
273 result = get_secure_auth_for_conf_string (value);
283 modest_server_account_set_secure_auth (ModestAccountMgr *self,
284 const gchar* account_name, ModestProtocol secure_auth)
286 /* Get the conf string for the enum value: */
287 const gchar* str_value = NULL;
288 if (secure_auth == MODEST_PROTOCOL_AUTH_NONE)
289 str_value = MODEST_ACCOUNT_AUTH_MECH_VALUE_NONE;
290 else if (secure_auth == MODEST_PROTOCOL_AUTH_PASSWORD)
291 str_value = MODEST_ACCOUNT_AUTH_MECH_VALUE_PASSWORD;
292 else if (secure_auth == MODEST_PROTOCOL_AUTH_CRAMMD5)
293 str_value = MODEST_ACCOUNT_AUTH_MECH_VALUE_CRAMMD5;
295 /* Set it in the configuration: */
296 modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, str_value, TRUE);
299 static ModestProtocol
300 get_security_for_conf_string(const gchar* value)
302 ModestProtocol result = MODEST_PROTOCOL_SECURITY_NONE;
304 if (strcmp(value, MODEST_ACCOUNT_SECURITY_VALUE_NONE) == 0)
305 result = MODEST_PROTOCOL_SECURITY_NONE;
306 else if (strcmp(value, MODEST_ACCOUNT_SECURITY_VALUE_NORMAL) == 0)
307 result = MODEST_PROTOCOL_SECURITY_TLS;
308 else if (strcmp(value, MODEST_ACCOUNT_SECURITY_VALUE_SSL) == 0)
309 result = MODEST_PROTOCOL_SECURITY_SSL;
316 modest_server_account_get_security (ModestAccountMgr *self,
317 const gchar* account_name)
319 ModestProtocol result = MODEST_PROTOCOL_SECURITY_NONE;
320 gchar* value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_SECURITY,
321 TRUE /* server account */);
323 result = get_security_for_conf_string (value);
332 modest_server_account_set_security (ModestAccountMgr *self,
333 const gchar* account_name, ModestProtocol security)
335 /* Get the conf string for the enum value: */
336 const gchar* str_value = NULL;
337 if (security == MODEST_PROTOCOL_SECURITY_NONE)
338 str_value = MODEST_ACCOUNT_SECURITY_VALUE_NONE;
339 else if (security == MODEST_PROTOCOL_SECURITY_TLS)
340 str_value = MODEST_ACCOUNT_SECURITY_VALUE_NORMAL;
341 else if (security == MODEST_PROTOCOL_SECURITY_SSL)
342 str_value = MODEST_ACCOUNT_SECURITY_VALUE_SSL;
344 /* Set it in the configuration: */
345 modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY, str_value, TRUE);
350 modest_account_mgr_get_server_account_option (ModestAccountMgr *self,
351 const gchar* account_name, const gchar* option_name)
353 GSList *option_list = modest_account_mgr_get_list (self, account_name, MODEST_ACCOUNT_OPTIONS,
354 MODEST_CONF_VALUE_STRING, TRUE);
358 gchar *result = modest_server_account_data_get_option_value (option_list, option_name);
360 /* TODO: Should we free the items too, or just the list? */
361 g_slist_free (option_list);
367 ModestServerAccountData*
368 modest_account_mgr_get_server_account_data (ModestAccountMgr *self, const gchar* name)
370 ModestServerAccountData *data;
373 g_return_val_if_fail (modest_account_mgr_account_exists (self, name, TRUE), NULL);
374 data = g_slice_new0 (ModestServerAccountData);
376 data->account_name = g_strdup (name);
377 data->hostname = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_HOSTNAME,TRUE);
378 data->username = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_USERNAME,TRUE);
379 proto = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_PROTO, TRUE);
380 data->proto = modest_protocol_info_get_protocol (proto);
383 data->port = modest_account_mgr_get_int (self, name, MODEST_ACCOUNT_PORT, TRUE);
385 gchar *secure_auth_str = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_AUTH_MECH, TRUE);
386 data->secure_auth = get_secure_auth_for_conf_string(secure_auth_str);
387 g_free (secure_auth_str);
389 gchar *security_str = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SECURITY, TRUE);
390 data->security = get_security_for_conf_string(security_str);
391 g_free (security_str);
393 data->last_updated = modest_account_mgr_get_int (self, name, MODEST_ACCOUNT_LAST_UPDATED,TRUE);
395 data->password = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_PASSWORD, TRUE);
396 data->uri = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_URI,TRUE);
397 data->options = modest_account_mgr_get_list (self, name, MODEST_ACCOUNT_OPTIONS,
398 MODEST_CONF_VALUE_STRING, TRUE);
406 modest_account_mgr_free_server_account_data (ModestAccountMgr *self,
407 ModestServerAccountData* data)
409 g_return_if_fail (self);
412 return; /* not an error */
414 g_free (data->account_name);
415 data->account_name = NULL;
417 g_free (data->hostname);
418 data->hostname = NULL;
420 g_free (data->username);
421 data->username = NULL;
423 g_free (data->password);
424 data->password = NULL;
427 GSList *tmp = data->options;
430 tmp = g_slist_next (tmp);
432 g_slist_free (data->options);
435 g_slice_free (ModestServerAccountData, data);
438 /** You must use modest_account_mgr_free_account_data() on the result.
441 modest_account_mgr_get_account_data (ModestAccountMgr *self, const gchar* name)
443 ModestAccountData *data;
444 gchar *server_account;
445 gchar *default_account;
447 g_return_val_if_fail (self, NULL);
448 g_return_val_if_fail (name, NULL);
450 if (!modest_account_mgr_account_exists (self, name, FALSE)) {
451 /* For instance, maybe you are mistakenly checking for a server account name? */
452 g_warning ("%s: Account %s does not exist.", __FUNCTION__, name);
456 data = g_slice_new0 (ModestAccountData);
458 data->account_name = g_strdup (name);
460 data->display_name = modest_account_mgr_get_string (self, name,
461 MODEST_ACCOUNT_DISPLAY_NAME,
463 data->fullname = modest_account_mgr_get_string (self, name,
464 MODEST_ACCOUNT_FULLNAME,
466 data->email = modest_account_mgr_get_string (self, name,
467 MODEST_ACCOUNT_EMAIL,
469 data->is_enabled = modest_account_mgr_get_enabled (self, name);
471 default_account = modest_account_mgr_get_default_account (self);
472 data->is_default = (default_account && strcmp (default_account, name) == 0);
473 g_free (default_account);
476 server_account = modest_account_mgr_get_string (self, name,
477 MODEST_ACCOUNT_STORE_ACCOUNT,
479 if (server_account) {
480 data->store_account =
481 modest_account_mgr_get_server_account_data (self, server_account);
482 g_free (server_account);
486 server_account = modest_account_mgr_get_string (self, name,
487 MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
489 if (server_account) {
490 data->transport_account =
491 modest_account_mgr_get_server_account_data (self, server_account);
492 g_free (server_account);
500 modest_account_mgr_free_account_data (ModestAccountMgr *self, ModestAccountData *data)
502 g_return_if_fail (self);
504 if (!data) /* not an error */
507 g_free (data->account_name);
508 g_free (data->display_name);
509 g_free (data->fullname);
510 g_free (data->email);
512 modest_account_mgr_free_server_account_data (self, data->store_account);
513 modest_account_mgr_free_server_account_data (self, data->transport_account);
515 g_slice_free (ModestAccountData, data);
520 modest_account_mgr_get_default_account (ModestAccountMgr *self)
526 g_return_val_if_fail (self, NULL);
528 conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
529 account = modest_conf_get_string (conf, MODEST_CONF_DEFAULT_ACCOUNT, &err);
532 g_printerr ("modest: failed to get '%s': %s\n",
533 MODEST_CONF_DEFAULT_ACCOUNT, err->message);
539 /* it's not really an error if there is no default account */
544 if (!modest_account_mgr_account_exists (self, account, FALSE)) {
545 g_printerr ("modest: default account does not exist\n");
555 modest_account_mgr_set_default_account (ModestAccountMgr *self, const gchar* account)
559 g_return_val_if_fail (self, FALSE);
560 g_return_val_if_fail (account, FALSE);
561 g_return_val_if_fail (modest_account_mgr_account_exists (self, account, FALSE),
564 conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
566 return modest_conf_set_string (conf, MODEST_CONF_DEFAULT_ACCOUNT,
572 modest_account_mgr_unset_default_account (ModestAccountMgr *self)
576 g_return_val_if_fail (self, FALSE);
578 conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
580 return modest_conf_remove_key (conf, MODEST_CONF_DEFAULT_ACCOUNT, NULL /* err */);
585 modest_account_mgr_set_first_account_as_default (ModestAccountMgr *self)
587 gboolean result = FALSE;
588 GSList *account_names = modest_account_mgr_account_names (self, TRUE /* only enabled */);
591 const gchar* account_name = (const gchar*)account_names->data;
593 result = modest_account_mgr_set_default_account (self, account_name);
596 /* TODO: Free the strings too? */
597 g_slist_free (account_names);
603 modest_account_mgr_get_from_string (ModestAccountMgr *self, const gchar* name)
605 gchar *fullname, *email, *from;
607 g_return_val_if_fail (self, NULL);
608 g_return_val_if_fail (name, NULL);
610 fullname = modest_account_mgr_get_string (self, name,MODEST_ACCOUNT_FULLNAME,
612 email = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_EMAIL,
614 from = g_strdup_printf ("%s <%s>",
615 fullname ? fullname : "",
623 /* Add a number to the end of the text, or increment a number that is already there.
626 util_increment_name (const gchar* text)
628 /* Get the end character,
629 * also doing a UTF-8 validation which is required for using g_utf8_prev_char().
631 const gchar* end = NULL;
632 if (!g_utf8_validate (text, -1, &end))
638 --end; /* Go to before the null-termination. */
640 /* Look at each UTF-8 characer, starting at the end: */
641 const gchar* p = end;
642 const gchar* alpha_end = NULL;
645 /* Stop when we reach the first character that is not a numeric digit: */
646 const gunichar ch = g_utf8_get_char (p);
647 if (!g_unichar_isdigit (ch)) {
652 p = g_utf8_prev_char (p);
656 /* The text must consist completely of numeric digits. */
662 /* Intepret and increment the number, if any: */
663 gint num = atol (alpha_end);
666 /* Get the name part: */
667 gint name_len = alpha_end - text;
668 gchar *name_without_number = g_malloc(name_len + 1);
669 memcpy (name_without_number, text, name_len);
670 name_without_number[name_len] = 0;\
672 /* Concatenate the text part and the new number: */
673 gchar *result = g_strdup_printf("%s%d", name_without_number, num);
674 g_free (name_without_number);
680 modest_account_mgr_get_unused_account_name (ModestAccountMgr *self, const gchar* starting_name,
681 gboolean server_account)
683 gchar *account_name = g_strdup (starting_name);
685 while (modest_account_mgr_account_exists (self,
686 account_name, server_account /* server_account */)) {
688 gchar * account_name2 = util_increment_name (account_name);
689 g_free (account_name);
690 account_name = account_name2;
697 modest_account_mgr_get_unused_account_display_name (ModestAccountMgr *self, const gchar* starting_name)
699 gchar *account_name = g_strdup (starting_name);
701 while (modest_account_mgr_account_with_display_name_exists (self, account_name)) {
703 gchar * account_name2 = util_increment_name (account_name);
704 g_free (account_name);
705 account_name = account_name2;