Statistics
| Revision:

root / src / inc.c @ 3211

History | View | Annotate | Download (50.4 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2013 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/gtkdialog.h>
33
#include <gtk/gtkstock.h>
34
#include <stdio.h>
35
#include <unistd.h>
36
#include <string.h>
37

    
38
#include "main.h"
39
#include "inc.h"
40
#include "mainwindow.h"
41
#include "folderview.h"
42
#include "summaryview.h"
43
#include "prefs_common.h"
44
#include "prefs_account.h"
45
#include "account.h"
46
#include "procmsg.h"
47
#include "socket.h"
48
#include "socks.h"
49
#include "pop.h"
50
#include "recv.h"
51
#include "mbox.h"
52
#include "imap.h"
53
#include "utils.h"
54
#include "gtkutils.h"
55
#include "statusbar.h"
56
#include "manage_window.h"
57
#include "stock_pixmap.h"
58
#include "progressdialog.h"
59
#include "alertpanel.h"
60
#include "trayicon.h"
61
#include "notificationwindow.h"
62
#include "filter.h"
63
#include "folder.h"
64
#include "procheader.h"
65
#include "plugin.h"
66

    
67

    
68
typedef struct _IncAccountNewMsgCount
69
{
70
        PrefsAccount *account;
71
        gint new_messages;
72
} IncAccountNewMsgCount;
73

    
74
typedef struct _IncMsgSummary
75
{
76
        gchar *subject;
77
        gchar *from;
78
} IncMsgSummary;
79

    
80
struct _IncResult
81
{
82
        GSList *count_list;
83
        GSList *msg_summaries;
84
};
85

    
86

    
87
static GList *inc_dialog_list = NULL;
88

    
89
static gboolean inc_is_running = FALSE;
90

    
91
static guint inc_lock_count = 0;
92
static gboolean block_notify = FALSE;
93

    
94
static GdkPixbuf *current_pixbuf;
95
static GdkPixbuf *error_pixbuf;
96
static GdkPixbuf *ok_pixbuf;
97

    
98

    
99
static void inc_finished                (MainWindow                *mainwin,
100
                                         IncResult                *result);
101
static GSList *inc_add_message_count        (GSList                        *list,
102
                                         PrefsAccount                *account,
103
                                         gint                         new_messages);
104
static void inc_result_free                (IncResult                *result,
105
                                         gboolean                 free_self);
106

    
107
static gint inc_remote_account_mail        (MainWindow                *mainwin,
108
                                         PrefsAccount                *account);
109
static gint inc_account_mail_real        (MainWindow                *mainwin,
110
                                         PrefsAccount                *account,
111
                                         IncResult                *result);
112

    
113
static IncProgressDialog *inc_progress_dialog_create
114
                                        (gboolean                 autocheck);
115
static void inc_progress_dialog_set_list(IncProgressDialog        *inc_dialog);
116
static void inc_progress_dialog_destroy        (IncProgressDialog        *inc_dialog);
117

    
118
static IncSession *inc_session_new        (PrefsAccount                *account);
119
static void inc_session_destroy                (IncSession                *session);
120
static gint inc_start                        (IncProgressDialog        *inc_dialog);
121
static IncState inc_pop3_session_do        (IncSession                *session);
122

    
123
static void inc_progress_dialog_update        (IncProgressDialog        *inc_dialog,
124
                                         IncSession                *inc_session);
125

    
126
static void inc_progress_dialog_set_label
127
                                        (IncProgressDialog        *inc_dialog,
128
                                         IncSession                *inc_session);
129
static void inc_progress_dialog_set_progress
130
                                        (IncProgressDialog        *inc_dialog,
131
                                         IncSession                *inc_session);
132

    
133
static void inc_update_folderview        (IncProgressDialog        *inc_dialog,
134
                                         IncSession                *inc_session);
135

    
136
static void inc_progress_dialog_update_periodic
137
                                        (IncProgressDialog        *inc_dialog,
138
                                         IncSession                *inc_session);
139
static void inc_update_folderview_periodic
140
                                        (IncProgressDialog        *inc_dialog,
141
                                         IncSession                *inc_session);
142

    
143
static gint inc_recv_data_progressive        (Session        *session,
144
                                         guint                 cur_len,
145
                                         guint                 total_len,
146
                                         gpointer         data);
147
static gint inc_recv_data_finished        (Session        *session,
148
                                         guint                 len,
149
                                         gpointer         data);
150
static gint inc_recv_message                (Session        *session,
151
                                         const gchar        *msg,
152
                                         gpointer         data);
153
static gint inc_drop_message                (Pop3Session        *session,
154
                                         const gchar        *file);
155

    
156
static void inc_put_error                (IncSession        *session,
157
                                         IncState         istate,
158
                                         const gchar        *pop3_msg);
159

    
160
static void inc_cancel_cb                (GtkWidget        *widget,
161
                                         gpointer         data);
162
static void inc_cancel_all_cb                (GtkWidget        *widget,
163
                                         gpointer         data);
164
static gint inc_dialog_delete_cb        (GtkWidget        *widget,
165
                                         GdkEventAny        *event,
166
                                         gpointer         data);
167

    
168
static gint inc_spool                        (void);
169
static gint get_spool                        (FolderItem        *dest,
170
                                         const gchar        *mbox);
171

    
172
static void inc_autocheck_timer_set_interval        (guint                 interval);
173
static gint inc_autocheck_func                        (gpointer         data);
174

    
175

    
176
/**
177
 * inc_finished:
178
 * @mainwin: Main window.
179
 * @result: Information of incorporation result.
180
 * @new_messages: Number of received messages.
181
 * 
182
 * Update the folder view and the summary view after receiving
183
 * messages.  If @new_messages is 0, this function avoids unneeded
184
 * updating.
185
 **/
186
static void inc_finished(MainWindow *mainwin, IncResult *result)
187
{
188
        FolderItem *item;
189
        gint new_messages = 0;
190
        gint other_new = 0;
191
        IncAccountNewMsgCount *count;
192
        GSList *cur;
193

    
194
        if (result) {
195
                for (cur = result->count_list; cur != NULL; cur = cur->next) {
196
                        count = cur->data;
197
                        if (count->new_messages > 0)
198
                                new_messages += count->new_messages;
199
                }
200
        }
201

    
202
        debug_print("inc_finished: %d new message(s)\n", new_messages);
203

    
204
        if (prefs_common.scan_all_after_inc) {
205
                other_new = folderview_check_new(NULL);
206
                new_messages += other_new;
207
        }
208

    
209
        if (new_messages > 0 && !block_notify) {
210
                gchar buf[1024];
211
                GString *str;
212
                gint c = 0;
213

    
214
                str = g_string_new("");
215
                g_string_printf(str, _("Sylpheed: %d new messages"),
216
                                new_messages);
217
                if (result) {
218
                        for (cur = result->count_list; cur != NULL; cur = cur->next) {
219
                                count = cur->data;
220
                                if (count->new_messages > 0) {
221
                                        if (c == 0)
222
                                                g_string_append(str, "\n");
223
                                        c++;
224
                                        g_string_append(str, "\n");
225
                                        if (!count->account)
226
                                                g_string_append_printf(str, _("[Local]: %d"), count->new_messages);
227
                                        else
228
                                                g_string_append_printf(str, "%s: %d", count->account->account_name ? count->account->account_name : "[?]", count->new_messages);
229
                                }
230
                        }
231
                }
232
                debug_print("inc_finished: %s\n", str->str);
233
                trayicon_set_tooltip(str->str);
234
                trayicon_set_notify(TRUE);
235

    
236
                g_snprintf(buf, sizeof(buf), _("Sylpheed: %d new messages"), new_messages);
237
                g_string_truncate(str, 0);
238
                if (result) {
239
                        for (cur = result->msg_summaries; cur != NULL; cur = cur->next) {
240
                                IncMsgSummary *summary = cur->data;
241
                                gchar *markup;
242

    
243
                                if (str->len > 0)
244
                                        g_string_append_c(str, '\n');
245
                                markup = g_markup_printf_escaped("<b>%s</b>  %s", summary->subject, summary->from);
246
                                g_string_append(str, markup);
247
                                g_free(markup);
248
                        }
249
                }
250

    
251
                notification_window_create(buf, str->str, 5);
252

    
253
                g_string_free(str, TRUE);
254
        }
255

    
256
        syl_plugin_signal_emit("inc-mail-finished", new_messages);
257

    
258
        inc_block_notify(FALSE);
259

    
260
        if (new_messages <= 0 && !prefs_common.scan_all_after_inc) return;
261

    
262
        if (prefs_common.open_inbox_on_inc) {
263
                item = cur_account && cur_account->inbox
264
                        ? folder_find_item_from_identifier(cur_account->inbox)
265
                        : folder_get_default_inbox();
266
                folderview_select(mainwin->folderview, item);
267
        } else if (prefs_common.scan_all_after_inc) {
268
                item = mainwin->summaryview->folder_item;
269
                if (item)
270
                        folderview_update_item(item, TRUE);
271
        }
272

    
273
        /* Notification */
274

    
275
        if (new_messages > 0 &&
276
            prefs_common.enable_newmsg_notify_sound &&
277
            prefs_common.newmsg_notify_sound) {
278
                play_sound(prefs_common.newmsg_notify_sound, TRUE);
279
        }
280

    
281
        if (new_messages > 0 &&
282
            prefs_common.enable_newmsg_notify &&
283
            prefs_common.newmsg_notify_cmd) {
284
                gchar buf[1024];
285

    
286
                if (str_find_format_times
287
                        (prefs_common.newmsg_notify_cmd, 'd') == 1)
288
                        g_snprintf(buf, sizeof(buf),
289
                                   prefs_common.newmsg_notify_cmd,
290
                                   new_messages);
291
                else
292
                        strncpy2(buf, prefs_common.newmsg_notify_cmd,
293
                                 sizeof(buf));
294
                execute_command_line(buf, TRUE);
295
        }
296
}
297

    
298
static GSList *inc_add_message_count(GSList *list, PrefsAccount *account,
299
                                     gint new_messages)
300
{
301
        IncAccountNewMsgCount *count;
302

    
303
        count = g_new(IncAccountNewMsgCount, 1);
304
        count->account = account;
305
        count->new_messages = new_messages;
306

    
307
        return g_slist_append(list, count);
308
}
309

    
310
static void inc_result_free(IncResult *result, gboolean free_self)
311
{
312
        GSList *cur;
313

    
314
        slist_free_strings(result->count_list);
315
        g_slist_free(result->count_list);
316
        for (cur = result->msg_summaries; cur != NULL; cur = cur->next) {
317
                IncMsgSummary *sum = cur->data;
318
                g_free(sum->subject);
319
                g_free(sum->from);
320
                g_free(sum);
321
        }
322
        g_slist_free(result->msg_summaries);
323

    
324
        if (free_self)
325
                g_free(result);
326
}
327

    
328
void inc_mail(MainWindow *mainwin)
329
{
330
        IncResult result = {NULL, NULL};
331
        gint new_msgs = 0;
332

    
333
        if (inc_lock_count) return;
334
        if (inc_is_active()) return;
335

    
336
        if (!main_window_toggle_online_if_offline(mainwin))
337
                return;
338

    
339
        inc_is_running = TRUE;
340

    
341
        inc_autocheck_timer_remove();
342
        summary_write_cache(mainwin->summaryview);
343
        main_window_lock(mainwin);
344

    
345
        syl_plugin_signal_emit("inc-mail-start", cur_account);
346

    
347
        if (prefs_common.use_extinc && prefs_common.extinc_cmd) {
348
                /* external incorporating program */
349
                if (execute_command_line(prefs_common.extinc_cmd, FALSE) != 0) {
350
                        inc_is_running = FALSE;
351
                        main_window_unlock(mainwin);
352
                        inc_autocheck_timer_set();
353
                        return;
354
                }
355

    
356
                if (prefs_common.inc_local) {
357
                        new_msgs = inc_spool();
358
                        result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs);
359
                }
360
        } else {
361
                if (prefs_common.inc_local) {
362
                        new_msgs = inc_spool();
363
                        if (new_msgs < 0)
364
                                new_msgs = 0;
365
                        result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs);
366
                }
367

    
368
                new_msgs = inc_account_mail_real(mainwin, cur_account, &result);
369
        }
370

    
371
        inc_finished(mainwin, &result);
372
        inc_result_free(&result, FALSE);
373

    
374
        inc_is_running = FALSE;
375

    
376
        main_window_unlock(mainwin);
377
        inc_autocheck_timer_set();
378
}
379

    
380
static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account)
381
{
382
        FolderItem *item = mainwin->summaryview->folder_item;
383
        gint new_msgs = 0;
384
        gboolean update_summary = FALSE;
385

    
386
        g_return_val_if_fail(account != NULL, 0);
387
        g_return_val_if_fail(account->folder != NULL, 0);
388

    
389
        if (account->protocol == A_IMAP4 &&
390
            account->imap_filter_inbox_on_recv) {
391
                FolderItem *inbox = FOLDER(account->folder)->inbox;
392
                GSList *mlist, *cur;
393
                FilterInfo *fltinfo;
394
                GSList junk_fltlist = {NULL, NULL};
395
                FilterRule *junk_rule;
396
                gint n_filtered = 0;
397

    
398
                debug_print("inc_remote_account_mail(): filtering IMAP4 INBOX\n");
399
                mlist = folder_item_get_uncached_msg_list(inbox);
400
                debug_print("inc_remote_account_mail(): uncached messages: %d\n", g_slist_length(mlist));
401

    
402
                junk_rule = filter_junk_rule_create(account, NULL, TRUE);
403
                if (junk_rule)
404
                        junk_fltlist.data = junk_rule;
405

    
406
                for (cur = mlist; cur != NULL; cur = cur->next) {
407
                        MsgInfo *msginfo = (MsgInfo *)cur->data;
408
                        gboolean is_junk = FALSE;
409

    
410
                        fltinfo = filter_info_new();
411
                        fltinfo->account = account;
412
                        fltinfo->flags = msginfo->flags;
413

    
414
                        if (prefs_common.enable_junk &&
415
                            prefs_common.filter_junk_on_recv &&
416
                            prefs_common.filter_junk_before && junk_rule) {
417
                                filter_apply_msginfo
418
                                        (&junk_fltlist, msginfo, fltinfo);
419
                                if (fltinfo->drop_done)
420
                                        is_junk = TRUE;
421
                        }
422

    
423
                        if (!fltinfo->drop_done) {
424
                                filter_apply_msginfo(prefs_common.fltlist,
425
                                                     msginfo, fltinfo);
426
                        }
427

    
428
                        if (!fltinfo->drop_done &&
429
                            prefs_common.enable_junk &&
430
                            prefs_common.filter_junk_on_recv &&
431
                            !prefs_common.filter_junk_before && junk_rule) {
432
                                filter_apply_msginfo
433
                                        (&junk_fltlist, msginfo, fltinfo);
434
                                if (fltinfo->drop_done)
435
                                        is_junk = TRUE;
436
                        }
437

    
438
                        if (msginfo->flags.perm_flags !=
439
                            fltinfo->flags.perm_flags) {
440
                                msginfo->flags = fltinfo->flags;
441
                                inbox->mark_dirty = TRUE;
442
                                if (fltinfo->actions[FLT_ACTION_MARK])
443
                                        imap_msg_set_perm_flags
444
                                                (msginfo, MSG_MARKED);
445
                                if (fltinfo->actions[FLT_ACTION_MARK_READ])
446
                                        imap_msg_unset_perm_flags
447
                                                (msginfo, MSG_NEW|MSG_UNREAD);
448
                        }
449

    
450
                        if (fltinfo->actions[FLT_ACTION_MOVE] &&
451
                            fltinfo->move_dest) {
452
                                folder_item_move_msg
453
                                        (fltinfo->move_dest, msginfo);
454
                                if (account->imap_check_inbox_only ||
455
                                    fltinfo->move_dest->folder !=
456
                                    inbox->folder) {
457
                                        if (!is_junk &&
458
                                            fltinfo->move_dest->stype != F_TRASH &&
459
                                            fltinfo->move_dest->stype != F_JUNK &&
460
                                            (MSG_IS_NEW(fltinfo->flags) ||
461
                                             MSG_IS_UNREAD(fltinfo->flags)))
462
                                                ++new_msgs;
463
                                }
464
                        } else if (fltinfo->actions[FLT_ACTION_DELETE])
465
                                folder_item_remove_msg(inbox, msginfo);
466
                        else if (!is_junk && (MSG_IS_NEW(msginfo->flags) ||
467
                                              MSG_IS_UNREAD(msginfo->flags)))
468
                                ++new_msgs;
469

    
470
                        if (fltinfo->drop_done)
471
                                ++n_filtered;
472

    
473
                        filter_info_free(fltinfo);
474
                }
475

    
476
                if (junk_rule)
477
                        filter_rule_free(junk_rule);
478

    
479
                procmsg_msg_list_free(mlist);
480

    
481
                debug_print("inc_remote_account_mail(): INBOX: %d new, %d filtered\n",
482
                            new_msgs, n_filtered);
483

    
484
                if (!prefs_common.scan_all_after_inc && item != NULL &&
485
                    inbox == item)
486
                        update_summary = TRUE;
487
        }
488

    
489
        if (account->protocol == A_IMAP4 && account->imap_check_inbox_only) {
490
                FolderItem *inbox = FOLDER(account->folder)->inbox;
491

    
492
                new_msgs += folderview_check_new_item(inbox);
493
                if (!prefs_common.scan_all_after_inc && item != NULL &&
494
                    inbox == item)
495
                        update_summary = TRUE;
496
        } else {
497
                new_msgs += folderview_check_new(FOLDER(account->folder));
498
                if (!prefs_common.scan_all_after_inc && item != NULL &&
499
                    FOLDER(account->folder) == item->folder)
500
                        update_summary = TRUE;
501
        }
502

    
503
        if (update_summary)
504
                folderview_update_item(item, TRUE);
505
        folderview_update_all_updated(FALSE);
506

    
507
        return new_msgs;
508
}
509

    
510
static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account,
511
                                  IncResult *result)
512
{
513
        IncProgressDialog *inc_dialog;
514
        IncSession *session;
515

    
516
        g_return_val_if_fail(account != NULL, 0);
517

    
518
        if (account->protocol == A_IMAP4 || account->protocol == A_NNTP)
519
                return inc_remote_account_mail(mainwin, account);
520

    
521
        session = inc_session_new(account);
522
        if (!session) return 0;
523

    
524
        inc_dialog = inc_progress_dialog_create(FALSE);
525
        inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session);
526
        inc_dialog->mainwin = mainwin;
527
        inc_dialog->result = result;
528
        inc_progress_dialog_set_list(inc_dialog);
529

    
530
        main_window_set_toolbar_sensitive(mainwin);
531
        main_window_set_menu_sensitive(mainwin);
532

    
533
        return inc_start(inc_dialog);
534
}
535

    
536
gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
537
{
538
        IncResult result = {NULL, NULL};
539
        gint new_msgs;
540

    
541
        if (inc_lock_count) return 0;
542
        if (inc_is_active()) return 0;
543

    
544
        if (!main_window_toggle_online_if_offline(mainwin))
545
                return 0;
546

    
547
        inc_is_running = TRUE;
548

    
549
        inc_autocheck_timer_remove();
550
        summary_write_cache(mainwin->summaryview);
551
        main_window_lock(mainwin);
552

    
553
        syl_plugin_signal_emit("inc-mail-start", account);
554

    
555
        new_msgs = inc_account_mail_real(mainwin, account, &result);
556

    
557
        inc_finished(mainwin, &result);
558
        inc_result_free(&result, FALSE);
559

    
560
        inc_is_running = FALSE;
561

    
562
        main_window_unlock(mainwin);
563
        inc_autocheck_timer_set();
564

    
565
        return new_msgs;
566
}
567

    
568
void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck)
569
{
570
        GList *list, *queue_list = NULL;
571
        IncProgressDialog *inc_dialog;
572
        IncResult result = {NULL, NULL};
573
        gint new_msgs = 0;
574

    
575
        if (inc_lock_count) return;
576
        if (inc_is_active()) return;
577

    
578
        if (!main_window_toggle_online_if_offline(mainwin))
579
                return;
580

    
581
        inc_is_running = TRUE;
582

    
583
        inc_autocheck_timer_remove();
584
        summary_write_cache(mainwin->summaryview);
585
        main_window_lock(mainwin);
586

    
587
        syl_plugin_signal_emit("inc-mail-start", NULL);
588

    
589
        if (prefs_common.inc_local) {
590
                new_msgs = inc_spool();
591
                if (new_msgs < 0)
592
                        new_msgs = 0;
593
                result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs);
594
        }
595

    
596
        /* check IMAP4 / News folders */
597
        for (list = account_get_list(); list != NULL; list = list->next) {
598
                PrefsAccount *account = list->data;
599
                if ((account->protocol == A_IMAP4 ||
600
                     account->protocol == A_NNTP) && account->recv_at_getall) {
601
                        new_msgs = inc_remote_account_mail(mainwin, account);
602
                        result.count_list = inc_add_message_count(result.count_list, account, new_msgs);
603
                }
604
        }
605

    
606
        /* check POP3 accounts */
607
        for (list = account_get_list(); list != NULL; list = list->next) {
608
                IncSession *session;
609
                PrefsAccount *account = list->data;
610

    
611
                if (account->recv_at_getall) {
612
                        session = inc_session_new(account);
613
                        if (session)
614
                                queue_list = g_list_append(queue_list, session);
615
                }
616
        }
617

    
618
        if (queue_list) {
619
                inc_dialog = inc_progress_dialog_create(autocheck);
620
                inc_dialog->queue_list = queue_list;
621
                inc_dialog->mainwin = mainwin;
622
                inc_dialog->result = &result;
623
                inc_progress_dialog_set_list(inc_dialog);
624

    
625
                main_window_set_toolbar_sensitive(mainwin);
626
                main_window_set_menu_sensitive(mainwin);
627

    
628
                inc_start(inc_dialog);
629
        }
630

    
631
        inc_finished(mainwin, &result);
632
        inc_result_free(&result, FALSE);
633

    
634
        inc_is_running = FALSE;
635

    
636
        main_window_unlock(mainwin);
637
        inc_autocheck_timer_set();
638
}
639

    
640
gint inc_pop_before_smtp(PrefsAccount *account)
641
{
642
        MainWindow *mainwin;
643
        IncProgressDialog *inc_dialog;
644
        IncSession *session;
645

    
646
        if (inc_lock_count) return -1;
647

    
648
        mainwin = main_window_get();
649

    
650
        if (!main_window_toggle_online_if_offline(mainwin))
651
                return -1;
652

    
653
        inc_is_running = TRUE;
654

    
655
        inc_autocheck_timer_remove();
656
        main_window_lock(mainwin);
657

    
658
        session = inc_session_new(account);
659
        if (!session) return -1;
660
        POP3_SESSION(session->session)->auth_only = TRUE;
661

    
662
        inc_dialog = inc_progress_dialog_create(FALSE);
663
        gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
664
                             _("Authenticating with POP3"));
665
        inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session);
666
        inc_dialog->mainwin = mainwin;
667
        inc_dialog->result = NULL;
668
        inc_progress_dialog_set_list(inc_dialog);
669
        inc_dialog->show_dialog = TRUE;
670

    
671
        main_window_set_toolbar_sensitive(mainwin);
672
        main_window_set_menu_sensitive(mainwin);
673

    
674
        inc_start(inc_dialog);
675

    
676
        inc_is_running = FALSE;
677

    
678
        main_window_unlock(mainwin);
679
        inc_autocheck_timer_set();
680

    
681
        return 0;
682
}
683

    
684
static IncProgressDialog *inc_progress_dialog_create(gboolean autocheck)
685
{
686
        IncProgressDialog *dialog;
687
        ProgressDialog *progress;
688
        GtkWidget *cancel_all_btn;
689

    
690
        dialog = g_new0(IncProgressDialog, 1);
691

    
692
        progress = progress_dialog_create();
693
        gtk_window_set_title(GTK_WINDOW(progress->window),
694
                             _("Retrieving new messages"));
695
        cancel_all_btn = gtk_dialog_add_button(GTK_DIALOG(progress->window),
696
                                               _("Cancel _all"),
697
                                               GTK_RESPONSE_NONE);
698
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
699
                         G_CALLBACK(inc_cancel_cb), dialog);
700
        g_signal_connect(G_OBJECT(cancel_all_btn), "clicked",
701
                         G_CALLBACK(inc_cancel_all_cb), dialog);
702
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
703
                         G_CALLBACK(inc_dialog_delete_cb), dialog);
704
        /* manage_window_set_transient(GTK_WINDOW(progress->window)); */
705

    
706
        progress_dialog_set_value(progress, 0.0);
707

    
708
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_COMPLETE, &ok_pixbuf);
709
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_CONTINUE,
710
                         &current_pixbuf);
711
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_ERROR, &error_pixbuf);
712

    
713
        if (prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS ||
714
            (prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL &&
715
             !autocheck)) {
716
                dialog->show_dialog = TRUE;
717
                gtk_widget_show_now(progress->window);
718
        }
719

    
720
        dialog->dialog = progress;
721
        g_get_current_time(&dialog->progress_tv);
722
        g_get_current_time(&dialog->folder_tv);
723
        dialog->queue_list = NULL;
724
        dialog->cur_row = 0;
725

    
726
        inc_dialog_list = g_list_append(inc_dialog_list, dialog);
727

    
728
        return dialog;
729
}
730

    
731
static void inc_progress_dialog_set_list(IncProgressDialog *inc_dialog)
732
{
733
        GList *list;
734

    
735
        for (list = inc_dialog->queue_list; list != NULL; list = list->next) {
736
                IncSession *session = list->data;
737
                Pop3Session *pop3_session = POP3_SESSION(session->session);
738

    
739
                session->data = inc_dialog;
740
                progress_dialog_append(inc_dialog->dialog, NULL,
741
                                       pop3_session->ac_prefs->account_name,
742
                                       _("Standby"), "", NULL);
743
        }
744
}
745

    
746
static void inc_progress_dialog_clear(IncProgressDialog *inc_dialog)
747
{
748
        progress_dialog_set_value(inc_dialog->dialog, 0.0);
749
        progress_dialog_set_label(inc_dialog->dialog, "");
750
        main_window_progress_off(inc_dialog->mainwin);
751
}
752

    
753
static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
754
{
755
        g_return_if_fail(inc_dialog != NULL);
756

    
757
        inc_dialog_list = g_list_remove(inc_dialog_list, inc_dialog);
758

    
759
        manage_window_destroy(inc_dialog->dialog->window, NULL);
760

    
761
        main_window_progress_off(inc_dialog->mainwin);
762
        progress_dialog_destroy(inc_dialog->dialog);
763

    
764
        g_free(inc_dialog);
765
}
766

    
767
static IncSession *inc_session_new(PrefsAccount *account)
768
{
769
        IncSession *session;
770
        FilterRule *rule;
771

    
772
        g_return_val_if_fail(account != NULL, NULL);
773

    
774
        if (account->protocol != A_POP3)
775
                return NULL;
776
        if (!account->recv_server || !account->userid)
777
                return NULL;
778

    
779
        session = g_new0(IncSession, 1);
780

    
781
        session->session = pop3_session_new(account);
782
        session->session->data = session;
783
        POP3_SESSION(session->session)->drop_message = inc_drop_message;
784
        session_set_recv_message_notify(session->session,
785
                                        inc_recv_message, session);
786
        session_set_recv_data_progressive_notify(session->session,
787
                                                 inc_recv_data_progressive,
788
                                                 session);
789
        session_set_recv_data_notify(session->session,
790
                                     inc_recv_data_finished, session);
791

    
792
        session->inc_state = INC_SUCCESS;
793

    
794
        session->folder_table = g_hash_table_new(NULL, NULL);
795
        session->tmp_folder_table = g_hash_table_new(NULL, NULL);
796

    
797
        rule = filter_junk_rule_create(account, NULL, FALSE);
798
        if (rule)
799
                session->junk_fltlist = g_slist_append(NULL, rule);
800
        else
801
                session->junk_fltlist = NULL;
802

    
803
        session->cur_total_bytes = 0;
804
        session->new_msgs = 0;
805

    
806
        session->start_num = 0;
807
        session->start_recv_bytes = 0;
808

    
809
        session->retr_count = 0;
810

    
811
        return session;
812
}
813

    
814
static void inc_session_destroy(IncSession *session)
815
{
816
        g_return_if_fail(session != NULL);
817

    
818
        session_destroy(session->session);
819
        g_hash_table_destroy(session->folder_table);
820
        g_hash_table_destroy(session->tmp_folder_table);
821
        if (session->junk_fltlist)
822
                filter_rule_list_free(session->junk_fltlist);
823
        g_free(session);
824
}
825

    
826
static void inc_update_folder_foreach(GHashTable *table)
827
{
828
        procmsg_flush_folder_foreach(table);
829
        folderview_update_item_foreach(table, TRUE);
830
}
831

    
832
static gint inc_start(IncProgressDialog *inc_dialog)
833
{
834
        IncSession *session;
835
        GList *qlist;
836
        Pop3Session *pop3_session;
837
        IncState inc_state;
838
        gint error_num = 0;
839
        gint new_msgs = 0;
840
        gchar *msg;
841
        gchar *fin_msg;
842

    
843
        qlist = inc_dialog->queue_list;
844
        while (qlist != NULL) {
845
                GList *next = qlist->next;
846

    
847
                session = qlist->data;
848
                if (session->inc_state == INC_CANCEL) {
849
                        qlist = next;
850
                        continue;
851
                }
852

    
853
                pop3_session = POP3_SESSION(session->session); 
854
                if (!pop3_session->pass) {
855
                        gchar *pass;
856

    
857
                        if (inc_dialog->show_dialog)
858
                                manage_window_focus_in
859
                                        (inc_dialog->dialog->window,
860
                                         NULL, NULL);
861

    
862
                        pass = input_query_password
863
                                (pop3_session->ac_prefs->recv_server,
864
                                 pop3_session->user);
865

    
866
                        if (inc_dialog->show_dialog)
867
                                manage_window_focus_out
868
                                        (inc_dialog->dialog->window,
869
                                         NULL, NULL);
870

    
871
                        if (pass) {
872
                                pop3_session->ac_prefs->tmp_pass =
873
                                        g_strdup(pass);
874
                                pop3_session->pass = pass;
875
                        }
876
                }
877

    
878
                qlist = next;
879
        }
880

    
881
#define SET_PIXMAP_AND_TEXT(pixbuf, status, progress)                        \
882
{                                                                        \
883
        progress_dialog_set_row_pixbuf(inc_dialog->dialog,                \
884
                                       inc_dialog->cur_row, pixbuf);        \
885
        progress_dialog_set_row_status(inc_dialog->dialog,                \
886
                                       inc_dialog->cur_row, status);        \
887
        if (progress)                                                        \
888
                progress_dialog_set_row_progress(inc_dialog->dialog,        \
889
                                                 inc_dialog->cur_row,        \
890
                                                 progress);                \
891
}
892

    
893
        for (; inc_dialog->queue_list != NULL; inc_dialog->cur_row++) {
894
                session = inc_dialog->queue_list->data;
895
                pop3_session = POP3_SESSION(session->session);
896

    
897
                if (session->inc_state == INC_CANCEL ||
898
                    pop3_session->pass == NULL) {
899
                        SET_PIXMAP_AND_TEXT(ok_pixbuf, _("Cancelled"), NULL);
900
                        inc_session_destroy(session);
901
                        inc_dialog->queue_list =
902
                                g_list_remove(inc_dialog->queue_list, session);
903
                        continue;
904
                }
905

    
906
                inc_progress_dialog_clear(inc_dialog);
907
                progress_dialog_scroll_to_row(inc_dialog->dialog,
908
                                              inc_dialog->cur_row);
909

    
910
                SET_PIXMAP_AND_TEXT(current_pixbuf, _("Retrieving"), NULL);
911

    
912
                /* begin POP3 session */
913
                inc_state = inc_pop3_session_do(session);
914

    
915
                switch (inc_state) {
916
                case INC_SUCCESS:
917
                        if (pop3_session->cur_total_num > 0)
918
                                msg = g_strdup_printf
919
                                        (_("%d message(s) (%s) received"),
920
                                         pop3_session->cur_total_num,
921
                                         to_human_readable(pop3_session->cur_total_recv_bytes));
922
                        else
923
                                msg = g_strdup_printf(_("no new messages"));
924
                        SET_PIXMAP_AND_TEXT(ok_pixbuf, _("Done"), msg);
925
                        g_free(msg);
926
                        break;
927
                case INC_LOOKUP_ERROR:
928
                        SET_PIXMAP_AND_TEXT(error_pixbuf,
929
                                            _("Server not found"), NULL);
930
                        break;
931
                case INC_CONNECT_ERROR:
932
                        SET_PIXMAP_AND_TEXT(error_pixbuf,
933
                                            _("Connection failed"), NULL);
934
                        break;
935
                case INC_AUTH_FAILED:
936
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Auth failed"),
937
                                            NULL);
938
                        break;
939
                case INC_LOCKED:
940
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Locked"), NULL);
941
                        break;
942
                case INC_ERROR:
943
                case INC_NO_SPACE:
944
                case INC_IO_ERROR:
945
                case INC_SOCKET_ERROR:
946
                case INC_EOF:
947
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Error"), NULL);
948
                        break;
949
                case INC_TIMEOUT:
950
                        SET_PIXMAP_AND_TEXT(error_pixbuf, _("Timeout"), NULL);
951
                        break;
952
                case INC_CANCEL:
953
                        SET_PIXMAP_AND_TEXT(ok_pixbuf, _("Cancelled"), NULL);
954
                        break;
955
                default:
956
                        break;
957
                }
958

    
959
                if (inc_dialog->result)
960
                        inc_dialog->result->count_list = inc_add_message_count(inc_dialog->result->count_list, pop3_session->ac_prefs, session->new_msgs);
961
                new_msgs += session->new_msgs;
962

    
963
                if (!prefs_common.scan_all_after_inc) {
964
                        inc_update_folder_foreach(session->folder_table);
965
                }
966

    
967
                if (pop3_session->error_val == PS_AUTHFAIL &&
968
                    pop3_session->ac_prefs->tmp_pass) {
969
                        g_free(pop3_session->ac_prefs->tmp_pass);
970
                        pop3_session->ac_prefs->tmp_pass = NULL;
971
                }
972

    
973
                pop3_write_uidl_list(pop3_session);
974

    
975
                if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) {
976
                        error_num++;
977
                        if (inc_dialog->show_dialog)
978
                                manage_window_focus_in
979
                                        (inc_dialog->dialog->window,
980
                                         NULL, NULL);
981
                        inc_put_error(session, inc_state,
982
                                      pop3_session->error_msg);
983
                        if (inc_dialog->show_dialog)
984
                                manage_window_focus_out
985
                                        (inc_dialog->dialog->window,
986
                                         NULL, NULL);
987
                        if (inc_state == INC_NO_SPACE ||
988
                            inc_state == INC_IO_ERROR)
989
                                break;
990
                }
991

    
992
                inc_session_destroy(session);
993
                inc_dialog->queue_list =
994
                        g_list_remove(inc_dialog->queue_list, session);
995
        }
996

    
997
#undef SET_PIXMAP_AND_TEXT
998

    
999
        if (new_msgs > 0)
1000
                fin_msg = g_strdup_printf(_("Finished (%d new message(s))"),
1001
                                          new_msgs);
1002
        else
1003
                fin_msg = g_strdup_printf(_("Finished (no new messages)"));
1004

    
1005
        progress_dialog_set_label(inc_dialog->dialog, fin_msg);
1006

    
1007
#if 0
1008
        if (error_num && !prefs_common.no_recv_err_panel) {
1009
                if (inc_dialog->show_dialog)
1010
                        manage_window_focus_in(inc_dialog->dialog->window,
1011
                                               NULL, NULL);
1012
                alertpanel_error(_("Some errors occurred while getting mail."));
1013
                if (inc_dialog->show_dialog)
1014
                        manage_window_focus_out(inc_dialog->dialog->window,
1015
                                                NULL, NULL);
1016
        }
1017
#endif
1018

    
1019
        while (inc_dialog->queue_list != NULL) {
1020
                session = inc_dialog->queue_list->data;
1021
                inc_session_destroy(session);
1022
                inc_dialog->queue_list =
1023
                        g_list_remove(inc_dialog->queue_list, session);
1024
        }
1025

    
1026
        if (prefs_common.close_recv_dialog || !inc_dialog->show_dialog)
1027
                inc_progress_dialog_destroy(inc_dialog);
1028
        else {
1029
                gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
1030
                                     fin_msg);
1031
                gtk_button_set_label(GTK_BUTTON(inc_dialog->dialog->cancel_btn),
1032
                                     GTK_STOCK_CLOSE);
1033
        }
1034

    
1035
        g_free(fin_msg);
1036

    
1037
        return new_msgs;
1038
}
1039

    
1040
static IncState inc_pop3_session_do(IncSession *session)
1041
{
1042
        Pop3Session *pop3_session = POP3_SESSION(session->session);
1043
        IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data;
1044
        PrefsAccount *ac = pop3_session->ac_prefs;
1045
        SocksInfo *socks_info = NULL;
1046
        gchar *buf;
1047

    
1048
        debug_print(_("getting new messages of account %s...\n"),
1049
                    ac->account_name);
1050

    
1051
        if (pop3_session->auth_only)
1052
                buf = g_strdup_printf(_("%s: Authenticating with POP3"),
1053
                                      ac->recv_server);
1054
        else
1055
                buf = g_strdup_printf(_("%s: Retrieving new messages"),
1056
                                      ac->recv_server);
1057
        gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf);
1058
        g_free(buf);
1059

    
1060
        buf = g_strdup_printf(_("Connecting to POP3 server: %s..."),
1061
                              ac->recv_server);
1062
        log_message("%s\n", buf);
1063
        progress_dialog_set_label(inc_dialog->dialog, buf);
1064
        g_free(buf);
1065

    
1066
        session_set_timeout(SESSION(pop3_session),
1067
                            prefs_common.io_timeout_secs * 1000);
1068

    
1069
        if (ac->use_socks && ac->use_socks_for_recv) {
1070
                socks_info = socks_info_new(ac->socks_type, ac->proxy_host, ac->proxy_port, ac->use_proxy_auth ? ac->proxy_name : NULL, ac->use_proxy_auth ? ac->proxy_pass : NULL);
1071
        }
1072

    
1073
        GTK_EVENTS_FLUSH();
1074

    
1075
        if (session_connect_full(SESSION(pop3_session),
1076
                                 SESSION(pop3_session)->server,
1077
                                 SESSION(pop3_session)->port, socks_info) < 0) {
1078
                log_warning(_("Can't connect to POP3 server: %s:%d\n"),
1079
                            SESSION(pop3_session)->server,
1080
                            SESSION(pop3_session)->port);
1081
                session->inc_state = INC_CONNECT_ERROR;
1082
                if (session_get_error(SESSION(pop3_session)) == SESSION_ERROR_LOOKUP)
1083
                        session->inc_state = INC_LOOKUP_ERROR;
1084
                statusbar_pop_all();
1085
                return session->inc_state;
1086
        }
1087

    
1088
        while (session_is_connected(SESSION(pop3_session)) &&
1089
               session->inc_state != INC_CANCEL) {
1090
                gtk_main_iteration();
1091
        }
1092
        log_window_flush();
1093

    
1094
        debug_print("inc_state: %d\n", session->inc_state);
1095
        debug_print("pop3_session.error_val: %d\n", pop3_session->error_val);
1096
        debug_print("pop3_session.error_msg: %s\n", pop3_session->error_msg ? pop3_session->error_msg : "(empty)");
1097

    
1098
        if (session->inc_state == INC_SUCCESS) {
1099
                switch (pop3_session->error_val) {
1100
                case PS_SUCCESS:
1101
                        switch (SESSION(pop3_session)->state) {
1102
                        case SESSION_ERROR:
1103
                                if (pop3_session->state == POP3_READY)
1104
                                        session->inc_state = INC_CONNECT_ERROR;
1105
                                else
1106
                                        session->inc_state = INC_ERROR;
1107
                                if (session_get_error(SESSION(pop3_session)) == SESSION_ERROR_LOOKUP)
1108
                                        session->inc_state = INC_LOOKUP_ERROR;
1109
                                break;
1110
                        case SESSION_EOF:
1111
                                session->inc_state = INC_EOF;
1112
                                break;
1113
                        case SESSION_TIMEOUT:
1114
                                session->inc_state = INC_TIMEOUT;
1115
                                break;
1116
                        default:
1117
                                session->inc_state = INC_SUCCESS;
1118
                                break;
1119
                        }
1120
                        break;
1121
                case PS_AUTHFAIL:
1122
                        session->inc_state = INC_AUTH_FAILED;
1123
                        break;
1124
                case PS_IOERR:
1125
                        session->inc_state = INC_IO_ERROR;
1126
                        break;
1127
                case PS_SOCKET:
1128
                        session->inc_state = INC_SOCKET_ERROR;
1129
                        break;
1130
                case PS_LOCKBUSY:
1131
                        session->inc_state = INC_LOCKED;
1132
                        break;
1133
                default:
1134
                        session->inc_state = INC_ERROR;
1135
                        break;
1136
                }
1137
        }
1138

    
1139
        session_disconnect(SESSION(pop3_session));
1140
        statusbar_pop_all();
1141

    
1142
        return session->inc_state;
1143
}
1144

    
1145
static void inc_progress_dialog_update(IncProgressDialog *inc_dialog,
1146
                                       IncSession *inc_session)
1147
{
1148
        inc_progress_dialog_set_label(inc_dialog, inc_session);
1149
        inc_progress_dialog_set_progress(inc_dialog, inc_session);
1150
}
1151

    
1152
static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
1153
                                          IncSession *inc_session)
1154
{
1155
        ProgressDialog *dialog = inc_dialog->dialog;
1156
        Pop3Session *session;
1157

    
1158
        g_return_if_fail(inc_session != NULL);
1159

    
1160
        session = POP3_SESSION(inc_session->session);
1161

    
1162
        switch (session->state) {
1163
        case POP3_GREETING:
1164
                break;
1165
        case POP3_GETAUTH_USER:
1166
        case POP3_GETAUTH_PASS:
1167
        case POP3_GETAUTH_APOP:
1168
                progress_dialog_set_label(dialog, _("Authenticating..."));
1169
                statusbar_print_all(_("Retrieving messages from %s..."),
1170
                                    SESSION(session)->server);
1171
                break;
1172
        case POP3_GETRANGE_STAT:
1173
                progress_dialog_set_label
1174
                        (dialog, _("Getting the number of new messages (STAT)..."));
1175
                break;
1176
        case POP3_GETRANGE_LAST:
1177
                progress_dialog_set_label
1178
                        (dialog, _("Getting the number of new messages (LAST)..."));
1179
                break;
1180
        case POP3_GETRANGE_UIDL:
1181
                progress_dialog_set_label
1182
                        (dialog, _("Getting the number of new messages (UIDL)..."));
1183
                break;
1184
        case POP3_GETSIZE_LIST:
1185
                progress_dialog_set_label
1186
                        (dialog, _("Getting the size of messages (LIST)..."));
1187
                break;
1188
        case POP3_RETR:
1189
        case POP3_RETR_RECV:
1190
                break;
1191
        case POP3_DELETE:
1192
#if 0
1193
                if (session->msg[session->cur_msg].recv_time <
1194
                        session->current_time) {
1195
                        gchar buf[BUFFSIZE];
1196
                        g_snprintf(buf, sizeof(buf), _("Deleting message %d"),
1197
                                   session->cur_msg);
1198
                        progress_dialog_set_label(dialog, buf);
1199
                }
1200
#endif
1201
                break;
1202
        case POP3_LOGOUT:
1203
                progress_dialog_set_label(dialog, _("Quitting"));
1204
                break;
1205
        default:
1206
                break;
1207
        }
1208
}
1209

    
1210
static void inc_progress_dialog_set_progress(IncProgressDialog *inc_dialog,
1211
                                             IncSession *inc_session)
1212
{
1213
        gchar buf[BUFFSIZE];
1214
        Pop3Session *pop3_session = POP3_SESSION(inc_session->session);
1215
        gint64 cur_total;
1216
        gint64 total;
1217
        gint cur_num;
1218
        gint total_num_to_recv;
1219

    
1220
        if (!pop3_session->new_msg_exist) return;
1221

    
1222
        if (inc_session->retr_count == 0) {
1223
                cur_num = total_num_to_recv = 0;
1224
                cur_total = total = 0;
1225
        } else {
1226
                cur_num = pop3_session->cur_msg - inc_session->start_num + 1;
1227
                total_num_to_recv = pop3_session->count - inc_session->start_num + 1;
1228
                cur_total = inc_session->cur_total_bytes - inc_session->start_recv_bytes;
1229
                total = pop3_session->total_bytes - inc_session->start_recv_bytes;
1230
        }
1231

    
1232
        if ((pop3_session->state == POP3_RETR ||
1233
             pop3_session->state == POP3_RETR_RECV ||
1234
             pop3_session->state == POP3_DELETE) && total_num_to_recv > 0) {
1235
                gchar total_size_str[16];
1236

    
1237
                to_human_readable_buf(total_size_str, sizeof(total_size_str),
1238
                                      total);
1239
                g_snprintf(buf, sizeof(buf),
1240
                           _("Retrieving message (%d / %d) (%s / %s)"),
1241
                           cur_num, total_num_to_recv,
1242
                           to_human_readable(cur_total), total_size_str);
1243
                progress_dialog_set_label(inc_dialog->dialog, buf);
1244
        }
1245

    
1246
        if (total > 0)
1247
                progress_dialog_set_percentage
1248
                        (inc_dialog->dialog, (gfloat)cur_total / (gfloat)total);
1249

    
1250
        gtk_progress_set_show_text
1251
                (GTK_PROGRESS(inc_dialog->mainwin->progressbar), TRUE);
1252
        if (total_num_to_recv > 0)
1253
                g_snprintf(buf, sizeof(buf), "%d / %d", cur_num, total_num_to_recv);
1254
        else
1255
                buf[0] = '\0';
1256
        gtk_progress_set_format_string
1257
                (GTK_PROGRESS(inc_dialog->mainwin->progressbar), buf);
1258
        if (total > 0)
1259
                gtk_progress_bar_update
1260
                        (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar),
1261
                         (gfloat)cur_total / (gfloat)total);
1262

    
1263
        if (pop3_session->cur_total_num > 0) {
1264
                g_snprintf(buf, sizeof(buf),
1265
                           _("%d message(s) (%s) received"),
1266
                           pop3_session->cur_total_num,
1267
                           to_human_readable(pop3_session->cur_total_recv_bytes));
1268
                progress_dialog_set_row_progress(inc_dialog->dialog,
1269
                                                 inc_dialog->cur_row, buf);
1270
        }
1271
}
1272

    
1273
static gboolean hash_remove_func(gpointer key, gpointer value, gpointer data)
1274
{
1275
        return TRUE;
1276
}
1277

    
1278
static void inc_update_folderview(IncProgressDialog *inc_dialog,
1279
                                  IncSession *inc_session)
1280
{
1281
        MainWindow *mainwin;
1282

    
1283
        if (g_hash_table_size(inc_session->tmp_folder_table) > 0) {
1284
                folderview_update_item_foreach(inc_session->tmp_folder_table,
1285
                                               FALSE);
1286
                g_hash_table_foreach_remove(inc_session->tmp_folder_table,
1287
                                            hash_remove_func, NULL);
1288
        }
1289

    
1290
        mainwin = main_window_get();
1291
        summary_show_queued_msgs(mainwin->summaryview);
1292
}
1293

    
1294
static void inc_progress_dialog_update_periodic(IncProgressDialog *inc_dialog,
1295
                                                IncSession *inc_session)
1296
{
1297
        GTimeVal tv_cur;
1298
        GTimeVal tv_result;
1299
        gint msec;
1300

    
1301
        g_get_current_time(&tv_cur);
1302

    
1303
        tv_result.tv_sec = tv_cur.tv_sec - inc_dialog->progress_tv.tv_sec;
1304
        tv_result.tv_usec = tv_cur.tv_usec - inc_dialog->progress_tv.tv_usec;
1305
        if (tv_result.tv_usec < 0) {
1306
                tv_result.tv_sec--;
1307
                tv_result.tv_usec += G_USEC_PER_SEC;
1308
        }
1309

    
1310
        msec = tv_result.tv_sec * 1000 + tv_result.tv_usec / 1000;
1311
        if (msec > PROGRESS_UPDATE_INTERVAL) {
1312
                inc_progress_dialog_update(inc_dialog, inc_session);
1313
                inc_dialog->progress_tv.tv_sec = tv_cur.tv_sec;
1314
                inc_dialog->progress_tv.tv_usec = tv_cur.tv_usec;
1315
        }
1316
}
1317

    
1318
static void inc_update_folderview_periodic(IncProgressDialog *inc_dialog,
1319
                                           IncSession *inc_session)
1320
{
1321
        GTimeVal tv_cur;
1322
        GTimeVal tv_result;
1323
        gint msec;
1324

    
1325
        g_get_current_time(&tv_cur);
1326

    
1327
        tv_result.tv_sec = tv_cur.tv_sec - inc_dialog->folder_tv.tv_sec;
1328
        tv_result.tv_usec = tv_cur.tv_usec - inc_dialog->folder_tv.tv_usec;
1329
        if (tv_result.tv_usec < 0) {
1330
                tv_result.tv_sec--;
1331
                tv_result.tv_usec += G_USEC_PER_SEC;
1332
        }
1333

    
1334
        msec = tv_result.tv_sec * 1000 + tv_result.tv_usec / 1000;
1335
        if (msec > FOLDER_UPDATE_INTERVAL) {
1336
                inc_update_folderview(inc_dialog, inc_session);
1337
                inc_dialog->folder_tv.tv_sec = tv_cur.tv_sec;
1338
                inc_dialog->folder_tv.tv_usec = tv_cur.tv_usec;
1339
        }
1340
}
1341

    
1342
static gint inc_recv_data_progressive(Session *session, guint cur_len,
1343
                                      guint total_len, gpointer data)
1344
{
1345
        IncSession *inc_session = (IncSession *)data;
1346
        Pop3Session *pop3_session = POP3_SESSION(session);
1347
        IncProgressDialog *inc_dialog;
1348
        gint64 cur_total;
1349

    
1350
        g_return_val_if_fail(inc_session != NULL, -1);
1351

    
1352
        if (pop3_session->state != POP3_RETR &&
1353
            pop3_session->state != POP3_RETR_RECV &&
1354
            pop3_session->state != POP3_DELETE &&
1355
            pop3_session->state != POP3_LOGOUT) return 0;
1356

    
1357
        if (!pop3_session->new_msg_exist) return 0;
1358

    
1359
        gdk_threads_enter();
1360

    
1361
        cur_total = pop3_session->cur_total_bytes + cur_len;
1362
        if (cur_total > pop3_session->total_bytes)
1363
                cur_total = pop3_session->total_bytes;
1364
        inc_session->cur_total_bytes = cur_total;
1365

    
1366
        inc_dialog = (IncProgressDialog *)inc_session->data;
1367
        inc_progress_dialog_update_periodic(inc_dialog, inc_session);
1368
        inc_update_folderview_periodic(inc_dialog, inc_session);
1369

    
1370
        gdk_threads_leave();
1371
        return 0;
1372
}
1373

    
1374
static gint inc_recv_data_finished(Session *session, guint len, gpointer data)
1375
{
1376
        IncSession *inc_session = (IncSession *)data;
1377
        IncProgressDialog *inc_dialog;
1378

    
1379
        g_return_val_if_fail(inc_session != NULL, -1);
1380

    
1381
        inc_dialog = (IncProgressDialog *)inc_session->data;
1382

    
1383
        inc_recv_data_progressive(session, 0, 0, inc_session);
1384

    
1385
        gdk_threads_enter();
1386

    
1387
        if (POP3_SESSION(session)->state == POP3_LOGOUT) {
1388
                inc_progress_dialog_update(inc_dialog, inc_session);
1389
                inc_update_folderview(inc_dialog, inc_session);
1390
        }
1391

    
1392
        gdk_threads_leave();
1393
        return 0;
1394
}
1395

    
1396
static gint inc_recv_message(Session *session, const gchar *msg, gpointer data)
1397
{
1398
        IncSession *inc_session = (IncSession *)data;
1399
        IncProgressDialog *inc_dialog;
1400
        Pop3Session *pop3_session = POP3_SESSION(session);
1401

    
1402
        g_return_val_if_fail(inc_session != NULL, -1);
1403

    
1404
        inc_dialog = (IncProgressDialog *)inc_session->data;
1405

    
1406
        switch (POP3_SESSION(session)->state) {
1407
        case POP3_GETAUTH_USER:
1408
        case POP3_GETAUTH_PASS:
1409
        case POP3_GETAUTH_APOP:
1410
        case POP3_GETRANGE_STAT:
1411
        case POP3_GETRANGE_LAST:
1412
        case POP3_GETRANGE_UIDL:
1413
        case POP3_GETSIZE_LIST:
1414
                gdk_threads_enter();
1415
                inc_progress_dialog_update(inc_dialog, inc_session);
1416
                gdk_threads_leave();
1417
                break;
1418
        case POP3_RETR_RECV:
1419
                if (inc_session->retr_count == 0) {
1420
                        inc_session->start_num = pop3_session->cur_msg;
1421
                        inc_session->start_recv_bytes = pop3_session->cur_total_bytes;
1422
                        inc_session->cur_total_bytes = pop3_session->cur_total_bytes;
1423
#if 0
1424
                        g_print("total_bytes_to_recv = %lld total_num_to_recv = %d\n", pop3_session->total_bytes - inc_session->start_recv_bytes, pop3_session->count - inc_session->start_num + 1);
1425
                        g_print("pop: total_bytes = %lld cur_total_bytes = %lld\n", pop3_session->total_bytes, pop3_session->cur_total_bytes);
1426
                        g_print("pop: count = %d cur_msg = %d\n", pop3_session->count, pop3_session->cur_msg);
1427
#endif
1428
                        inc_session->retr_count++;
1429
                        gdk_threads_enter();
1430
                        inc_progress_dialog_update(inc_dialog, inc_session);
1431
                        gdk_threads_leave();
1432
                } else {
1433
                        inc_session->retr_count++;
1434
                        inc_recv_data_progressive(session, 0, 0, inc_session);
1435
                }
1436
                break;
1437
        case POP3_LOGOUT:
1438
                gdk_threads_enter();
1439
                inc_progress_dialog_update(inc_dialog, inc_session);
1440
                inc_update_folderview(inc_dialog, inc_session);
1441
                gdk_threads_leave();
1442
                break;
1443
        default:
1444
                break;
1445
        }
1446

    
1447
        return 0;
1448
}
1449

    
1450
/**
1451
 * inc_drop_message:
1452
 * @session: Current Pop3Session.
1453
 * @file: Received message file.
1454
 * 
1455
 * Callback function to drop received message into local mailbox.
1456
 *
1457
 * Return value: DROP_OK if succeeded. DROP_ERROR if error occurred.
1458
 *   DROP_DONT_RECEIVE if the message should be skipped.
1459
 *   DROP_DELETE if the message should be deleted.
1460
 **/
1461
static gint inc_drop_message(Pop3Session *session, const gchar *file)
1462
{
1463
        FolderItem *inbox;
1464
        GSList *cur;
1465
        MsgInfo *msginfo;
1466
        FilterInfo *fltinfo;
1467
        IncSession *inc_session = (IncSession *)(SESSION(session)->data);
1468
        gint val;
1469
        gboolean is_junk = FALSE;
1470
        gboolean is_counted = FALSE;
1471
        IncProgressDialog *inc_dialog;
1472

    
1473
        g_return_val_if_fail(inc_session != NULL, DROP_ERROR);
1474

    
1475
        gdk_threads_enter();
1476

    
1477
        inc_dialog = (IncProgressDialog *)inc_session->data;
1478

    
1479
        if (session->ac_prefs->inbox) {
1480
                inbox = folder_find_item_from_identifier
1481
                        (session->ac_prefs->inbox);
1482
                if (!inbox)
1483
                        inbox = folder_get_default_inbox();
1484
        } else
1485
                inbox = folder_get_default_inbox();
1486
        if (!inbox) {
1487
                gdk_threads_leave();
1488
                return DROP_ERROR;
1489
        }
1490

    
1491
        fltinfo = filter_info_new();
1492
        fltinfo->account = session->ac_prefs;
1493
        fltinfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
1494
        fltinfo->flags.tmp_flags = MSG_RECEIVED;
1495

    
1496
        msginfo = procheader_parse_file(file, fltinfo->flags, FALSE);
1497
        if (!msginfo) {
1498
                g_warning("inc_drop_message: procheader_parse_file failed");
1499
                filter_info_free(fltinfo);
1500
                gdk_threads_leave();
1501
                return DROP_ERROR;
1502
        }
1503
        fltinfo->flags = msginfo->flags;
1504
        msginfo->file_path = g_strdup(file);
1505

    
1506
        if (prefs_common.enable_junk &&
1507
            prefs_common.filter_junk_on_recv &&
1508
            prefs_common.filter_junk_before &&
1509
            inc_session->junk_fltlist) {
1510
                filter_apply_msginfo(inc_session->junk_fltlist, msginfo,
1511
                                     fltinfo);
1512
                if (fltinfo->drop_done)
1513
                        is_junk = TRUE;
1514
                else if (fltinfo->error == FLT_ERROR_EXEC_FAILED ||
1515
                         fltinfo->last_exec_exit_status >= 3) {
1516
                        g_warning("inc_drop_message: junk filter command returned %d",
1517
                                  fltinfo->last_exec_exit_status);
1518
                        alertpanel_error
1519
                                (_("Execution of the junk filter command failed.\n"
1520
                                   "Please check the junk mail control setting."));
1521
                        procmsg_msginfo_free(msginfo);
1522
                        filter_info_free(fltinfo);
1523
                        inc_session->inc_state = INC_ERROR;
1524
                        gdk_threads_leave();
1525
                        return DROP_ERROR;
1526
                }
1527
        }
1528

    
1529
        if (!fltinfo->drop_done && session->ac_prefs->filter_on_recv)
1530
                filter_apply_msginfo(prefs_common.fltlist, msginfo, fltinfo);
1531

    
1532
        if (!fltinfo->drop_done) {
1533
                if (prefs_common.enable_junk &&
1534
                    prefs_common.filter_junk_on_recv &&
1535
                    !prefs_common.filter_junk_before &&
1536
                    inc_session->junk_fltlist) {
1537
                        filter_apply_msginfo(inc_session->junk_fltlist,
1538
                                             msginfo, fltinfo);
1539
                        if (fltinfo->drop_done)
1540
                                is_junk = TRUE;
1541
                        else if (fltinfo->error == FLT_ERROR_EXEC_FAILED ||
1542
                                 fltinfo->last_exec_exit_status >= 3) {
1543
                                g_warning("inc_drop_message: junk filter command returned %d",
1544
                                          fltinfo->last_exec_exit_status);
1545
                                alertpanel_error
1546
                                        (_("Execution of the junk filter command failed.\n"
1547
                                           "Please check the junk mail control setting."));
1548
                                procmsg_msginfo_free(msginfo);
1549
                                filter_info_free(fltinfo);
1550
                                inc_session->inc_state = INC_ERROR;
1551
                                gdk_threads_leave();
1552
                                return DROP_ERROR;
1553
                        }
1554
                }
1555
        }
1556

    
1557
        if (!fltinfo->drop_done) {
1558
                msginfo->flags = fltinfo->flags;
1559
                if (folder_item_add_msg_msginfo(inbox, msginfo, FALSE) < 0) {
1560
                        procmsg_msginfo_free(msginfo);
1561
                        filter_info_free(fltinfo);
1562
                        gdk_threads_leave();
1563
                        return DROP_ERROR;
1564
                }
1565
                fltinfo->dest_list = g_slist_append(fltinfo->dest_list, inbox);
1566
        }
1567

    
1568
        for (cur = fltinfo->dest_list; cur != NULL; cur = cur->next) {
1569
                FolderItem *drop_folder = (FolderItem *)cur->data;
1570

    
1571
                val = GPOINTER_TO_INT(g_hash_table_lookup
1572
                                      (inc_session->folder_table, drop_folder));
1573
                if (val == 0)
1574
                        g_hash_table_insert(inc_session->folder_table,
1575
                                            drop_folder, GINT_TO_POINTER(1));
1576
                g_hash_table_insert(inc_session->tmp_folder_table, drop_folder,
1577
                                    GINT_TO_POINTER(1));
1578

    
1579
                if (drop_folder->stype != F_TRASH &&
1580
                    drop_folder->stype != F_JUNK)
1581
                        is_counted = TRUE;
1582
        }
1583

    
1584
        if (fltinfo->actions[FLT_ACTION_NOT_RECEIVE] == TRUE)
1585
                val = DROP_DONT_RECEIVE;
1586
        else if (fltinfo->actions[FLT_ACTION_DELETE] == TRUE)
1587
                val = DROP_DELETE;
1588
        else {
1589
                val = DROP_OK;
1590
                if (!is_junk && is_counted &&
1591
                    fltinfo->actions[FLT_ACTION_MARK_READ] == FALSE) {
1592
                        inc_session->new_msgs++;
1593

    
1594
                        if (inc_dialog->result && msginfo->subject && g_slist_length(inc_dialog->result->msg_summaries) < 5) {
1595
                                IncMsgSummary *summary;
1596
                                summary = g_new(IncMsgSummary, 1);
1597
                                summary->subject = g_strdup(msginfo->subject);
1598
                                summary->from = g_strdup(msginfo->fromname);
1599
                                inc_dialog->result->msg_summaries = g_slist_append(inc_dialog->result->msg_summaries, summary);
1600
                        }
1601
                }
1602
        }
1603

    
1604
        procmsg_msginfo_free(msginfo);
1605
        filter_info_free(fltinfo);
1606

    
1607
        gdk_threads_leave();
1608
        return val;
1609
}
1610

    
1611
static void inc_put_error(IncSession *session, IncState istate, const gchar *pop3_msg)
1612
{
1613
        gchar *log_msg = NULL;
1614
        gchar *err_msg = NULL;
1615
        gboolean fatal_error = FALSE;
1616

    
1617
        switch (istate) {
1618
        case INC_LOOKUP_ERROR:
1619
                log_msg = _("Server not found.");
1620
                if (prefs_common.no_recv_err_panel)
1621
                        break;
1622
                err_msg = g_strdup_printf
1623
                        (_("Server %s not found."), session->session->server);
1624
                break;
1625
        case INC_CONNECT_ERROR:
1626
                log_msg = _("Connection failed.");
1627
                if (prefs_common.no_recv_err_panel)
1628
                        break;
1629
                err_msg = g_strdup_printf
1630
                        (_("Connection to %s:%d failed."),
1631
                         session->session->server, session->session->port);
1632
                break;
1633
        case INC_ERROR:
1634
                log_msg = _("Error occurred while processing mail.");
1635
                if (prefs_common.no_recv_err_panel)
1636
                        break;
1637
                if (pop3_msg)
1638
                        err_msg = g_strdup_printf
1639
                                (_("Error occurred while processing mail:\n%s"),
1640
                                 pop3_msg);
1641
                else
1642
                        err_msg = g_strdup(log_msg);
1643
                break;
1644
        case INC_NO_SPACE:
1645
                log_msg = _("No disk space left.");
1646
                err_msg = g_strdup(log_msg);
1647
                fatal_error = TRUE;
1648
                break;
1649
        case INC_IO_ERROR:
1650
                log_msg = _("Can't write file.");
1651
                err_msg = g_strdup(log_msg);
1652
                fatal_error = TRUE;
1653
                break;
1654
        case INC_SOCKET_ERROR:
1655
                log_msg = _("Socket error.");
1656
                if (prefs_common.no_recv_err_panel)
1657
                        break;
1658
                err_msg = g_strdup(log_msg);
1659
                break;
1660
        case INC_EOF:
1661
                log_msg = _("Connection closed by the remote host.");
1662
                if (prefs_common.no_recv_err_panel)
1663
                        break;
1664
                err_msg = g_strdup(log_msg);
1665
                break;
1666
        case INC_LOCKED:
1667
                log_msg = _("Mailbox is locked.");
1668
                if (prefs_common.no_recv_err_panel)
1669
                        break;
1670
                if (pop3_msg)
1671
                        err_msg = g_strdup_printf(_("Mailbox is locked:\n%s"),
1672
                                                  pop3_msg);
1673
                else
1674
                        err_msg = g_strdup(log_msg);
1675
                break;
1676
        case INC_AUTH_FAILED:
1677
                log_msg = _("Authentication failed.");
1678
                if (prefs_common.no_recv_err_panel)
1679
                        break;
1680
                if (pop3_msg)
1681
                        err_msg = g_strdup_printf
1682
                                (_("Authentication failed:\n%s"), pop3_msg);
1683
                else
1684
                        err_msg = g_strdup(log_msg);
1685
                break;
1686
        case INC_TIMEOUT:
1687
                log_msg = _("Session timed out.");
1688
                if (prefs_common.no_recv_err_panel)
1689
                        break;
1690
                err_msg = g_strdup(log_msg);
1691
                break;
1692
        default:
1693
                break;
1694
        }
1695

    
1696
        if (log_msg) {
1697
                if (fatal_error)
1698
                        log_error("%s\n", log_msg);
1699
                else
1700
                        log_warning("%s\n", log_msg);
1701
        }
1702
        if (err_msg) {
1703
                alertpanel_error("%s", err_msg);
1704
                g_free(err_msg);
1705
        }
1706
}
1707

    
1708
static void inc_cancel(IncProgressDialog *dialog, gboolean cancel_all)
1709
{
1710
        IncSession *session;
1711
        GList *list;
1712

    
1713
        g_return_if_fail(dialog != NULL);
1714

    
1715
        if (dialog->queue_list == NULL) {
1716
                inc_progress_dialog_destroy(dialog);
1717
                return;
1718
        }
1719

    
1720
        for (list = dialog->queue_list; list != NULL; list = list->next) {
1721
                session = list->data;
1722
                session->inc_state = INC_CANCEL;
1723
                session_disconnect(session->session);
1724
                if (!cancel_all)
1725
                        break;
1726
        }
1727

    
1728
        log_message(_("Incorporation cancelled\n"));
1729
}
1730

    
1731
gboolean inc_is_active(void)
1732
{
1733
        GList *cur;
1734

    
1735
        if (inc_is_running)
1736
                return TRUE;
1737

    
1738
        if (inc_dialog_list == NULL)
1739
                return FALSE;
1740

    
1741
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next) {
1742
                IncProgressDialog *dialog = cur->data;
1743
                if (dialog->queue_list)
1744
                        return TRUE;
1745
        }
1746

    
1747
        return FALSE;
1748
}
1749

    
1750
void inc_block_notify(gboolean block)
1751
{
1752
        if (!block)
1753
                block_notify = FALSE;
1754
        else if (inc_is_active())
1755
                block_notify = TRUE;
1756
}
1757

    
1758
void inc_cancel_all(void)
1759
{
1760
        GList *cur;
1761

    
1762
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next)
1763
                inc_cancel((IncProgressDialog *)cur->data, TRUE);
1764
}
1765

    
1766
static void inc_cancel_cb(GtkWidget *widget, gpointer data)
1767
{
1768
        inc_cancel((IncProgressDialog *)data, FALSE);
1769
}
1770

    
1771
static void inc_cancel_all_cb(GtkWidget *widget, gpointer data)
1772
{
1773
        inc_cancel((IncProgressDialog *)data, TRUE);
1774
}
1775

    
1776
static gint inc_dialog_delete_cb(GtkWidget *widget, GdkEventAny *event,
1777
                                 gpointer data)
1778
{
1779
        IncProgressDialog *dialog = (IncProgressDialog *)data;
1780

    
1781
        if (dialog->queue_list == NULL)
1782
                inc_progress_dialog_destroy(dialog);
1783
        else
1784
                inc_cancel(dialog, TRUE);
1785

    
1786
        return TRUE;
1787
}
1788

    
1789
static gint inc_spool(void)
1790
{
1791
        gchar *spool_path;
1792
        gchar *mbox;
1793
        gint msgs;
1794

    
1795
        spool_path = prefs_common.spool_path
1796
                ? prefs_common.spool_path : DEFAULT_SPOOL_PATH;
1797
        if (is_file_exist(spool_path))
1798
                mbox = g_strdup(spool_path);
1799
        else if (is_dir_exist(spool_path))
1800
                mbox = g_strconcat(spool_path, G_DIR_SEPARATOR_S,
1801
                                   g_get_user_name(), NULL);
1802
        else {
1803
                debug_print("%s: local mailbox not found.\n", spool_path);
1804
                return -1;
1805
        }
1806

    
1807
        msgs = get_spool(folder_get_default_inbox(), mbox);
1808
        g_free(mbox);
1809

    
1810
        return msgs;
1811
}
1812

    
1813
static gint get_spool(FolderItem *dest, const gchar *mbox)
1814
{
1815
        gint msgs, size;
1816
        gint lockfd;
1817
        gchar tmp_mbox[MAXPATHLEN + 1];
1818
        GHashTable *folder_table = NULL;
1819

    
1820
        g_return_val_if_fail(dest != NULL, -1);
1821
        g_return_val_if_fail(mbox != NULL, -1);
1822

    
1823
        if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
1824
                debug_print("%s: no messages in local mailbox.\n", mbox);
1825
                return 0;
1826
        } else if (size < 0)
1827
                return -1;
1828

    
1829
        if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
1830
                return -1;
1831

    
1832
        g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
1833
                   get_tmp_dir(), G_DIR_SEPARATOR, mbox);
1834

    
1835
        if (copy_mbox(mbox, tmp_mbox) < 0) {
1836
                unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1837
                return -1;
1838
        }
1839

    
1840
        debug_print(_("Getting new messages from %s into %s...\n"),
1841
                    mbox, dest->path);
1842

    
1843
        folder_table = g_hash_table_new(NULL, NULL);
1844

    
1845
        msgs = proc_mbox_full(dest, tmp_mbox, folder_table,
1846
                              prefs_common.filter_on_inc,
1847
                              prefs_common.enable_junk &&
1848
                              prefs_common.filter_junk_on_recv);
1849

    
1850
        g_unlink(tmp_mbox);
1851
        if (msgs >= 0) empty_mbox(mbox);
1852
        unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1853

    
1854
        if (!prefs_common.scan_all_after_inc) {
1855
                inc_update_folder_foreach(folder_table);
1856
        }
1857

    
1858
        g_hash_table_destroy(folder_table);
1859

    
1860
        return msgs;
1861
}
1862

    
1863
void inc_lock(void)
1864
{
1865
        inc_lock_count++;
1866
}
1867

    
1868
void inc_unlock(void)
1869
{
1870
        if (inc_lock_count > 0)
1871
                inc_lock_count--;
1872
}
1873

    
1874
static guint autocheck_timer = 0;
1875
static gpointer autocheck_data = NULL;
1876

    
1877
void inc_autocheck_timer_init(MainWindow *mainwin)
1878
{
1879
        autocheck_data = mainwin;
1880
        inc_autocheck_timer_set();
1881
}
1882

    
1883
static void inc_autocheck_timer_set_interval(guint interval)
1884
{
1885
        inc_autocheck_timer_remove();
1886

    
1887
        if (prefs_common.autochk_newmail && autocheck_data) {
1888
                autocheck_timer = g_timeout_add_full
1889
                        (G_PRIORITY_LOW, interval, inc_autocheck_func,
1890
                         autocheck_data, NULL);
1891
                debug_print("added timer = %d\n", autocheck_timer);
1892
        }
1893
}
1894

    
1895
void inc_autocheck_timer_set(void)
1896
{
1897
        inc_autocheck_timer_set_interval(prefs_common.autochk_itv * 60000);
1898
}
1899

    
1900
void inc_autocheck_timer_remove(void)
1901
{
1902
        if (autocheck_timer) {
1903
                debug_print("removed timer = %d\n", autocheck_timer);
1904
                g_source_remove(autocheck_timer);
1905
                autocheck_timer = 0;
1906
        }
1907
}
1908

    
1909
static gint inc_autocheck_func(gpointer data)
1910
{
1911
        MainWindow *mainwin = (MainWindow *)data;
1912

    
1913
        gdk_threads_enter();
1914

    
1915
        if (inc_lock_count) {
1916
                debug_print("autocheck is locked.\n");
1917
                inc_autocheck_timer_set_interval(1000);
1918
                gdk_threads_leave();
1919
                return FALSE;
1920
        }
1921

    
1922
        inc_all_account_mail(mainwin, TRUE);
1923

    
1924
        gdk_threads_leave();
1925

    
1926
        return FALSE;
1927
}