Statistics
| Revision:

root / src / inc.c @ 1655

History | View | Annotate | Download (40.5 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2007 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 <gtk/gtkmain.h>
29
#include <gtk/gtkwindow.h>
30
#include <gtk/gtksignal.h>
31
#include <gtk/gtkprogressbar.h>
32
#include <gtk/gtkstock.h>
33
#include <stdio.h>
34
#include <unistd.h>
35
#include <string.h>
36
37
#include "main.h"
38
#include "inc.h"
39
#include "mainwindow.h"
40
#include "folderview.h"
41
#include "summaryview.h"
42
#include "prefs_common.h"
43
#include "prefs_account.h"
44
#include "account.h"
45
#include "procmsg.h"
46
#include "socket.h"
47
#include "ssl.h"
48
#include "pop.h"
49
#include "recv.h"
50
#include "mbox.h"
51
#include "utils.h"
52
#include "gtkutils.h"
53
#include "statusbar.h"
54
#include "manage_window.h"
55
#include "stock_pixmap.h"
56
#include "progressdialog.h"
57
#include "alertpanel.h"
58
#include "trayicon.h"
59
#include "filter.h"
60
#include "folder.h"
61
62
static GList *inc_dialog_list = NULL;
63
64
static guint inc_lock_count = 0;
65
66
static GdkPixbuf *current_pixbuf;
67
static GdkPixbuf *error_pixbuf;
68
static GdkPixbuf *ok_pixbuf;
69
70
#define MSGBUFSIZE        8192
71
72
static void inc_finished                (MainWindow                *mainwin,
73
                                         gint                         new_messages);
74
75
static gint inc_remote_account_mail        (MainWindow                *mainwin,
76
                                         PrefsAccount                *account);
77
static gint inc_account_mail_real        (MainWindow                *mainwin,
78
                                         PrefsAccount                *account);
79
80
static IncProgressDialog *inc_progress_dialog_create
81
                                        (gboolean                 autocheck);
82
static void inc_progress_dialog_set_list(IncProgressDialog        *inc_dialog);
83
static void inc_progress_dialog_destroy        (IncProgressDialog        *inc_dialog);
84
85
static IncSession *inc_session_new        (PrefsAccount                *account);
86
static void inc_session_destroy                (IncSession                *session);
87
static gint inc_start                        (IncProgressDialog        *inc_dialog);
88
static IncState inc_pop3_session_do        (IncSession                *session);
89
90
static void inc_progress_dialog_update        (IncProgressDialog        *inc_dialog,
91
                                         IncSession                *inc_session);
92
93
static void inc_progress_dialog_set_label
94
                                        (IncProgressDialog        *inc_dialog,
95
                                         IncSession                *inc_session);
96
static void inc_progress_dialog_set_progress
97
                                        (IncProgressDialog        *inc_dialog,
98
                                         IncSession                *inc_session);
99
100
static void inc_update_folderview        (IncProgressDialog        *inc_dialog,
101
                                         IncSession                *inc_session);
102
103
static void inc_progress_dialog_update_periodic
104
                                        (IncProgressDialog        *inc_dialog,
105
                                         IncSession                *inc_session);
106
static void inc_update_folderview_periodic
107
                                        (IncProgressDialog        *inc_dialog,
108
                                         IncSession                *inc_session);
109
110
static gint inc_recv_data_progressive        (Session        *session,
111
                                         guint                 cur_len,
112
                                         guint                 total_len,
113
                                         gpointer         data);
114
static gint inc_recv_data_finished        (Session        *session,
115
                                         guint                 len,
116
                                         gpointer         data);
117
static gint inc_recv_message                (Session        *session,
118
                                         const gchar        *msg,
119
                                         gpointer         data);
120
static gint inc_drop_message                (Pop3Session        *session,
121
                                         const gchar        *file);
122
123
static void inc_put_error                (IncState         istate,
124
                                         const gchar        *msg);
125
126
static void inc_cancel_cb                (GtkWidget        *widget,
127
                                         gpointer         data);
128
static gint inc_dialog_delete_cb        (GtkWidget        *widget,
129
                                         GdkEventAny        *event,
130
                                         gpointer         data);
131
132
static gint inc_spool                        (void);
133
static gint get_spool                        (FolderItem        *dest,
134
                                         const gchar        *mbox);
135
136
static void inc_autocheck_timer_set_interval        (guint                 interval);
137
static gint inc_autocheck_func                        (gpointer         data);
138
139
/**
140
 * inc_finished:
141
 * @mainwin: Main window.
142
 * @new_messages: Number of received messages.
143
 * 
144
 * Update the folder view and the summary view after receiving
145
 * messages.  If @new_messages is 0, this function avoids unneeded
146
 * updating.
147
 **/
148
static void inc_finished(MainWindow *mainwin, gint new_messages)
149
{
150
        FolderItem *item;
151
152
        debug_print("inc_finished(): %d new message(s)\n", new_messages);
153
154
        if (prefs_common.scan_all_after_inc)
155
                new_messages += folderview_check_new(NULL);
156
157
        if (new_messages > 0) {
158
                gchar buf[1024];
159
160
                g_snprintf(buf, sizeof(buf), _("Sylpheed: %d new messages"),
161
                           new_messages);
162
                trayicon_set_tooltip(buf);
163
                trayicon_set_notify(TRUE);
164
        } else {
165
#if 0
166
                trayicon_set_tooltip(NULL);
167
                trayicon_set_notify(FALSE);
168
#endif
169
        }
170
171
        if (new_messages <= 0 && !prefs_common.scan_all_after_inc) return;
172
173
        if (prefs_common.open_inbox_on_inc) {
174
                item = cur_account && cur_account->inbox
175
                        ? folder_find_item_from_identifier(cur_account->inbox)
176
                        : folder_get_default_inbox();
177
                folderview_unselect(mainwin->folderview);
178
                folderview_select(mainwin->folderview, item);
179
        } else if (prefs_common.scan_all_after_inc) {
180
                item = mainwin->summaryview->folder_item;
181
                if (item)
182
                        folderview_update_item(item, TRUE);
183
        }
184
185
        if (new_messages > 0 &&
186
            prefs_common.enable_newmsg_notify &&
187
            prefs_common.newmsg_notify_cmd) {
188
                gchar buf[1024];
189
190
                if (str_find_format_times
191
                        (prefs_common.newmsg_notify_cmd, 'd') == 1)
192
                        g_snprintf(buf, sizeof(buf),
193
                                   prefs_common.newmsg_notify_cmd,
194
                                   new_messages);
195
                else
196
                        strncpy2(buf, prefs_common.newmsg_notify_cmd,
197
                                 sizeof(buf));
198
                execute_command_line(buf, TRUE);
199
        }
200
}
201
202
void inc_mail(MainWindow *mainwin)
203
{
204
        gint new_msgs = 0;
205
206
        if (inc_lock_count) return;
207
        if (inc_is_active()) return;
208
209
        if (!main_window_toggle_online_if_offline(mainwin))
210
                return;
211
212
        inc_autocheck_timer_remove();
213
        summary_write_cache(mainwin->summaryview);
214
        main_window_lock(mainwin);
215
216
        if (prefs_common.use_extinc && prefs_common.extinc_cmd) {
217
                /* external incorporating program */
218
                if (execute_command_line(prefs_common.extinc_cmd, FALSE) != 0) {
219
                        main_window_unlock(mainwin);
220
                        inc_autocheck_timer_set();
221
                        return;
222
                }
223
224
                if (prefs_common.inc_local)
225
                        new_msgs = inc_spool();
226
        } else {
227
                if (prefs_common.inc_local) {
228
                        new_msgs = inc_spool();
229
                        if (new_msgs < 0)
230
                                new_msgs = 0;
231
                }
232
233
                new_msgs += inc_account_mail_real(mainwin, cur_account);
234
        }
235
236
        inc_finished(mainwin, new_msgs);
237
        main_window_unlock(mainwin);
238
        inc_autocheck_timer_set();
239
}
240
241
static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account)
242
{
243
        FolderItem *item = mainwin->summaryview->folder_item;
244
        gint new_msgs = 0;
245
        gboolean update_summary = FALSE;
246
247
        g_return_val_if_fail(account->folder != NULL, 0);
248
249
        if (account->protocol == A_IMAP4 &&
250
            account->imap_filter_inbox_on_recv) {
251
                FolderItem *inbox = FOLDER(account->folder)->inbox;
252
                GSList *mlist, *cur;
253
                FilterInfo *fltinfo;
254
                gint n_filtered = 0;
255
256
                debug_print("inc_remote_account_mail(): filtering IMAP4 INBOX\n");
257
                mlist = folder_item_get_uncached_msg_list(inbox);
258
                debug_print("inc_remote_account_mail(): uncached messages: %d\n", g_slist_length(mlist));
259
260
                for (cur = mlist; cur != NULL; cur = cur->next) {
261
                        MsgInfo *msginfo = (MsgInfo *)cur->data;
262
263
                        fltinfo = filter_info_new();
264
                        fltinfo->account = account;
265
                        fltinfo->flags = msginfo->flags;
266
267
                        if (prefs_common.enable_junk &&
268
                            prefs_common.filter_junk_on_recv &&
269
                            prefs_common.filter_junk_before) {
270
                                filter_apply_msginfo
271
                                        (prefs_common.manual_junk_fltlist,
272
                                         msginfo, fltinfo);
273
                        }
274
275
                        if (!fltinfo->drop_done) {
276
                                filter_apply_msginfo(prefs_common.fltlist,
277
                                                     msginfo, fltinfo);
278
                        }
279
280
                        if (!fltinfo->drop_done &&
281
                            prefs_common.enable_junk &&
282
                            prefs_common.filter_junk_on_recv &&
283
                            !prefs_common.filter_junk_before) {
284
                                filter_apply_msginfo
285
                                        (prefs_common.manual_junk_fltlist,
286
                                         msginfo, fltinfo);
287
                        }
288
289
                        if (msginfo->flags.perm_flags !=
290
                            fltinfo->flags.perm_flags) {
291
                                msginfo->flags = fltinfo->flags;
292
                                inbox->mark_dirty = TRUE;
293
                                if (fltinfo->actions[FLT_ACTION_MARK])
294
                                        imap_msg_set_perm_flags
295
                                                (msginfo, MSG_MARKED);
296
                                if (fltinfo->actions[FLT_ACTION_MARK_READ])
297
                                        imap_msg_unset_perm_flags
298
                                                (msginfo, MSG_NEW|MSG_UNREAD);
299
                        }
300
301
                        if (fltinfo->actions[FLT_ACTION_MOVE] &&
302
                            fltinfo->move_dest) {
303
                                folder_item_move_msg
304
                                        (fltinfo->move_dest, msginfo);
305
                                if (account->imap_check_inbox_only ||
306
                                    fltinfo->move_dest->folder !=
307
                                    inbox->folder) {
308
                                        if (MSG_IS_NEW(fltinfo->flags) ||
309
                                            MSG_IS_UNREAD(fltinfo->flags))
310
                                                ++new_msgs;
311
                                }
312
                        } else if (fltinfo->actions[FLT_ACTION_DELETE])
313
                                folder_item_remove_msg(inbox, msginfo);
314
                        else if (MSG_IS_NEW(msginfo->flags) ||
315
                                 MSG_IS_UNREAD(msginfo->flags))
316
                                ++new_msgs;
317
318
                        if (fltinfo->drop_done)
319
                                ++n_filtered;
320
321
                        filter_info_free(fltinfo);
322
                }
323
324
                procmsg_msg_list_free(mlist);
325
326
                debug_print("inc_remote_account_mail(): INBOX: %d new, %d filtered\n",
327
                            new_msgs, n_filtered);
328
329
                if (!prefs_common.scan_all_after_inc && item != NULL &&
330
                    inbox == item)
331
                        update_summary = TRUE;
332
        }
333
334
        if (account->protocol == A_IMAP4 && account->imap_check_inbox_only) {
335
                FolderItem *inbox = FOLDER(account->folder)->inbox;
336
337
                new_msgs += folderview_check_new_item(inbox);
338
                if (!prefs_common.scan_all_after_inc && item != NULL &&
339
                    inbox == item)
340
                        update_summary = TRUE;
341
        } else {
342
                new_msgs += folderview_check_new(FOLDER(account->folder));
343
                if (!prefs_common.scan_all_after_inc && item != NULL &&
344
                    FOLDER(account->folder) == item->folder)
345
                        update_summary = TRUE;
346
        }
347
348
        if (update_summary)
349
                folderview_update_item(item, TRUE);
350
        folderview_update_all_updated(FALSE);
351
352
        return new_msgs;
353
}
354
355
static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account)
356
{
357
        IncProgressDialog *inc_dialog;
358
        IncSession *session;
359
360
        if (account->protocol == A_IMAP4 || account->protocol == A_NNTP)
361
                return inc_remote_account_mail(mainwin, account);
362
363
        session = inc_session_new(account);
364
        if (!session) return 0;
365
366
        inc_dialog = inc_progress_dialog_create(FALSE);
367
        inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session);
368
        inc_dialog->mainwin = mainwin;
369
        inc_progress_dialog_set_list(inc_dialog);
370
371
        main_window_set_toolbar_sensitive(mainwin);
372
        main_window_set_menu_sensitive(mainwin);
373
374
        return inc_start(inc_dialog);
375
}
376
377
gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
378
{
379
        gint new_msgs;
380
381
        if (inc_lock_count) return 0;
382
        if (inc_is_active()) return 0;
383
384
        if (!main_window_toggle_online_if_offline(mainwin))
385
                return 0;
386
387
        inc_autocheck_timer_remove();
388
        summary_write_cache(mainwin->summaryview);
389
        main_window_lock(mainwin);
390
391
        new_msgs = inc_account_mail_real(mainwin, account);
392
393
        inc_finished(mainwin, new_msgs);
394
        main_window_unlock(mainwin);
395
        inc_autocheck_timer_set();
396
397
        return new_msgs;
398
}
399
400
void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck)
401
{
402
        GList *list, *queue_list = NULL;
403
        IncProgressDialog *inc_dialog;
404
        gint new_msgs = 0;
405
406
        if (inc_lock_count) return;
407
        if (inc_is_active()) return;
408
409
        if (!main_window_toggle_online_if_offline(mainwin))
410
                return;
411
412
        inc_autocheck_timer_remove();
413
        summary_write_cache(mainwin->summaryview);
414
        main_window_lock(mainwin);
415
416
        if (prefs_common.inc_local) {
417
                new_msgs = inc_spool();
418
                if (new_msgs < 0)
419
                        new_msgs = 0;
420
        }
421
422
        /* check IMAP4 / News folders */
423
        for (list = account_get_list(); list != NULL; list = list->next) {
424
                PrefsAccount *account = list->data;
425
                if ((account->protocol == A_IMAP4 ||
426
                     account->protocol == A_NNTP) && account->recv_at_getall)
427
                        new_msgs += inc_remote_account_mail(mainwin, account);
428
        }
429
430
        /* check POP3 accounts */
431
        for (list = account_get_list(); list != NULL; list = list->next) {
432
                IncSession *session;
433
                PrefsAccount *account = list->data;
434
435
                if (account->recv_at_getall) {
436
                        session = inc_session_new(account);
437
                        if (session)
438
                                queue_list = g_list_append(queue_list, session);
439
                }
440
        }
441
442
        if (queue_list) {
443
                inc_dialog = inc_progress_dialog_create(autocheck);
444
                inc_dialog->queue_list = queue_list;
445
                inc_dialog->mainwin = mainwin;
446
                inc_progress_dialog_set_list(inc_dialog);
447
448
                main_window_set_toolbar_sensitive(mainwin);
449
                main_window_set_menu_sensitive(mainwin);
450
451
                new_msgs += inc_start(inc_dialog);
452
        }
453
454
        inc_finished(mainwin, new_msgs);
455
        main_window_unlock(mainwin);
456
        inc_autocheck_timer_set();
457
}
458
459
gint inc_pop_before_smtp(PrefsAccount *account)
460
{
461
        MainWindow *mainwin;
462
        IncProgressDialog *inc_dialog;
463
        IncSession *session;
464
465
        if (inc_lock_count) return -1;
466
467
        mainwin = main_window_get();
468
469
        if (!main_window_toggle_online_if_offline(mainwin))
470
                return -1;
471
472
        inc_autocheck_timer_remove();
473
        main_window_lock(mainwin);
474
475
        session = inc_session_new(account);
476
        if (!session) return -1;
477
        POP3_SESSION(session->session)->auth_only = TRUE;
478
479
        inc_dialog = inc_progress_dialog_create(FALSE);
480
        gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
481
                             _("Authenticating with POP3"));
482
        inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session);
483
        inc_dialog->mainwin = mainwin;
484
        inc_progress_dialog_set_list(inc_dialog);
485
        inc_dialog->show_dialog = TRUE;
486
487
        main_window_set_toolbar_sensitive(mainwin);
488
        main_window_set_menu_sensitive(mainwin);
489
490
        inc_start(inc_dialog);
491
492
        main_window_unlock(mainwin);
493
        inc_autocheck_timer_set();
494
495
        return 0;
496
}
497
498
static IncProgressDialog *inc_progress_dialog_create(gboolean autocheck)
499
{
500
        IncProgressDialog *dialog;
501
        ProgressDialog *progress;
502
503
        dialog = g_new0(IncProgressDialog, 1);
504
505
        progress = progress_dialog_create();
506
        gtk_window_set_title(GTK_WINDOW(progress->window),
507
                             _("Retrieving new messages"));
508
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
509
                         G_CALLBACK(inc_cancel_cb), dialog);
510
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
511
                         G_CALLBACK(inc_dialog_delete_cb), dialog);
512
        /* manage_window_set_transient(GTK_WINDOW(progress->window)); */
513
514
        progress_dialog_set_value(progress, 0.0);
515
516
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_COMPLETE, &ok_pixbuf);
517
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_CONTINUE,
518
                         &current_pixbuf);
519
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_ERROR, &error_pixbuf);
520
521
        if (prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS ||
522
            (prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL &&
523
             !autocheck)) {
524
                dialog->show_dialog = TRUE;
525
                gtk_widget_show_now(progress->window);
526
        }
527
528
        dialog->dialog = progress;
529
        g_get_current_time(&dialog->progress_tv);
530
        g_get_current_time(&dialog->folder_tv);
531
        dialog->queue_list = NULL;
532
        dialog->cur_row = 0;
533
534
        inc_dialog_list = g_list_append(inc_dialog_list, dialog);
535
536
        return dialog;
537
}
538
539
static void inc_progress_dialog_set_list(IncProgressDialog *inc_dialog)
540
{
541
        GList *list;
542
543
        for (list = inc_dialog->queue_list; list != NULL; list = list->next) {
544
                IncSession *session = list->data;
545
                Pop3Session *pop3_session = POP3_SESSION(session->session);
546
547
                session->data = inc_dialog;
548
                progress_dialog_append(inc_dialog->dialog, NULL,
549
                                       pop3_session->ac_prefs->account_name,
550
                                       _("Standby"), NULL);
551
        }
552
}
553
554
static void inc_progress_dialog_clear(IncProgressDialog *inc_dialog)
555
{
556
        progress_dialog_set_value(inc_dialog->dialog, 0.0);
557
        progress_dialog_set_label(inc_dialog->dialog, "");
558
        main_window_progress_off(inc_dialog->mainwin);
559
}
560
561
static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
562
{
563
        g_return_if_fail(inc_dialog != NULL);
564
565
        inc_dialog_list = g_list_remove(inc_dialog_list, inc_dialog);
566
567
        manage_window_destroy(inc_dialog->dialog->window, NULL);
568
569
        main_window_progress_off(inc_dialog->mainwin);
570
        progress_dialog_destroy(inc_dialog->dialog);
571
572
        g_free(inc_dialog);
573
}
574
575
static IncSession *inc_session_new(PrefsAccount *account)
576
{
577
        IncSession *session;
578
579
        g_return_val_if_fail(account != NULL, NULL);
580
581
        if (account->protocol != A_POP3)
582
                return NULL;
583
        if (!account->recv_server || !account->userid)
584
                return NULL;
585
586
        session = g_new0(IncSession, 1);
587
588
        session->session = pop3_session_new(account);
589
        session->session->data = session;
590
        POP3_SESSION(session->session)->drop_message = inc_drop_message;
591
        session_set_recv_message_notify(session->session,
592
                                        inc_recv_message, session);
593
        session_set_recv_data_progressive_notify(session->session,
594
                                                 inc_recv_data_progressive,
595
                                                 session);
596
        session_set_recv_data_notify(session->session,
597
                                     inc_recv_data_finished, session);
598
599
        session->inc_state = INC_SUCCESS;
600
601
        session->folder_table = g_hash_table_new(NULL, NULL);
602
        session->tmp_folder_table = g_hash_table_new(NULL, NULL);
603
604
        session->cur_total_bytes = 0;
605
        session->new_msgs = 0;
606
607
        return session;
608
}
609
610
static void inc_session_destroy(IncSession *session)
611
{
612
        g_return_if_fail(session != NULL);
613
614
        session_destroy(session->session);
615
        g_hash_table_destroy(session->folder_table);
616
        g_hash_table_destroy(session->tmp_folder_table);
617
        g_free(session);
618
}
619
620
static gint inc_start(IncProgressDialog *inc_dialog)
621
{
622
        IncSession *session;
623
        GList *qlist;
624
        Pop3Session *pop3_session;
625
        IncState inc_state;
626
        gint error_num = 0;
627
        gint new_msgs = 0;
628
        gchar *msg;
629
        gchar *fin_msg;
630
631
        qlist = inc_dialog->queue_list;
632
        while (qlist != NULL) {
633
                GList *next = qlist->next;
634
635
                session = qlist->data;
636
                if (session->inc_state == INC_CANCEL) {
637
                        qlist = next;
638
                        continue;
639
                }
640
641
                pop3_session = POP3_SESSION(session->session); 
642
                pop3_session->user = g_strdup(pop3_session->ac_prefs->userid);
643
                if (pop3_session->ac_prefs->passwd)
644
                        pop3_session->pass =
645
                                g_strdup(pop3_session->ac_prefs->passwd);
646
                else if (pop3_session->ac_prefs->tmp_pass)
647
                        pop3_session->pass =
648
                                g_strdup(pop3_session->ac_prefs->tmp_pass);
649
                else {
650
                        gchar *pass;
651
652
                        if (inc_dialog->show_dialog)
653
                                manage_window_focus_in
654
                                        (inc_dialog->dialog->window,
655
                                         NULL, NULL);
656
657
                        pass = input_query_password
658
                                (pop3_session->ac_prefs->recv_server,
659
                                 pop3_session->user);
660
661
                        if (inc_dialog->show_dialog)
662
                                manage_window_focus_out
663
                                        (inc_dialog->dialog->window,
664
                                         NULL, NULL);
665
666
                        if (pass) {
667
                                pop3_session->ac_prefs->tmp_pass =
668
                                        g_strdup(pass);
669
                                pop3_session->pass = pass;
670
                        }
671
                }
672
673
                qlist = next;
674
        }
675
676
#define SET_PIXMAP_AND_TEXT(pixbuf, str)                                \
677
{                                                                        \
678
        progress_dialog_set_row_pixbuf(inc_dialog->dialog,                \
679
                                       inc_dialog->cur_row, pixbuf);        \
680
        progress_dialog_set_row_status(inc_dialog->dialog,                \
681
                                       inc_dialog->cur_row, str);        \
682
}
683
684
        for (; inc_dialog->queue_list != NULL; inc_dialog->cur_row++) {
685
                session = inc_dialog->queue_list->data;
686
                pop3_session = POP3_SESSION(session->session);
687
688
                if (session->inc_state == INC_CANCEL ||
689
                    pop3_session->pass == NULL) {
690
                        SET_PIXMAP_AND_TEXT(ok_pixbuf, _("Cancelled"));
691
                        inc_session_destroy(session);
692
                        inc_dialog->queue_list =
693
                                g_list_remove(inc_dialog->queue_list, session);
694
                        continue;
695
                }
696
697
                inc_progress_dialog_clear(inc_dialog);
698
                progress_dialog_scroll_to_row(inc_dialog->dialog,
699
                                              inc_dialog->cur_row);
700
701
                SET_PIXMAP_AND_TEXT(current_pixbuf, _("Retrieving"));
702
703
                /* begin POP3 session */
704
                inc_state = inc_pop3_session_do(session);
705
706
                switch (inc_state) {
707
                case INC_SUCCESS:
708
                        if (pop3_session->cur_total_num > 0)
709
                                msg = g_strdup_printf
710
                                        (_("Done (%d message(s) (%s) received)"),
711
                                         pop3_session->cur_total_num,
712
                                         to_human_readable(pop3_session->cur_total_recv_bytes));
713
                        else
714
                                msg = g_strdup_printf(_("Done (no new messages)"));
715
                        SET_PIXMAP_AND_TEXT(ok_pixbuf, msg);
716
                        g_free(msg);
717
                        break;
718
                case INC_CONNECT_ERROR:
719
                        SET_PIXMAP_AND_TEXT(error_pixbuf,
720
                                            _("Connection failed"));
721
                        break;
722
                case INC_AUTH_FAILED:
723
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Auth failed"));
724
                        break;
725
                case INC_LOCKED:
726
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Locked"));
727
                        break;
728
                case INC_ERROR:
729
                case INC_NO_SPACE:
730
                case INC_IO_ERROR:
731
                case INC_SOCKET_ERROR:
732
                case INC_EOF:
733
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Error"));
734
                        break;
735
                case INC_TIMEOUT:
736
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Timeout"));
737
                        break;
738
                case INC_CANCEL:
739
                        SET_PIXMAP_AND_TEXT(ok_pixbuf, _("Cancelled"));
740
                        break;
741
                default:
742
                        break;
743
                }
744
745
                new_msgs += session->new_msgs;
746
747
                if (!prefs_common.scan_all_after_inc) {
748
                        folder_item_scan_foreach(session->folder_table);
749
                        folderview_update_item_foreach
750
                                (session->folder_table,
751
                                 !prefs_common.open_inbox_on_inc);
752
                }
753
754
                if (pop3_session->error_val == PS_AUTHFAIL &&
755
                    pop3_session->ac_prefs->tmp_pass) {
756
                        g_free(pop3_session->ac_prefs->tmp_pass);
757
                        pop3_session->ac_prefs->tmp_pass = NULL;
758
                }
759
760
                pop3_write_uidl_list(pop3_session);
761
762
                if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) {
763
                        error_num++;
764
                        if (inc_dialog->show_dialog)
765
                                manage_window_focus_in
766
                                        (inc_dialog->dialog->window,
767
                                         NULL, NULL);
768
                        inc_put_error(inc_state, pop3_session->error_msg);
769
                        if (inc_dialog->show_dialog)
770
                                manage_window_focus_out
771
                                        (inc_dialog->dialog->window,
772
                                         NULL, NULL);
773
                        if (inc_state == INC_NO_SPACE ||
774
                            inc_state == INC_IO_ERROR)
775
                                break;
776
                }
777
778
                inc_session_destroy(session);
779
                inc_dialog->queue_list =
780
                        g_list_remove(inc_dialog->queue_list, session);
781
        }
782
783
#undef SET_PIXMAP_AND_TEXT
784
785
        if (new_msgs > 0)
786
                fin_msg = g_strdup_printf(_("Finished (%d new message(s))"),
787
                                          new_msgs);
788
        else
789
                fin_msg = g_strdup_printf(_("Finished (no new messages)"));
790
791
        progress_dialog_set_label(inc_dialog->dialog, fin_msg);
792
793
#if 0
794
        if (error_num && !prefs_common.no_recv_err_panel) {
795
                if (inc_dialog->show_dialog)
796
                        manage_window_focus_in(inc_dialog->dialog->window,
797
                                               NULL, NULL);
798
                alertpanel_error(_("Some errors occurred while getting mail."));
799
                if (inc_dialog->show_dialog)
800
                        manage_window_focus_out(inc_dialog->dialog->window,
801
                                                NULL, NULL);
802
        }
803
#endif
804
805
        while (inc_dialog->queue_list != NULL) {
806
                session = inc_dialog->queue_list->data;
807
                inc_session_destroy(session);
808
                inc_dialog->queue_list =
809
                        g_list_remove(inc_dialog->queue_list, session);
810
        }
811
812
        if (prefs_common.close_recv_dialog || !inc_dialog->show_dialog)
813
                inc_progress_dialog_destroy(inc_dialog);
814
        else {
815
                gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
816
                                     fin_msg);
817
                gtk_button_set_label(GTK_BUTTON(inc_dialog->dialog->cancel_btn),
818
                                     GTK_STOCK_CLOSE);
819
        }
820
821
        g_free(fin_msg);
822
823
        return new_msgs;
824
}
825
826
static IncState inc_pop3_session_do(IncSession *session)
827
{
828
        Pop3Session *pop3_session = POP3_SESSION(session->session);
829
        IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data;
830
        gchar *server;
831
        gushort port;
832
        gchar *buf;
833
834
        debug_print(_("getting new messages of account %s...\n"),
835
                    pop3_session->ac_prefs->account_name);
836
837
        if (pop3_session->auth_only)
838
                buf = g_strdup_printf(_("%s: Authenticating with POP3"),
839
                                      pop3_session->ac_prefs->recv_server);
840
        else
841
                buf = g_strdup_printf(_("%s: Retrieving new messages"),
842
                                      pop3_session->ac_prefs->recv_server);
843
        gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf);
844
        g_free(buf);
845
846
        server = pop3_session->ac_prefs->recv_server;
847
#if USE_SSL
848
        port = pop3_session->ac_prefs->set_popport ?
849
                pop3_session->ac_prefs->popport :
850
                pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110;
851
        SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop;
852
        if (pop3_session->ac_prefs->ssl_pop != SSL_NONE)
853
                SESSION(pop3_session)->nonblocking =
854
                        pop3_session->ac_prefs->use_nonblocking_ssl;
855
#else
856
        port = pop3_session->ac_prefs->set_popport ?
857
                pop3_session->ac_prefs->popport : 110;
858
#endif
859
860
        buf = g_strdup_printf(_("Connecting to POP3 server: %s..."), server);
861
        log_message("%s\n", buf);
862
        progress_dialog_set_label(inc_dialog->dialog, buf);
863
        g_free(buf);
864
865
        session_set_timeout(SESSION(pop3_session),
866
                            prefs_common.io_timeout_secs * 1000);
867
868
        GTK_EVENTS_FLUSH();
869
870
        if (session_connect(SESSION(pop3_session), server, port) < 0) {
871
                log_warning(_("Can't connect to POP3 server: %s:%d\n"),
872
                            server, port);
873
                session->inc_state = INC_CONNECT_ERROR;
874
                statusbar_pop_all();
875
                return INC_CONNECT_ERROR;
876
        }
877
878
        while (session_is_connected(SESSION(pop3_session)) &&
879
               session->inc_state != INC_CANCEL)
880
                gtk_main_iteration();
881
882
        if (session->inc_state == INC_SUCCESS) {
883
                switch (pop3_session->error_val) {
884
                case PS_SUCCESS:
885
                        switch (SESSION(pop3_session)->state) {
886
                        case SESSION_ERROR:
887
                                if (pop3_session->state == POP3_READY)
888
                                        session->inc_state = INC_CONNECT_ERROR;
889
                                else
890
                                        session->inc_state = INC_ERROR;
891
                                break;
892
                        case SESSION_EOF:
893
                                session->inc_state = INC_EOF;
894
                                break;
895
                        case SESSION_TIMEOUT:
896
                                session->inc_state = INC_TIMEOUT;
897
                                break;
898
                        default:
899
                                session->inc_state = INC_SUCCESS;
900
                                break;
901
                        }
902
                        break;
903
                case PS_AUTHFAIL:
904
                        session->inc_state = INC_AUTH_FAILED;
905
                        break;
906
                case PS_IOERR:
907
                        session->inc_state = INC_IO_ERROR;
908
                        break;
909
                case PS_SOCKET:
910
                        session->inc_state = INC_SOCKET_ERROR;
911
                        break;
912
                case PS_LOCKBUSY:
913
                        session->inc_state = INC_LOCKED;
914
                        break;
915
                default:
916
                        session->inc_state = INC_ERROR;
917
                        break;
918
                }
919
        }
920
921
        session_disconnect(SESSION(pop3_session));
922
        statusbar_pop_all();
923
924
        return session->inc_state;
925
}
926
927
static void inc_progress_dialog_update(IncProgressDialog *inc_dialog,
928
                                       IncSession *inc_session)
929
{
930
        inc_progress_dialog_set_label(inc_dialog, inc_session);
931
        inc_progress_dialog_set_progress(inc_dialog, inc_session);
932
}
933
934
static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
935
                                          IncSession *inc_session)
936
{
937
        ProgressDialog *dialog = inc_dialog->dialog;
938
        Pop3Session *session;
939
940
        g_return_if_fail(inc_session != NULL);
941
942
        session = POP3_SESSION(inc_session->session);
943
944
        switch (session->state) {
945
        case POP3_GREETING:
946
                break;
947
        case POP3_GETAUTH_USER:
948
        case POP3_GETAUTH_PASS:
949
        case POP3_GETAUTH_APOP:
950
                progress_dialog_set_label(dialog, _("Authenticating..."));
951
                statusbar_print_all(_("Retrieving messages from %s..."),
952
                                    SESSION(session)->server);
953
                break;
954
        case POP3_GETRANGE_STAT:
955
                progress_dialog_set_label
956
                        (dialog, _("Getting the number of new messages (STAT)..."));
957
                break;
958
        case POP3_GETRANGE_LAST:
959
                progress_dialog_set_label
960
                        (dialog, _("Getting the number of new messages (LAST)..."));
961
                break;
962
        case POP3_GETRANGE_UIDL:
963
                progress_dialog_set_label
964
                        (dialog, _("Getting the number of new messages (UIDL)..."));
965
                break;
966
        case POP3_GETSIZE_LIST:
967
                progress_dialog_set_label
968
                        (dialog, _("Getting the size of messages (LIST)..."));
969
                break;
970
        case POP3_RETR:
971
        case POP3_RETR_RECV:
972
                break;
973
        case POP3_DELETE:
974
#if 0
975
                if (session->msg[session->cur_msg].recv_time <
976
                        session->current_time) {
977
                        gchar buf[MSGBUFSIZE];
978
                        g_snprintf(buf, sizeof(buf), _("Deleting message %d"),
979
                                   session->cur_msg);
980
                        progress_dialog_set_label(dialog, buf);
981
                }
982
#endif
983
                break;
984
        case POP3_LOGOUT:
985
                progress_dialog_set_label(dialog, _("Quitting"));
986
                break;
987
        default:
988
                break;
989
        }
990
}
991
992
static void inc_progress_dialog_set_progress(IncProgressDialog *inc_dialog,
993
                                             IncSession *inc_session)
994
{
995
        gchar buf[MSGBUFSIZE];
996
        Pop3Session *pop3_session = POP3_SESSION(inc_session->session);
997
        gchar *total_size_str;
998
        gint64 cur_total;
999
        gint64 total;
1000
1001
        if (!pop3_session->new_msg_exist) return;
1002
1003
        cur_total = inc_session->cur_total_bytes;
1004
        total = pop3_session->total_bytes;
1005
        if (pop3_session->state == POP3_RETR ||
1006
            pop3_session->state == POP3_RETR_RECV ||
1007
            pop3_session->state == POP3_DELETE) {
1008
                Xstrdup_a(total_size_str, to_human_readable(total), return);
1009
                g_snprintf(buf, sizeof(buf),
1010
                           _("Retrieving message (%d / %d) (%s / %s)"),
1011
                           pop3_session->cur_msg, pop3_session->count,
1012
                           to_human_readable(cur_total), total_size_str);
1013
                progress_dialog_set_label(inc_dialog->dialog, buf);
1014
        }
1015
1016
        progress_dialog_set_percentage
1017
                (inc_dialog->dialog,(gfloat)cur_total / (gfloat)total);
1018
1019
        gtk_progress_set_show_text
1020
                (GTK_PROGRESS(inc_dialog->mainwin->progressbar), TRUE);
1021
        g_snprintf(buf, sizeof(buf), "%d / %d",
1022
                   pop3_session->cur_msg, pop3_session->count);
1023
        gtk_progress_set_format_string
1024
                (GTK_PROGRESS(inc_dialog->mainwin->progressbar), buf);
1025
        gtk_progress_bar_update
1026
                (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar),
1027
                 (gfloat)cur_total / (gfloat)total);
1028
1029
        if (pop3_session->cur_total_num > 0) {
1030
                g_snprintf(buf, sizeof(buf),
1031
                           _("Retrieving (%d message(s) (%s) received)"),
1032
                           pop3_session->cur_total_num,
1033
                           to_human_readable
1034
                           (pop3_session->cur_total_recv_bytes));
1035
                progress_dialog_set_row_status(inc_dialog->dialog,
1036
                                               inc_dialog->cur_row, buf);
1037
        }
1038
}
1039
1040
static gboolean hash_remove_func(gpointer key, gpointer value, gpointer data)
1041
{
1042
        return TRUE;
1043
}
1044
1045
static void inc_update_folderview(IncProgressDialog *inc_dialog,
1046
                                  IncSession *inc_session)
1047
{
1048
        if (g_hash_table_size(inc_session->tmp_folder_table) > 0) {
1049
                folderview_update_item_foreach(inc_session->tmp_folder_table,
1050
                                               FALSE);
1051
                g_hash_table_foreach_remove(inc_session->tmp_folder_table,
1052
                                            hash_remove_func, NULL);
1053
        }
1054
}
1055
1056
static void inc_progress_dialog_update_periodic(IncProgressDialog *inc_dialog,
1057
                                                IncSession *inc_session)
1058
{
1059
        GTimeVal tv_cur;
1060
        GTimeVal tv_result;
1061
        gint msec;
1062
1063
        g_get_current_time(&tv_cur);
1064
1065
        tv_result.tv_sec = tv_cur.tv_sec - inc_dialog->progress_tv.tv_sec;
1066
        tv_result.tv_usec = tv_cur.tv_usec - inc_dialog->progress_tv.tv_usec;
1067
        if (tv_result.tv_usec < 0) {
1068
                tv_result.tv_sec--;
1069
                tv_result.tv_usec += G_USEC_PER_SEC;
1070
        }
1071
1072
        msec = tv_result.tv_sec * 1000 + tv_result.tv_usec / 1000;
1073
        if (msec > PROGRESS_UPDATE_INTERVAL) {
1074
                inc_progress_dialog_update(inc_dialog, inc_session);
1075
                inc_dialog->progress_tv.tv_sec = tv_cur.tv_sec;
1076
                inc_dialog->progress_tv.tv_usec = tv_cur.tv_usec;
1077
        }
1078
}
1079
1080
static void inc_update_folderview_periodic(IncProgressDialog *inc_dialog,
1081
                                           IncSession *inc_session)
1082
{
1083
        GTimeVal tv_cur;
1084
        GTimeVal tv_result;
1085
        gint msec;
1086
1087
        g_get_current_time(&tv_cur);
1088
1089
        tv_result.tv_sec = tv_cur.tv_sec - inc_dialog->folder_tv.tv_sec;
1090
        tv_result.tv_usec = tv_cur.tv_usec - inc_dialog->folder_tv.tv_usec;
1091
        if (tv_result.tv_usec < 0) {
1092
                tv_result.tv_sec--;
1093
                tv_result.tv_usec += G_USEC_PER_SEC;
1094
        }
1095
1096
        msec = tv_result.tv_sec * 1000 + tv_result.tv_usec / 1000;
1097
        if (msec > FOLDER_UPDATE_INTERVAL) {
1098
                inc_update_folderview(inc_dialog, inc_session);
1099
                inc_dialog->folder_tv.tv_sec = tv_cur.tv_sec;
1100
                inc_dialog->folder_tv.tv_usec = tv_cur.tv_usec;
1101
        }
1102
}
1103
1104
static gint inc_recv_data_progressive(Session *session, guint cur_len,
1105
                                      guint total_len, gpointer data)
1106
{
1107
        IncSession *inc_session = (IncSession *)data;
1108
        Pop3Session *pop3_session = POP3_SESSION(session);
1109
        IncProgressDialog *inc_dialog;
1110
        gint64 cur_total;
1111
1112
        g_return_val_if_fail(inc_session != NULL, -1);
1113
1114
        if (pop3_session->state != POP3_RETR &&
1115
            pop3_session->state != POP3_RETR_RECV &&
1116
            pop3_session->state != POP3_DELETE &&
1117
            pop3_session->state != POP3_LOGOUT) return 0;
1118
1119
        if (!pop3_session->new_msg_exist) return 0;
1120
1121
        cur_total = pop3_session->cur_total_bytes + cur_len;
1122
        if (cur_total > pop3_session->total_bytes)
1123
                cur_total = pop3_session->total_bytes;
1124
        inc_session->cur_total_bytes = cur_total;
1125
1126
        inc_dialog = (IncProgressDialog *)inc_session->data;
1127
        inc_progress_dialog_update_periodic(inc_dialog, inc_session);
1128
        inc_update_folderview_periodic(inc_dialog, inc_session);
1129
1130
        return 0;
1131
}
1132
1133
static gint inc_recv_data_finished(Session *session, guint len, gpointer data)
1134
{
1135
        IncSession *inc_session = (IncSession *)data;
1136
        IncProgressDialog *inc_dialog;
1137
1138
        g_return_val_if_fail(inc_session != NULL, -1);
1139
1140
        inc_dialog = (IncProgressDialog *)inc_session->data;
1141
1142
        inc_recv_data_progressive(session, 0, 0, inc_session);
1143
1144
        if (POP3_SESSION(session)->state == POP3_LOGOUT) {
1145
                inc_progress_dialog_update(inc_dialog, inc_session);
1146
                inc_update_folderview(inc_dialog, inc_session);
1147
        }
1148
1149
        return 0;
1150
}
1151
1152
static gint inc_recv_message(Session *session, const gchar *msg, gpointer data)
1153
{
1154
        IncSession *inc_session = (IncSession *)data;
1155
        IncProgressDialog *inc_dialog;
1156
1157
        g_return_val_if_fail(inc_session != NULL, -1);
1158
1159
        inc_dialog = (IncProgressDialog *)inc_session->data;
1160
1161
        switch (POP3_SESSION(session)->state) {
1162
        case POP3_GETAUTH_USER:
1163
        case POP3_GETAUTH_PASS:
1164
        case POP3_GETAUTH_APOP:
1165
        case POP3_GETRANGE_STAT:
1166
        case POP3_GETRANGE_LAST:
1167
        case POP3_GETRANGE_UIDL:
1168
        case POP3_GETSIZE_LIST:
1169
                inc_progress_dialog_update(inc_dialog, inc_session);
1170
                break;
1171
        case POP3_RETR:
1172
                inc_recv_data_progressive(session, 0, 0, inc_session);
1173
                break;
1174
        case POP3_LOGOUT:
1175
                inc_progress_dialog_update(inc_dialog, inc_session);
1176
                inc_update_folderview(inc_dialog, inc_session);
1177
                break;
1178
        default:
1179
                break;
1180
        }
1181
1182
        return 0;
1183
}
1184
1185
static gint inc_drop_message(Pop3Session *session, const gchar *file)
1186
{
1187
        FolderItem *inbox;
1188
        GSList *cur;
1189
        FilterInfo *fltinfo;
1190
        IncSession *inc_session = (IncSession *)(SESSION(session)->data);
1191
        gint val;
1192
        gboolean is_junk = FALSE;
1193
1194
        g_return_val_if_fail(inc_session != NULL, DROP_ERROR);
1195
1196
        if (session->ac_prefs->inbox) {
1197
                inbox = folder_find_item_from_identifier
1198
                        (session->ac_prefs->inbox);
1199
                if (!inbox)
1200
                        inbox = folder_get_default_inbox();
1201
        } else
1202
                inbox = folder_get_default_inbox();
1203
        if (!inbox)
1204
                return DROP_ERROR;
1205
1206
        fltinfo = filter_info_new();
1207
        fltinfo->account = session->ac_prefs;
1208
        fltinfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
1209
        fltinfo->flags.tmp_flags = MSG_RECEIVED;
1210
1211
        if (prefs_common.enable_junk &&
1212
            prefs_common.filter_junk_on_recv &&
1213
            prefs_common.filter_junk_before) {
1214
                filter_apply(prefs_common.junk_fltlist, file, fltinfo);
1215
                if (fltinfo->drop_done)
1216
                        is_junk = TRUE;
1217
                else if (fltinfo->error == FLT_ERROR_EXEC_FAILED) {
1218
                        alertpanel_error
1219
                                (_("Execution of the junk filter command failed.\n"
1220
                                   "Please check the junk mail control setting."));
1221
                        filter_info_free(fltinfo);
1222
                        inc_session->inc_state = INC_ERROR;
1223
                        return DROP_ERROR;
1224
                }
1225
        }
1226
1227
        if (!fltinfo->drop_done && session->ac_prefs->filter_on_recv)
1228
                filter_apply(prefs_common.fltlist, file, fltinfo);
1229
1230
        if (!fltinfo->drop_done) {
1231
                if (prefs_common.enable_junk &&
1232
                    prefs_common.filter_junk_on_recv &&
1233
                    !prefs_common.filter_junk_before) {
1234
                        filter_apply(prefs_common.junk_fltlist, file, fltinfo);
1235
                        if (fltinfo->drop_done)
1236
                                is_junk = TRUE;
1237
                        else if (fltinfo->error == FLT_ERROR_EXEC_FAILED) {
1238
                                alertpanel_error
1239
                                        (_("Execution of the junk filter command failed.\n"
1240
                                           "Please check the junk mail control setting."));
1241
                                filter_info_free(fltinfo);
1242
                                inc_session->inc_state = INC_ERROR;
1243
                                return DROP_ERROR;
1244
                        }
1245
                }
1246
        }
1247
1248
        if (!fltinfo->drop_done) {
1249
                if (folder_item_add_msg
1250
                        (inbox, file, &fltinfo->flags, FALSE) < 0) {
1251
                        filter_info_free(fltinfo);
1252
                        return DROP_ERROR;
1253
                }
1254
                fltinfo->dest_list = g_slist_append(fltinfo->dest_list, inbox);
1255
        }
1256
1257
        for (cur = fltinfo->dest_list; cur != NULL; cur = cur->next) {
1258
                FolderItem *drop_folder = (FolderItem *)cur->data;
1259
1260
                val = GPOINTER_TO_INT(g_hash_table_lookup
1261
                                      (inc_session->folder_table, drop_folder));
1262
                if (val == 0)
1263
                        g_hash_table_insert(inc_session->folder_table,
1264
                                            drop_folder, GINT_TO_POINTER(1));
1265
                g_hash_table_insert(inc_session->tmp_folder_table, drop_folder,
1266
                                    GINT_TO_POINTER(1));
1267
        }
1268
1269
        if (fltinfo->actions[FLT_ACTION_NOT_RECEIVE] == TRUE)
1270
                val = DROP_DONT_RECEIVE;
1271
        else if (fltinfo->actions[FLT_ACTION_DELETE] == TRUE)
1272
                val = DROP_DELETE;
1273
        else {
1274
                val = DROP_OK;
1275
                if (!is_junk && fltinfo->actions[FLT_ACTION_MARK_READ] == FALSE)
1276
                        inc_session->new_msgs++;
1277
        }
1278
1279
        filter_info_free(fltinfo);
1280
1281
        return val;
1282
}
1283
1284
static void inc_put_error(IncState istate, const gchar *msg)
1285
{
1286
        gchar *log_msg = NULL;
1287
        gchar *err_msg = NULL;
1288
        gboolean fatal_error = FALSE;
1289
1290
        switch (istate) {
1291
        case INC_CONNECT_ERROR:
1292
                log_msg = _("Connection failed.");
1293
                if (prefs_common.no_recv_err_panel)
1294
                        break;
1295
                err_msg = g_strdup(log_msg);
1296
                break;
1297
        case INC_ERROR:
1298
                log_msg = _("Error occurred while processing mail.");
1299
                if (prefs_common.no_recv_err_panel)
1300
                        break;
1301
                if (msg)
1302
                        err_msg = g_strdup_printf
1303
                                (_("Error occurred while processing mail:\n%s"),
1304
                                 msg);
1305
                else
1306
                        err_msg = g_strdup(log_msg);
1307
                break;
1308
        case INC_NO_SPACE:
1309
                log_msg = _("No disk space left.");
1310
                err_msg = g_strdup(log_msg);
1311
                fatal_error = TRUE;
1312
                break;
1313
        case INC_IO_ERROR:
1314
                log_msg = _("Can't write file.");
1315
                err_msg = g_strdup(log_msg);
1316
                fatal_error = TRUE;
1317
                break;
1318
        case INC_SOCKET_ERROR:
1319
                log_msg = _("Socket error.");
1320
                if (prefs_common.no_recv_err_panel)
1321
                        break;
1322
                err_msg = g_strdup(log_msg);
1323
                break;
1324
        case INC_EOF:
1325
                log_msg = _("Connection closed by the remote host.");
1326
                if (prefs_common.no_recv_err_panel)
1327
                        break;
1328
                err_msg = g_strdup(log_msg);
1329
                break;
1330
        case INC_LOCKED:
1331
                log_msg = _("Mailbox is locked.");
1332
                if (prefs_common.no_recv_err_panel)
1333
                        break;
1334
                if (msg)
1335
                        err_msg = g_strdup_printf(_("Mailbox is locked:\n%s"),
1336
                                                  msg);
1337
                else
1338
                        err_msg = g_strdup(log_msg);
1339
                break;
1340
        case INC_AUTH_FAILED:
1341
                log_msg = _("Authentication failed.");
1342
                if (prefs_common.no_recv_err_panel)
1343
                        break;
1344
                if (msg)
1345
                        err_msg = g_strdup_printf
1346
                                (_("Authentication failed:\n%s"), msg);
1347
                else
1348
                        err_msg = g_strdup(log_msg);
1349
                break;
1350
        case INC_TIMEOUT:
1351
                log_msg = _("Session timed out.");
1352
                if (prefs_common.no_recv_err_panel)
1353
                        break;
1354
                err_msg = g_strdup(log_msg);
1355
                break;
1356
        default:
1357
                break;
1358
        }
1359
1360
        if (log_msg) {
1361
                if (fatal_error)
1362
                        log_error("%s\n", log_msg);
1363
                else
1364
                        log_warning("%s\n", log_msg);
1365
        }
1366
        if (err_msg) {
1367
                alertpanel_error(err_msg);
1368
                g_free(err_msg);
1369
        }
1370
}
1371
1372
static void inc_cancel(IncProgressDialog *dialog, gboolean cancel_all)
1373
{
1374
        IncSession *session;
1375
        GList *list;
1376
1377
        g_return_if_fail(dialog != NULL);
1378
1379
        if (dialog->queue_list == NULL) {
1380
                inc_progress_dialog_destroy(dialog);
1381
                return;
1382
        }
1383
1384
        for (list = dialog->queue_list; list != NULL; list = list->next) {
1385
                session = list->data;
1386
                session->inc_state = INC_CANCEL;
1387
                session_disconnect(session->session);
1388
                if (!cancel_all)
1389
                        break;
1390
        }
1391
1392
        log_message(_("Incorporation cancelled\n"));
1393
}
1394
1395
gboolean inc_is_active(void)
1396
{
1397
        GList *cur;
1398
1399
        if (inc_dialog_list == NULL)
1400
                return FALSE;
1401
1402
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next) {
1403
                IncProgressDialog *dialog = cur->data;
1404
                if (dialog->queue_list)
1405
                        return TRUE;
1406
        }
1407
1408
        return FALSE;
1409
}
1410
1411
void inc_cancel_all(void)
1412
{
1413
        GList *cur;
1414
1415
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next)
1416
                inc_cancel((IncProgressDialog *)cur->data, TRUE);
1417
}
1418
1419
static void inc_cancel_cb(GtkWidget *widget, gpointer data)
1420
{
1421
        inc_cancel((IncProgressDialog *)data, FALSE);
1422
}
1423
1424
static gint inc_dialog_delete_cb(GtkWidget *widget, GdkEventAny *event,
1425
                                 gpointer data)
1426
{
1427
        IncProgressDialog *dialog = (IncProgressDialog *)data;
1428
1429
        if (dialog->queue_list == NULL)
1430
                inc_progress_dialog_destroy(dialog);
1431
1432
        return TRUE;
1433
}
1434
1435
static gint inc_spool(void)
1436
{
1437
        gchar *spool_path;
1438
        gchar *mbox;
1439
        gint msgs;
1440
1441
        spool_path = prefs_common.spool_path
1442
                ? prefs_common.spool_path : DEFAULT_SPOOL_PATH;
1443
        if (is_file_exist(spool_path))
1444
                mbox = g_strdup(spool_path);
1445
        else if (is_dir_exist(spool_path))
1446
                mbox = g_strconcat(spool_path, G_DIR_SEPARATOR_S,
1447
                                   g_get_user_name(), NULL);
1448
        else {
1449
                debug_print("%s: local mailbox not found.\n", spool_path);
1450
                return -1;
1451
        }
1452
1453
        msgs = get_spool(folder_get_default_inbox(), mbox);
1454
        g_free(mbox);
1455
1456
        return msgs;
1457
}
1458
1459
static gint get_spool(FolderItem *dest, const gchar *mbox)
1460
{
1461
        gint msgs, size;
1462
        gint lockfd;
1463
        gchar tmp_mbox[MAXPATHLEN + 1];
1464
        GHashTable *folder_table = NULL;
1465
1466
        g_return_val_if_fail(dest != NULL, -1);
1467
        g_return_val_if_fail(mbox != NULL, -1);
1468
1469
        if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
1470
                debug_print("%s: no messages in local mailbox.\n", mbox);
1471
                return 0;
1472
        } else if (size < 0)
1473
                return -1;
1474
1475
        if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
1476
                return -1;
1477
1478
        g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
1479
                   get_tmp_dir(), G_DIR_SEPARATOR, mbox);
1480
1481
        if (copy_mbox(mbox, tmp_mbox) < 0) {
1482
                unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1483
                return -1;
1484
        }
1485
1486
        debug_print(_("Getting new messages from %s into %s...\n"),
1487
                    mbox, dest->path);
1488
1489
        folder_table = g_hash_table_new(NULL, NULL);
1490
1491
        msgs = proc_mbox_full(dest, tmp_mbox, folder_table,
1492
                              prefs_common.filter_on_inc,
1493
                              prefs_common.enable_junk &&
1494
                              prefs_common.filter_junk_on_recv);
1495
1496
        g_unlink(tmp_mbox);
1497
        if (msgs >= 0) empty_mbox(mbox);
1498
        unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1499
1500
        if (!prefs_common.scan_all_after_inc) {
1501
                folder_item_scan_foreach(folder_table);
1502
                folderview_update_item_foreach
1503
                        (folder_table, !prefs_common.open_inbox_on_inc);
1504
        }
1505
1506
        g_hash_table_destroy(folder_table);
1507
1508
        return msgs;
1509
}
1510
1511
void inc_lock(void)
1512
{
1513
        inc_lock_count++;
1514
}
1515
1516
void inc_unlock(void)
1517
{
1518
        if (inc_lock_count > 0)
1519
                inc_lock_count--;
1520
}
1521
1522
static guint autocheck_timer = 0;
1523
static gpointer autocheck_data = NULL;
1524
1525
void inc_autocheck_timer_init(MainWindow *mainwin)
1526
{
1527
        autocheck_data = mainwin;
1528
        inc_autocheck_timer_set();
1529
}
1530
1531
static void inc_autocheck_timer_set_interval(guint interval)
1532
{
1533
        inc_autocheck_timer_remove();
1534
1535
        if (prefs_common.autochk_newmail && autocheck_data) {
1536
                autocheck_timer = gtk_timeout_add
1537
                        (interval, inc_autocheck_func, autocheck_data);
1538
                debug_print("added timer = %d\n", autocheck_timer);
1539
        }
1540
}
1541
1542
void inc_autocheck_timer_set(void)
1543
{
1544
        inc_autocheck_timer_set_interval(prefs_common.autochk_itv * 60000);
1545
}
1546
1547
void inc_autocheck_timer_remove(void)
1548
{
1549
        if (autocheck_timer) {
1550
                debug_print("removed timer = %d\n", autocheck_timer);
1551
                gtk_timeout_remove(autocheck_timer);
1552
                autocheck_timer = 0;
1553
        }
1554
}
1555
1556
static gint inc_autocheck_func(gpointer data)
1557
{
1558
        MainWindow *mainwin = (MainWindow *)data;
1559
1560
        if (inc_lock_count) {
1561
                debug_print("autocheck is locked.\n");
1562
                inc_autocheck_timer_set_interval(1000);
1563
                return FALSE;
1564
        }
1565
1566
        inc_all_account_mail(mainwin, TRUE);
1567
1568
        return FALSE;
1569
}