summaryrefslogtreecommitdiff
path: root/libsylph/account.c
diff options
context:
space:
mode:
authorSimeon Simeonov2018-02-26 11:23:00 +0100
committerSimeon Simeonov2018-02-26 11:23:00 +0100
commit0b3cbf57875fd692e4ba0b336fefa4bee1ed00dc (patch)
treeaf916a30553c78ce9d4f2d8658656a175c5b6921 /libsylph/account.c
Initial commit for sylpheed 3.7.0
Diffstat (limited to 'libsylph/account.c')
-rw-r--r--libsylph/account.c491
1 files changed, 491 insertions, 0 deletions
diff --git a/libsylph/account.c b/libsylph/account.c
new file mode 100644
index 0000000..2431bf3
--- /dev/null
+++ b/libsylph/account.c
@@ -0,0 +1,491 @@
1/*
2 * LibSylph -- E-Mail client library
3 * Copyright (C) 1999-2009 Hiroyuki Yamamoto
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include "config.h"
22#endif
23
24#include "defs.h"
25
26#include <glib.h>
27#include <glib/gi18n.h>
28#include <stdio.h>
29#include <errno.h>
30
31#include "folder.h"
32#include "account.h"
33#include "prefs.h"
34#include "prefs_account.h"
35#include "procmsg.h"
36#include "procheader.h"
37#include "utils.h"
38#include "sylmain.h"
39
40PrefsAccount *cur_account;
41
42static GList *account_list = NULL;
43
44GHashTable *address_table;
45
46
47void account_read_config_all(void)
48{
49 GSList *ac_label_list = NULL, *cur;
50 gchar *rcpath;
51 FILE *fp;
52 gchar buf[PREFSBUFSIZE];
53 PrefsAccount *ac_prefs;
54
55 debug_print(_("Reading all config for each account...\n"));
56
57 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
58 if ((fp = g_fopen(rcpath, "rb")) == NULL) {
59 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
60 g_free(rcpath);
61 return;
62 }
63 g_free(rcpath);
64
65 while (fgets(buf, sizeof(buf), fp) != NULL) {
66 if (!strncmp(buf, "[Account: ", 10)) {
67 strretchomp(buf);
68 memmove(buf, buf + 1, strlen(buf));
69 buf[strlen(buf) - 1] = '\0';
70 debug_print("Found label: %s\n", buf);
71 ac_label_list = g_slist_append(ac_label_list,
72 g_strdup(buf));
73 }
74 }
75 fclose(fp);
76
77 /* read config data from file */
78 cur_account = NULL;
79 for (cur = ac_label_list; cur != NULL; cur = cur->next) {
80 ac_prefs = prefs_account_new();
81 prefs_account_read_config(ac_prefs, (gchar *)cur->data);
82 account_list = g_list_append(account_list, ac_prefs);
83 if (ac_prefs->is_default)
84 cur_account = ac_prefs;
85 }
86 /* if default is not set, assume first account as default */
87 if (!cur_account && account_list) {
88 ac_prefs = (PrefsAccount *)account_list->data;
89 account_set_as_default(ac_prefs);
90 cur_account = ac_prefs;
91 }
92
93 while (ac_label_list) {
94 g_free(ac_label_list->data);
95 ac_label_list = g_slist_remove(ac_label_list,
96 ac_label_list->data);
97 }
98}
99
100void account_write_config_all(void)
101{
102 prefs_account_write_config_all(account_list);
103}
104
105PrefsAccount *account_get_current_account(void)
106{
107 return cur_account;
108}
109
110PrefsAccount *account_find_from_smtp_server(const gchar *address,
111 const gchar *smtp_server)
112{
113 GList *cur;
114 PrefsAccount *ac;
115
116 g_return_val_if_fail(address != NULL, NULL);
117 g_return_val_if_fail(smtp_server != NULL, NULL);
118
119 for (cur = account_list; cur != NULL; cur = cur->next) {
120 ac = (PrefsAccount *)cur->data;
121 if (!strcmp2(address, ac->address) &&
122 !strcmp2(smtp_server, ac->smtp_server))
123 return ac;
124 }
125
126 return NULL;
127}
128
129/*
130 * account_find_from_address:
131 * @address: Email address string.
132 *
133 * Find a mail (not news) account with the specified email address.
134 *
135 * Return value: The found account, or NULL if not found.
136 */
137PrefsAccount *account_find_from_address(const gchar *address)
138{
139 GList *cur;
140 PrefsAccount *ac;
141
142 g_return_val_if_fail(address != NULL, NULL);
143
144 for (cur = account_list; cur != NULL; cur = cur->next) {
145 ac = (PrefsAccount *)cur->data;
146 if (ac->protocol != A_NNTP && ac->address &&
147 strcasestr(address, ac->address) != NULL)
148 return ac;
149 }
150
151 return NULL;
152}
153
154PrefsAccount *account_find_from_id(gint id)
155{
156 GList *cur;
157 PrefsAccount *ac;
158
159 for (cur = account_list; cur != NULL; cur = cur->next) {
160 ac = (PrefsAccount *)cur->data;
161 if (id == ac->account_id)
162 return ac;
163 }
164
165 return NULL;
166}
167
168PrefsAccount *account_find_from_item(FolderItem *item)
169{
170 PrefsAccount *ac;
171
172 g_return_val_if_fail(item != NULL, NULL);
173
174 ac = account_find_from_item_property(item);
175 if (!ac)
176 ac = item->folder->account;
177
178 return ac;
179}
180
181PrefsAccount *account_find_from_item_property(FolderItem *item)
182{
183 PrefsAccount *ac;
184
185 g_return_val_if_fail(item != NULL, NULL);
186
187 ac = item->account;
188 if (!ac) {
189 FolderItem *cur_item = item->parent;
190 while (cur_item != NULL) {
191 if (cur_item->account && cur_item->ac_apply_sub) {
192 ac = cur_item->account;
193 break;
194 }
195 cur_item = cur_item->parent;
196 }
197 }
198
199 return ac;
200}
201
202PrefsAccount *account_find_from_message_file(const gchar *file)
203{
204 static HeaderEntry hentry[] = {{"From:", NULL, FALSE},
205 {"X-Sylpheed-Account-Id:", NULL, FALSE},
206 {"AID:", NULL, FALSE},
207 {NULL, NULL, FALSE}};
208
209 enum
210 {
211 H_FROM = 0,
212 H_X_SYLPHEED_ACCOUNT_ID = 1,
213 H_AID = 2
214 };
215
216 PrefsAccount *ac = NULL;
217 FILE *fp;
218 gchar *str;
219 gchar buf[BUFFSIZE];
220 gint hnum;
221
222 g_return_val_if_fail(file != NULL, NULL);
223
224 if ((fp = g_fopen(file, "rb")) == NULL) {
225 FILE_OP_ERROR(file, "fopen");
226 return NULL;
227 }
228
229 while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
230 != -1) {
231 str = buf + strlen(hentry[hnum].name);
232 if (hnum == H_FROM)
233 ac = account_find_from_address(str);
234 else if (hnum == H_X_SYLPHEED_ACCOUNT_ID || hnum == H_AID) {
235 PrefsAccount *tmp_ac;
236
237 tmp_ac = account_find_from_id(atoi(str));
238 if (tmp_ac) {
239 ac = tmp_ac;
240 break;
241 }
242 }
243 }
244
245 fclose(fp);
246 return ac;
247}
248
249PrefsAccount *account_find_from_msginfo(MsgInfo *msginfo)
250{
251 gchar *file;
252 PrefsAccount *ac;
253
254 file = procmsg_get_message_file(msginfo);
255 ac = account_find_from_message_file(file);
256 g_free(file);
257
258 if (!ac && msginfo->folder)
259 ac = account_find_from_item(msginfo->folder);
260
261 return ac;
262}
263
264gboolean account_address_exist(const gchar *address)
265{
266 if (!address_table) {
267 GList *cur;
268
269 address_table = g_hash_table_new(g_str_hash, g_str_equal);
270 for (cur = account_list; cur != NULL; cur = cur->next) {
271 PrefsAccount *ac = (PrefsAccount *)cur->data;
272
273 if (ac->address)
274 g_hash_table_insert(address_table, ac->address,
275 GINT_TO_POINTER(1));
276 }
277 }
278
279 return (gboolean)g_hash_table_lookup(address_table, address);
280}
281
282void account_foreach(AccountFunc func, gpointer user_data)
283{
284 GList *cur;
285
286 for (cur = account_list; cur != NULL; cur = cur->next)
287 if (func((PrefsAccount *)cur->data, user_data) != 0)
288 return;
289}
290
291GList *account_get_list(void)
292{
293 return account_list;
294}
295
296void account_list_free(void)
297{
298 g_list_free(account_list);
299 account_list = NULL;
300}
301
302void account_append(PrefsAccount *ac_prefs)
303{
304 account_list = g_list_append(account_list, ac_prefs);
305 account_updated();
306}
307
308void account_set_as_default(PrefsAccount *ac_prefs)
309{
310 PrefsAccount *ap;
311 GList *cur;
312
313 for (cur = account_list; cur != NULL; cur = cur->next) {
314 ap = (PrefsAccount *)cur->data;
315 if (ap->is_default)
316 ap->is_default = FALSE;
317 }
318
319 ac_prefs->is_default = TRUE;
320}
321
322PrefsAccount *account_get_default(void)
323{
324 PrefsAccount *ap;
325 GList *cur;
326
327 for (cur = account_list; cur != NULL; cur = cur->next) {
328 ap = (PrefsAccount *)cur->data;
329 if (ap->is_default)
330 return ap;
331 }
332
333 return NULL;
334}
335
336#if 0
337void account_set_missing_folder(void)
338{
339 PrefsAccount *ap;
340 GList *cur;
341
342 for (cur = account_list; cur != NULL; cur = cur->next) {
343 ap = (PrefsAccount *)cur->data;
344 if ((ap->protocol == A_IMAP4 || ap->protocol == A_NNTP) &&
345 !ap->folder) {
346 Folder *folder;
347
348 if (ap->protocol == A_IMAP4) {
349 folder = folder_new(F_IMAP, ap->account_name,
350 ap->recv_server);
351 } else {
352 folder = folder_new(F_NEWS, ap->account_name,
353 ap->nntp_server);
354 }
355
356 folder->account = ap;
357 ap->folder = REMOTE_FOLDER(folder);
358 folder_add(folder);
359 if (ap->protocol == A_IMAP4) {
360 if (main_window_toggle_online_if_offline
361 (main_window_get())) {
362 folder->klass->create_tree(folder);
363 statusbar_pop_all();
364 }
365 }
366 }
367 }
368}
369#endif
370
371FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
372 SpecialFolderItemType type)
373{
374 FolderItem *item = NULL;
375
376 g_return_val_if_fail(ac_prefs != NULL, NULL);
377
378 switch (type) {
379 case F_INBOX:
380 if (ac_prefs->folder)
381 item = FOLDER(ac_prefs->folder)->inbox;
382 if (!item)
383 item = folder_get_default_inbox();
384 break;
385 case F_OUTBOX:
386 if (ac_prefs->set_sent_folder && ac_prefs->sent_folder) {
387 item = folder_find_item_from_identifier
388 (ac_prefs->sent_folder);
389 }
390 if (!item) {
391 if (ac_prefs->folder)
392 item = FOLDER(ac_prefs->folder)->outbox;
393 if (!item)
394 item = folder_get_default_outbox();
395 }
396 break;
397 case F_DRAFT:
398 if (ac_prefs->set_draft_folder && ac_prefs->draft_folder) {
399 item = folder_find_item_from_identifier
400 (ac_prefs->draft_folder);
401 }
402 if (!item) {
403 if (ac_prefs->folder)
404 item = FOLDER(ac_prefs->folder)->draft;
405 if (!item)
406 item = folder_get_default_draft();
407 }
408 break;
409 case F_QUEUE:
410 if (ac_prefs->set_queue_folder && ac_prefs->queue_folder) {
411 item = folder_find_item_from_identifier
412 (ac_prefs->queue_folder);
413 /* only allow queue-type folder */
414 if (item && item->stype != F_QUEUE)
415 item = NULL;
416 }
417 if (!item) {
418 if (ac_prefs->folder)
419 item = FOLDER(ac_prefs->folder)->queue;
420 if (!item)
421 item = folder_get_default_queue();
422 }
423 break;
424 case F_TRASH:
425 if (ac_prefs->set_trash_folder && ac_prefs->trash_folder) {
426 item = folder_find_item_from_identifier
427 (ac_prefs->trash_folder);
428 }
429 if (!item) {
430 if (ac_prefs->folder)
431 item = FOLDER(ac_prefs->folder)->trash;
432 if (!item)
433 item = folder_get_default_trash();
434 }
435 break;
436 default:
437 break;
438 }
439
440 return item;
441}
442
443void account_destroy(PrefsAccount *ac_prefs)
444{
445 g_return_if_fail(ac_prefs != NULL);
446
447 folder_unref_account_all(ac_prefs);
448
449 account_list = g_list_remove(account_list, ac_prefs);
450 if (cur_account == ac_prefs)
451 cur_account = NULL;
452 prefs_account_free(ac_prefs);
453
454 if (!cur_account && account_list) {
455 cur_account = account_get_default();
456 if (!cur_account) {
457 ac_prefs = (PrefsAccount *)account_list->data;
458 account_set_as_default(ac_prefs);
459 cur_account = ac_prefs;
460 }
461 }
462
463 account_updated();
464}
465
466static guint account_update_lock_count = 0;
467
468void account_update_lock(void)
469{
470 account_update_lock_count++;
471}
472
473void account_update_unlock(void)
474{
475 if (account_update_lock_count > 0)
476 account_update_lock_count--;
477}
478
479void account_updated(void)
480{
481 if (account_update_lock_count)
482 return;
483
484 if (address_table) {
485 g_hash_table_destroy(address_table);
486 address_table = NULL;
487 }
488
489 if (syl_app_get())
490 g_signal_emit_by_name(syl_app_get(), "account-updated");
491}