Statistics
| Revision:

root / src / account.c @ 540

History | View | Annotate | Download (9.1 kB)

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