Statistics
| Revision:

root / src / inc.c @ 2259

History | View | Annotate | Download (41.1 kB)

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