Statistics
| Revision:

root / libsylph / account.c @ 548

History | View | Annotate | Download (9.1 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program 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
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
39
#define PREFSBUFSIZE                1024
40
41
PrefsAccount *cur_account;
42
43
static GList *account_list = NULL;
44
45
46
void account_read_config_all(void)
47
{
48
        GSList *ac_label_list = NULL, *cur;
49
        gchar *rcpath;
50
        FILE *fp;
51
        gchar buf[PREFSBUFSIZE];
52
        PrefsAccount *ac_prefs;
53
54
        debug_print(_("Reading all config for each account...\n"));
55
56
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
57
        if ((fp = g_fopen(rcpath, "rb")) == NULL) {
58
                if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
59
                g_free(rcpath);
60
                return;
61
        }
62
        g_free(rcpath);
63
64
        while (fgets(buf, sizeof(buf), fp) != NULL) {
65
                if (!strncmp(buf, "[Account: ", 10)) {
66
                        strretchomp(buf);
67
                        memmove(buf, buf + 1, strlen(buf));
68
                        buf[strlen(buf) - 1] = '\0';
69
                        debug_print("Found label: %s\n", buf);
70
                        ac_label_list = g_slist_append(ac_label_list,
71
                                                       g_strdup(buf));
72
                }
73
        }
74
        fclose(fp);
75
76
        /* read config data from file */
77
        cur_account = NULL;
78
        for (cur = ac_label_list; cur != NULL; cur = cur->next) {
79
                ac_prefs = prefs_account_new();
80
                prefs_account_read_config(ac_prefs, (gchar *)cur->data);
81
                account_list = g_list_append(account_list, ac_prefs);
82
                if (ac_prefs->is_default)
83
                        cur_account = ac_prefs;
84
        }
85
        /* if default is not set, assume first account as default */
86
        if (!cur_account && account_list) {
87
                ac_prefs = (PrefsAccount *)account_list->data;
88
                account_set_as_default(ac_prefs);
89
                cur_account = ac_prefs;
90
        }
91
92
        while (ac_label_list) {
93
                g_free(ac_label_list->data);
94
                ac_label_list = g_slist_remove(ac_label_list,
95
                                               ac_label_list->data);
96
        }
97
}
98
99
void account_write_config_all(void)
100
{
101
        prefs_account_write_config_all(account_list);
102
}
103
104
PrefsAccount *account_find_from_smtp_server(const gchar *address,
105
                                            const gchar *smtp_server)
106
{
107
        GList *cur;
108
        PrefsAccount *ac;
109
110
        g_return_val_if_fail(address != NULL, NULL);
111
        g_return_val_if_fail(smtp_server != NULL, NULL);
112
113
        for (cur = account_list; cur != NULL; cur = cur->next) {
114
                ac = (PrefsAccount *)cur->data;
115
                if (!strcmp2(address, ac->address) &&
116
                    !strcmp2(smtp_server, ac->smtp_server))
117
                        return ac;
118
        }
119
120
        return NULL;
121
}
122
123
/*
124
 * account_find_from_address:
125
 * @address: Email address string.
126
 *
127
 * Find a mail (not news) account with the specified email address.
128
 *
129
 * Return value: The found account, or NULL if not found.
130
 */
131
PrefsAccount *account_find_from_address(const gchar *address)
132
{
133
        GList *cur;
134
        PrefsAccount *ac;
135
136
        g_return_val_if_fail(address != NULL, NULL);
137
138
        for (cur = account_list; cur != NULL; cur = cur->next) {
139
                ac = (PrefsAccount *)cur->data;
140
                if (ac->protocol != A_NNTP && ac->address &&
141
                    strcasestr(address, ac->address) != NULL)
142
                        return ac;
143
        }
144
145
        return NULL;
146
}
147
148
PrefsAccount *account_find_from_id(gint id)
149
{
150
        GList *cur;
151
        PrefsAccount *ac;
152
153
        for (cur = account_list; cur != NULL; cur = cur->next) {
154
                ac = (PrefsAccount *)cur->data;
155
                if (id == ac->account_id)
156
                        return ac;
157
        }
158
159
        return NULL;
160
}
161
162
PrefsAccount *account_find_from_item(FolderItem *item)
163
{
164
        PrefsAccount *ac;
165
166
        g_return_val_if_fail(item != NULL, NULL);
167
168
        ac = item->account;
169
        if (!ac) {
170
                FolderItem *cur_item = item->parent;
171
                while (cur_item != NULL) {
172
                        if (cur_item->account && cur_item->ac_apply_sub) {
173
                                ac = cur_item->account;
174
                                break;
175
                        }
176
                        cur_item = cur_item->parent;
177
                }
178
        }
179
        if (!ac)
180
                ac = item->folder->account;
181
182
        return ac;
183
}
184
185
PrefsAccount *account_find_from_message_file(const gchar *file)
186
{
187
        static HeaderEntry hentry[] = {{"From:",                  NULL, FALSE},
188
                                       {"X-Sylpheed-Account-Id:", NULL, FALSE},
189
                                       {"AID:",                          NULL, FALSE},
190
                                       {NULL,                          NULL, FALSE}};
191
192
        enum
193
        {
194
                H_FROM                        = 0,
195
                H_X_SYLPHEED_ACCOUNT_ID = 1,
196
                H_AID                        = 2
197
        };
198
199
        PrefsAccount *ac = NULL;
200
        FILE *fp;
201
        gchar *str;
202
        gchar buf[BUFFSIZE];
203
        gint hnum;
204
205
        g_return_val_if_fail(file != NULL, NULL);
206
207
        if ((fp = g_fopen(file, "rb")) == NULL) {
208
                FILE_OP_ERROR(file, "fopen");
209
                return NULL;
210
        }
211
212
        while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
213
               != -1) {
214
                str = buf + strlen(hentry[hnum].name);
215
                if (hnum == H_FROM)
216
                        ac = account_find_from_address(str);
217
                else if (hnum == H_X_SYLPHEED_ACCOUNT_ID || hnum == H_AID) {
218
                        PrefsAccount *tmp_ac;
219
220
                        tmp_ac = account_find_from_id(atoi(str));
221
                        if (tmp_ac) {
222
                                ac = tmp_ac;
223
                                break;
224
                        }
225
                }
226
        }
227
228
        fclose(fp);
229
        return ac;
230
}
231
232
PrefsAccount *account_find_from_msginfo(MsgInfo *msginfo)
233
{
234
        gchar *file;
235
        PrefsAccount *ac;
236
237
        file = procmsg_get_message_file(msginfo);
238
        ac = account_find_from_message_file(file);
239
        g_free(file);
240
241
        if (!ac && msginfo->folder)
242
                ac = account_find_from_item(msginfo->folder);
243
244
        return ac;
245
}
246
247
void account_foreach(AccountFunc func, gpointer user_data)
248
{
249
        GList *cur;
250
251
        for (cur = account_list; cur != NULL; cur = cur->next)
252
                if (func((PrefsAccount *)cur->data, user_data) != 0)
253
                        return;
254
}
255
256
GList *account_get_list(void)
257
{
258
        return account_list;
259
}
260
261
void account_list_free(void)
262
{
263
        g_list_free(account_list);
264
        account_list = NULL;
265
}
266
267
void account_append(PrefsAccount *ac_prefs)
268
{
269
        account_list = g_list_append(account_list, ac_prefs);
270
}
271
272
void account_set_as_default(PrefsAccount *ac_prefs)
273
{
274
        PrefsAccount *ap;
275
        GList *cur;
276
277
        for (cur = account_list; cur != NULL; cur = cur->next) {
278
                ap = (PrefsAccount *)cur->data;
279
                if (ap->is_default)
280
                        ap->is_default = FALSE;
281
        }
282
283
        ac_prefs->is_default = TRUE;
284
}
285
286
PrefsAccount *account_get_default(void)
287
{
288
        PrefsAccount *ap;
289
        GList *cur;
290
291
        for (cur = account_list; cur != NULL; cur = cur->next) {
292
                ap = (PrefsAccount *)cur->data;
293
                if (ap->is_default)
294
                        return ap;
295
        }
296
297
        return NULL;
298
}
299
300
#if 0
301
void account_set_missing_folder(void)
302
{
303
        PrefsAccount *ap;
304
        GList *cur;
305
306
        for (cur = account_list; cur != NULL; cur = cur->next) {
307
                ap = (PrefsAccount *)cur->data;
308
                if ((ap->protocol == A_IMAP4 || ap->protocol == A_NNTP) &&
309
                    !ap->folder) {
310
                        Folder *folder;
311
312
                        if (ap->protocol == A_IMAP4) {
313
                                folder = folder_new(F_IMAP, ap->account_name,
314
                                                    ap->recv_server);
315
                        } else {
316
                                folder = folder_new(F_NEWS, ap->account_name,
317
                                                    ap->nntp_server);
318
                        }
319
320
                        folder->account = ap;
321
                        ap->folder = REMOTE_FOLDER(folder);
322
                        folder_add(folder);
323
                        if (ap->protocol == A_IMAP4) {
324
                                if (main_window_toggle_online_if_offline
325
                                        (main_window_get())) {
326
                                        folder->klass->create_tree(folder);
327
                                        statusbar_pop_all();
328
                                }
329
                        }
330
                }
331
        }
332
}
333
#endif
334
335
FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
336
                                       SpecialFolderItemType type)
337
{
338
        FolderItem *item = NULL;
339
340
        g_return_val_if_fail(ac_prefs != NULL, NULL);
341
342
        switch (type) {
343
        case F_INBOX:
344
                if (ac_prefs->folder)
345
                        item = FOLDER(ac_prefs->folder)->inbox;
346
                if (!item)
347
                        item = folder_get_default_inbox();
348
                break;
349
        case F_OUTBOX:
350
                if (ac_prefs->set_sent_folder && ac_prefs->sent_folder) {
351
                        item = folder_find_item_from_identifier
352
                                (ac_prefs->sent_folder);
353
                }
354
                if (!item) {
355
                        if (ac_prefs->folder)
356
                                item = FOLDER(ac_prefs->folder)->outbox;
357
                        if (!item)
358
                                item = folder_get_default_outbox();
359
                }
360
                break;
361
        case F_DRAFT:
362
                if (ac_prefs->set_draft_folder && ac_prefs->draft_folder) {
363
                        item = folder_find_item_from_identifier
364
                                (ac_prefs->draft_folder);
365
                }
366
                if (!item) {
367
                        if (ac_prefs->folder)
368
                                item = FOLDER(ac_prefs->folder)->draft;
369
                        if (!item)
370
                                item = folder_get_default_draft();
371
                }
372
                break;
373
        case F_QUEUE:
374
                if (ac_prefs->folder)
375
                        item = FOLDER(ac_prefs->folder)->queue;
376
                if (!item)
377
                        item = folder_get_default_queue();
378
                break;
379
        case F_TRASH:
380
                if (ac_prefs->set_trash_folder && ac_prefs->trash_folder) {
381
                        item = folder_find_item_from_identifier
382
                                (ac_prefs->trash_folder);
383
                }
384
                if (!item) {
385
                        if (ac_prefs->folder)
386
                                item = FOLDER(ac_prefs->folder)->trash;
387
                        if (!item)
388
                                item = folder_get_default_trash();
389
                }
390
                break;
391
        default:
392
                break;
393
        }
394
395
        return item;
396
}
397
398
void account_destroy(PrefsAccount *ac_prefs)
399
{
400
        g_return_if_fail(ac_prefs != NULL);
401
402
        folder_unref_account_all(ac_prefs);
403
404
        prefs_account_free(ac_prefs);
405
        account_list = g_list_remove(account_list, ac_prefs);
406
407
        if (cur_account == ac_prefs) cur_account = NULL;
408
        if (!cur_account && account_list) {
409
                cur_account = account_get_default();
410
                if (!cur_account) {
411
                        ac_prefs = (PrefsAccount *)account_list->data;
412
                        account_set_as_default(ac_prefs);
413
                        cur_account = ac_prefs;
414
                }
415
        }
416
}