Statistics
| Revision:

root / src / inc.c @ 3216

History | View | Annotate | Download (50.5 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
                GString *str;
211
                gint c = 0;
212

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

    
235
                if (prefs_common.enable_newmsg_notify_window) {
236
                        gchar buf[1024];
237

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

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

    
253
                        notification_window_open(buf, str->str, 5);
254
                }
255

    
256
                g_string_free(str, TRUE);
257
        }
258

    
259
        syl_plugin_signal_emit("inc-mail-finished", new_messages);
260

    
261
        inc_block_notify(FALSE);
262

    
263
        if (new_messages <= 0 && !prefs_common.scan_all_after_inc) return;
264

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

    
276
        /* Notification */
277

    
278
        if (new_messages > 0 &&
279
            prefs_common.enable_newmsg_notify_sound &&
280
            prefs_common.newmsg_notify_sound) {
281
                play_sound(prefs_common.newmsg_notify_sound, TRUE);
282
        }
283

    
284
        if (new_messages > 0 &&
285
            prefs_common.enable_newmsg_notify &&
286
            prefs_common.newmsg_notify_cmd) {
287
                gchar buf[1024];
288

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

    
301
static GSList *inc_add_message_count(GSList *list, PrefsAccount *account,
302
                                     gint new_messages)
303
{
304
        IncAccountNewMsgCount *count;
305

    
306
        count = g_new(IncAccountNewMsgCount, 1);
307
        count->account = account;
308
        count->new_messages = new_messages;
309

    
310
        return g_slist_append(list, count);
311
}
312

    
313
static void inc_result_free(IncResult *result, gboolean free_self)
314
{
315
        GSList *cur;
316

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

    
327
        if (free_self)
328
                g_free(result);
329
}
330

    
331
void inc_mail(MainWindow *mainwin)
332
{
333
        IncResult result = {NULL, NULL};
334
        gint new_msgs = 0;
335

    
336
        if (inc_lock_count) return;
337
        if (inc_is_active()) return;
338

    
339
        if (!main_window_toggle_online_if_offline(mainwin))
340
                return;
341

    
342
        inc_is_running = TRUE;
343

    
344
        inc_autocheck_timer_remove();
345
        summary_write_cache(mainwin->summaryview);
346
        main_window_lock(mainwin);
347

    
348
        syl_plugin_signal_emit("inc-mail-start", cur_account);
349

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

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

    
371
                new_msgs = inc_account_mail_real(mainwin, cur_account, &result);
372
        }
373

    
374
        inc_finished(mainwin, &result);
375
        inc_result_free(&result, FALSE);
376

    
377
        inc_is_running = FALSE;
378

    
379
        main_window_unlock(mainwin);
380
        inc_autocheck_timer_set();
381
}
382

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

    
389
        g_return_val_if_fail(account != NULL, 0);
390
        g_return_val_if_fail(account->folder != NULL, 0);
391

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

    
401
                debug_print("inc_remote_account_mail(): filtering IMAP4 INBOX\n");
402
                mlist = folder_item_get_uncached_msg_list(inbox);
403
                debug_print("inc_remote_account_mail(): uncached messages: %d\n", g_slist_length(mlist));
404

    
405
                junk_rule = filter_junk_rule_create(account, NULL, TRUE);
406
                if (junk_rule)
407
                        junk_fltlist.data = junk_rule;
408

    
409
                for (cur = mlist; cur != NULL; cur = cur->next) {
410
                        MsgInfo *msginfo = (MsgInfo *)cur->data;
411
                        gboolean is_junk = FALSE;
412

    
413
                        fltinfo = filter_info_new();
414
                        fltinfo->account = account;
415
                        fltinfo->flags = msginfo->flags;
416

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

    
426
                        if (!fltinfo->drop_done) {
427
                                filter_apply_msginfo(prefs_common.fltlist,
428
                                                     msginfo, fltinfo);
429
                        }
430

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

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

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

    
473
                        if (fltinfo->drop_done)
474
                                ++n_filtered;
475

    
476
                        filter_info_free(fltinfo);
477
                }
478

    
479
                if (junk_rule)
480
                        filter_rule_free(junk_rule);
481

    
482
                procmsg_msg_list_free(mlist);
483

    
484
                debug_print("inc_remote_account_mail(): INBOX: %d new, %d filtered\n",
485
                            new_msgs, n_filtered);
486

    
487
                if (!prefs_common.scan_all_after_inc && item != NULL &&
488
                    inbox == item)
489
                        update_summary = TRUE;
490
        }
491

    
492
        if (account->protocol == A_IMAP4 && account->imap_check_inbox_only) {
493
                FolderItem *inbox = FOLDER(account->folder)->inbox;
494

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

    
506
        if (update_summary)
507
                folderview_update_item(item, TRUE);
508
        folderview_update_all_updated(FALSE);
509

    
510
        return new_msgs;
511
}
512

    
513
static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account,
514
                                  IncResult *result)
515
{
516
        IncProgressDialog *inc_dialog;
517
        IncSession *session;
518

    
519
        g_return_val_if_fail(account != NULL, 0);
520

    
521
        if (account->protocol == A_IMAP4 || account->protocol == A_NNTP)
522
                return inc_remote_account_mail(mainwin, account);
523

    
524
        session = inc_session_new(account);
525
        if (!session) return 0;
526

    
527
        inc_dialog = inc_progress_dialog_create(FALSE);
528
        inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session);
529
        inc_dialog->mainwin = mainwin;
530
        inc_dialog->result = result;
531
        inc_progress_dialog_set_list(inc_dialog);
532

    
533
        main_window_set_toolbar_sensitive(mainwin);
534
        main_window_set_menu_sensitive(mainwin);
535

    
536
        return inc_start(inc_dialog);
537
}
538

    
539
gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
540
{
541
        IncResult result = {NULL, NULL};
542
        gint new_msgs;
543

    
544
        if (inc_lock_count) return 0;
545
        if (inc_is_active()) return 0;
546

    
547
        if (!main_window_toggle_online_if_offline(mainwin))
548
                return 0;
549

    
550
        inc_is_running = TRUE;
551

    
552
        inc_autocheck_timer_remove();
553
        summary_write_cache(mainwin->summaryview);
554
        main_window_lock(mainwin);
555

    
556
        syl_plugin_signal_emit("inc-mail-start", account);
557

    
558
        new_msgs = inc_account_mail_real(mainwin, account, &result);
559

    
560
        inc_finished(mainwin, &result);
561
        inc_result_free(&result, FALSE);
562

    
563
        inc_is_running = FALSE;
564

    
565
        main_window_unlock(mainwin);
566
        inc_autocheck_timer_set();
567

    
568
        return new_msgs;
569
}
570

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

    
578
        if (inc_lock_count) return;
579
        if (inc_is_active()) return;
580

    
581
        if (!main_window_toggle_online_if_offline(mainwin))
582
                return;
583

    
584
        inc_is_running = TRUE;
585

    
586
        inc_autocheck_timer_remove();
587
        summary_write_cache(mainwin->summaryview);
588
        main_window_lock(mainwin);
589

    
590
        syl_plugin_signal_emit("inc-mail-start", NULL);
591

    
592
        if (prefs_common.inc_local) {
593
                new_msgs = inc_spool();
594
                if (new_msgs < 0)
595
                        new_msgs = 0;
596
                result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs);
597
        }
598

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

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

    
614
                if (account->recv_at_getall) {
615
                        session = inc_session_new(account);
616
                        if (session)
617
                                queue_list = g_list_append(queue_list, session);
618
                }
619
        }
620

    
621
        if (queue_list) {
622
                inc_dialog = inc_progress_dialog_create(autocheck);
623
                inc_dialog->queue_list = queue_list;
624
                inc_dialog->mainwin = mainwin;
625
                inc_dialog->result = &result;
626
                inc_progress_dialog_set_list(inc_dialog);
627

    
628
                main_window_set_toolbar_sensitive(mainwin);
629
                main_window_set_menu_sensitive(mainwin);
630

    
631
                inc_start(inc_dialog);
632
        }
633

    
634
        inc_finished(mainwin, &result);
635
        inc_result_free(&result, FALSE);
636

    
637
        inc_is_running = FALSE;
638

    
639
        main_window_unlock(mainwin);
640
        inc_autocheck_timer_set();
641
}
642

    
643
gint inc_pop_before_smtp(PrefsAccount *account)
644
{
645
        MainWindow *mainwin;
646
        IncProgressDialog *inc_dialog;
647
        IncSession *session;
648

    
649
        if (inc_lock_count) return -1;
650

    
651
        mainwin = main_window_get();
652

    
653
        if (!main_window_toggle_online_if_offline(mainwin))
654
                return -1;
655

    
656
        inc_is_running = TRUE;
657

    
658
        inc_autocheck_timer_remove();
659
        main_window_lock(mainwin);
660

    
661
        session = inc_session_new(account);
662
        if (!session) return -1;
663
        POP3_SESSION(session->session)->auth_only = TRUE;
664

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

    
674
        main_window_set_toolbar_sensitive(mainwin);
675
        main_window_set_menu_sensitive(mainwin);
676

    
677
        inc_start(inc_dialog);
678

    
679
        inc_is_running = FALSE;
680

    
681
        main_window_unlock(mainwin);
682
        inc_autocheck_timer_set();
683

    
684
        return 0;
685
}
686

    
687
static IncProgressDialog *inc_progress_dialog_create(gboolean autocheck)
688
{
689
        IncProgressDialog *dialog;
690
        ProgressDialog *progress;
691
        GtkWidget *cancel_all_btn;
692

    
693
        dialog = g_new0(IncProgressDialog, 1);
694

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

    
709
        progress_dialog_set_value(progress, 0.0);
710

    
711
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_COMPLETE, &ok_pixbuf);
712
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_CONTINUE,
713
                         &current_pixbuf);
714
        stock_pixbuf_gdk(progress->treeview, STOCK_PIXMAP_ERROR, &error_pixbuf);
715

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

    
723
        dialog->dialog = progress;
724
        g_get_current_time(&dialog->progress_tv);
725
        g_get_current_time(&dialog->folder_tv);
726
        dialog->queue_list = NULL;
727
        dialog->cur_row = 0;
728

    
729
        inc_dialog_list = g_list_append(inc_dialog_list, dialog);
730

    
731
        return dialog;
732
}
733

    
734
static void inc_progress_dialog_set_list(IncProgressDialog *inc_dialog)
735
{
736
        GList *list;
737

    
738
        for (list = inc_dialog->queue_list; list != NULL; list = list->next) {
739
                IncSession *session = list->data;
740
                Pop3Session *pop3_session = POP3_SESSION(session->session);
741

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

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

    
756
static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
757
{
758
        g_return_if_fail(inc_dialog != NULL);
759

    
760
        inc_dialog_list = g_list_remove(inc_dialog_list, inc_dialog);
761

    
762
        manage_window_destroy(inc_dialog->dialog->window, NULL);
763

    
764
        main_window_progress_off(inc_dialog->mainwin);
765
        progress_dialog_destroy(inc_dialog->dialog);
766

    
767
        g_free(inc_dialog);
768
}
769

    
770
static IncSession *inc_session_new(PrefsAccount *account)
771
{
772
        IncSession *session;
773
        FilterRule *rule;
774

    
775
        g_return_val_if_fail(account != NULL, NULL);
776

    
777
        if (account->protocol != A_POP3)
778
                return NULL;
779
        if (!account->recv_server || !account->userid)
780
                return NULL;
781

    
782
        session = g_new0(IncSession, 1);
783

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

    
795
        session->inc_state = INC_SUCCESS;
796

    
797
        session->folder_table = g_hash_table_new(NULL, NULL);
798
        session->tmp_folder_table = g_hash_table_new(NULL, NULL);
799

    
800
        rule = filter_junk_rule_create(account, NULL, FALSE);
801
        if (rule)
802
                session->junk_fltlist = g_slist_append(NULL, rule);
803
        else
804
                session->junk_fltlist = NULL;
805

    
806
        session->cur_total_bytes = 0;
807
        session->new_msgs = 0;
808

    
809
        session->start_num = 0;
810
        session->start_recv_bytes = 0;
811

    
812
        session->retr_count = 0;
813

    
814
        return session;
815
}
816

    
817
static void inc_session_destroy(IncSession *session)
818
{
819
        g_return_if_fail(session != NULL);
820

    
821
        session_destroy(session->session);
822
        g_hash_table_destroy(session->folder_table);
823
        g_hash_table_destroy(session->tmp_folder_table);
824
        if (session->junk_fltlist)
825
                filter_rule_list_free(session->junk_fltlist);
826
        g_free(session);
827
}
828

    
829
static void inc_update_folder_foreach(GHashTable *table)
830
{
831
        procmsg_flush_folder_foreach(table);
832
        folderview_update_item_foreach(table, TRUE);
833
}
834

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

    
846
        qlist = inc_dialog->queue_list;
847
        while (qlist != NULL) {
848
                GList *next = qlist->next;
849

    
850
                session = qlist->data;
851
                if (session->inc_state == INC_CANCEL) {
852
                        qlist = next;
853
                        continue;
854
                }
855

    
856
                pop3_session = POP3_SESSION(session->session); 
857
                if (!pop3_session->pass) {
858
                        gchar *pass;
859

    
860
                        if (inc_dialog->show_dialog)
861
                                manage_window_focus_in
862
                                        (inc_dialog->dialog->window,
863
                                         NULL, NULL);
864

    
865
                        pass = input_query_password
866
                                (pop3_session->ac_prefs->recv_server,
867
                                 pop3_session->user);
868

    
869
                        if (inc_dialog->show_dialog)
870
                                manage_window_focus_out
871
                                        (inc_dialog->dialog->window,
872
                                         NULL, NULL);
873

    
874
                        if (pass) {
875
                                pop3_session->ac_prefs->tmp_pass =
876
                                        g_strdup(pass);
877
                                pop3_session->pass = pass;
878
                        }
879
                }
880

    
881
                qlist = next;
882
        }
883

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

    
896
        for (; inc_dialog->queue_list != NULL; inc_dialog->cur_row++) {
897
                session = inc_dialog->queue_list->data;
898
                pop3_session = POP3_SESSION(session->session);
899

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

    
909
                inc_progress_dialog_clear(inc_dialog);
910
                progress_dialog_scroll_to_row(inc_dialog->dialog,
911
                                              inc_dialog->cur_row);
912

    
913
                SET_PIXMAP_AND_TEXT(current_pixbuf, _("Retrieving"), NULL);
914

    
915
                /* begin POP3 session */
916
                inc_state = inc_pop3_session_do(session);
917

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

    
962
                if (inc_dialog->result)
963
                        inc_dialog->result->count_list = inc_add_message_count(inc_dialog->result->count_list, pop3_session->ac_prefs, session->new_msgs);
964
                new_msgs += session->new_msgs;
965

    
966
                if (!prefs_common.scan_all_after_inc) {
967
                        inc_update_folder_foreach(session->folder_table);
968
                }
969

    
970
                if (pop3_session->error_val == PS_AUTHFAIL &&
971
                    pop3_session->ac_prefs->tmp_pass) {
972
                        g_free(pop3_session->ac_prefs->tmp_pass);
973
                        pop3_session->ac_prefs->tmp_pass = NULL;
974
                }
975

    
976
                pop3_write_uidl_list(pop3_session);
977

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

    
995
                inc_session_destroy(session);
996
                inc_dialog->queue_list =
997
                        g_list_remove(inc_dialog->queue_list, session);
998
        }
999

    
1000
#undef SET_PIXMAP_AND_TEXT
1001

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

    
1008
        progress_dialog_set_label(inc_dialog->dialog, fin_msg);
1009

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

    
1022
        while (inc_dialog->queue_list != NULL) {
1023
                session = inc_dialog->queue_list->data;
1024
                inc_session_destroy(session);
1025
                inc_dialog->queue_list =
1026
                        g_list_remove(inc_dialog->queue_list, session);
1027
        }
1028

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

    
1038
        g_free(fin_msg);
1039

    
1040
        return new_msgs;
1041
}
1042

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

    
1051
        debug_print(_("getting new messages of account %s...\n"),
1052
                    ac->account_name);
1053

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

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

    
1069
        session_set_timeout(SESSION(pop3_session),
1070
                            prefs_common.io_timeout_secs * 1000);
1071

    
1072
        if (ac->use_socks && ac->use_socks_for_recv) {
1073
                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);
1074
        }
1075

    
1076
        GTK_EVENTS_FLUSH();
1077

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

    
1091
        while (session_is_connected(SESSION(pop3_session)) &&
1092
               session->inc_state != INC_CANCEL) {
1093
                gtk_main_iteration();
1094
        }
1095
        log_window_flush();
1096

    
1097
        debug_print("inc_state: %d\n", session->inc_state);
1098
        debug_print("pop3_session.error_val: %d\n", pop3_session->error_val);
1099
        debug_print("pop3_session.error_msg: %s\n", pop3_session->error_msg ? pop3_session->error_msg : "(empty)");
1100

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

    
1142
        session_disconnect(SESSION(pop3_session));
1143
        statusbar_pop_all();
1144

    
1145
        return session->inc_state;
1146
}
1147

    
1148
static void inc_progress_dialog_update(IncProgressDialog *inc_dialog,
1149
                                       IncSession *inc_session)
1150
{
1151
        inc_progress_dialog_set_label(inc_dialog, inc_session);
1152
        inc_progress_dialog_set_progress(inc_dialog, inc_session);
1153
}
1154

    
1155
static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
1156
                                          IncSession *inc_session)
1157
{
1158
        ProgressDialog *dialog = inc_dialog->dialog;
1159
        Pop3Session *session;
1160

    
1161
        g_return_if_fail(inc_session != NULL);
1162

    
1163
        session = POP3_SESSION(inc_session->session);
1164

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

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

    
1223
        if (!pop3_session->new_msg_exist) return;
1224

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

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

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

    
1249
        if (total > 0)
1250
                progress_dialog_set_percentage
1251
                        (inc_dialog->dialog, (gfloat)cur_total / (gfloat)total);
1252

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

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

    
1276
static gboolean hash_remove_func(gpointer key, gpointer value, gpointer data)
1277
{
1278
        return TRUE;
1279
}
1280

    
1281
static void inc_update_folderview(IncProgressDialog *inc_dialog,
1282
                                  IncSession *inc_session)
1283
{
1284
        MainWindow *mainwin;
1285

    
1286
        if (g_hash_table_size(inc_session->tmp_folder_table) > 0) {
1287
                folderview_update_item_foreach(inc_session->tmp_folder_table,
1288
                                               FALSE);
1289
                g_hash_table_foreach_remove(inc_session->tmp_folder_table,
1290
                                            hash_remove_func, NULL);
1291
        }
1292

    
1293
        mainwin = main_window_get();
1294
        summary_show_queued_msgs(mainwin->summaryview);
1295
}
1296

    
1297
static void inc_progress_dialog_update_periodic(IncProgressDialog *inc_dialog,
1298
                                                IncSession *inc_session)
1299
{
1300
        GTimeVal tv_cur;
1301
        GTimeVal tv_result;
1302
        gint msec;
1303

    
1304
        g_get_current_time(&tv_cur);
1305

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

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

    
1321
static void inc_update_folderview_periodic(IncProgressDialog *inc_dialog,
1322
                                           IncSession *inc_session)
1323
{
1324
        GTimeVal tv_cur;
1325
        GTimeVal tv_result;
1326
        gint msec;
1327

    
1328
        g_get_current_time(&tv_cur);
1329

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

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

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

    
1353
        g_return_val_if_fail(inc_session != NULL, -1);
1354

    
1355
        if (pop3_session->state != POP3_RETR &&
1356
            pop3_session->state != POP3_RETR_RECV &&
1357
            pop3_session->state != POP3_DELETE &&
1358
            pop3_session->state != POP3_LOGOUT) return 0;
1359

    
1360
        if (!pop3_session->new_msg_exist) return 0;
1361

    
1362
        gdk_threads_enter();
1363

    
1364
        cur_total = pop3_session->cur_total_bytes + cur_len;
1365
        if (cur_total > pop3_session->total_bytes)
1366
                cur_total = pop3_session->total_bytes;
1367
        inc_session->cur_total_bytes = cur_total;
1368

    
1369
        inc_dialog = (IncProgressDialog *)inc_session->data;
1370
        inc_progress_dialog_update_periodic(inc_dialog, inc_session);
1371
        inc_update_folderview_periodic(inc_dialog, inc_session);
1372

    
1373
        gdk_threads_leave();
1374
        return 0;
1375
}
1376

    
1377
static gint inc_recv_data_finished(Session *session, guint len, gpointer data)
1378
{
1379
        IncSession *inc_session = (IncSession *)data;
1380
        IncProgressDialog *inc_dialog;
1381

    
1382
        g_return_val_if_fail(inc_session != NULL, -1);
1383

    
1384
        inc_dialog = (IncProgressDialog *)inc_session->data;
1385

    
1386
        inc_recv_data_progressive(session, 0, 0, inc_session);
1387

    
1388
        gdk_threads_enter();
1389

    
1390
        if (POP3_SESSION(session)->state == POP3_LOGOUT) {
1391
                inc_progress_dialog_update(inc_dialog, inc_session);
1392
                inc_update_folderview(inc_dialog, inc_session);
1393
        }
1394

    
1395
        gdk_threads_leave();
1396
        return 0;
1397
}
1398

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

    
1405
        g_return_val_if_fail(inc_session != NULL, -1);
1406

    
1407
        inc_dialog = (IncProgressDialog *)inc_session->data;
1408

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

    
1450
        return 0;
1451
}
1452

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

    
1476
        g_return_val_if_fail(inc_session != NULL, DROP_ERROR);
1477

    
1478
        gdk_threads_enter();
1479

    
1480
        inc_dialog = (IncProgressDialog *)inc_session->data;
1481

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

    
1494
        fltinfo = filter_info_new();
1495
        fltinfo->account = session->ac_prefs;
1496
        fltinfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
1497
        fltinfo->flags.tmp_flags = MSG_RECEIVED;
1498

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

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

    
1532
        if (!fltinfo->drop_done && session->ac_prefs->filter_on_recv)
1533
                filter_apply_msginfo(prefs_common.fltlist, msginfo, fltinfo);
1534

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

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

    
1571
        for (cur = fltinfo->dest_list; cur != NULL; cur = cur->next) {
1572
                FolderItem *drop_folder = (FolderItem *)cur->data;
1573

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

    
1582
                if (drop_folder->stype != F_TRASH &&
1583
                    drop_folder->stype != F_JUNK)
1584
                        is_counted = TRUE;
1585
        }
1586

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

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

    
1609
        procmsg_msginfo_free(msginfo);
1610
        filter_info_free(fltinfo);
1611

    
1612
        gdk_threads_leave();
1613
        return val;
1614
}
1615

    
1616
static void inc_put_error(IncSession *session, IncState istate, const gchar *pop3_msg)
1617
{
1618
        gchar *log_msg = NULL;
1619
        gchar *err_msg = NULL;
1620
        gboolean fatal_error = FALSE;
1621

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

    
1701
        if (log_msg) {
1702
                if (fatal_error)
1703
                        log_error("%s\n", log_msg);
1704
                else
1705
                        log_warning("%s\n", log_msg);
1706
        }
1707
        if (err_msg) {
1708
                alertpanel_error("%s", err_msg);
1709
                g_free(err_msg);
1710
        }
1711
}
1712

    
1713
static void inc_cancel(IncProgressDialog *dialog, gboolean cancel_all)
1714
{
1715
        IncSession *session;
1716
        GList *list;
1717

    
1718
        g_return_if_fail(dialog != NULL);
1719

    
1720
        if (dialog->queue_list == NULL) {
1721
                inc_progress_dialog_destroy(dialog);
1722
                return;
1723
        }
1724

    
1725
        for (list = dialog->queue_list; list != NULL; list = list->next) {
1726
                session = list->data;
1727
                session->inc_state = INC_CANCEL;
1728
                session_disconnect(session->session);
1729
                if (!cancel_all)
1730
                        break;
1731
        }
1732

    
1733
        log_message(_("Incorporation cancelled\n"));
1734
}
1735

    
1736
gboolean inc_is_active(void)
1737
{
1738
        GList *cur;
1739

    
1740
        if (inc_is_running)
1741
                return TRUE;
1742

    
1743
        if (inc_dialog_list == NULL)
1744
                return FALSE;
1745

    
1746
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next) {
1747
                IncProgressDialog *dialog = cur->data;
1748
                if (dialog->queue_list)
1749
                        return TRUE;
1750
        }
1751

    
1752
        return FALSE;
1753
}
1754

    
1755
void inc_block_notify(gboolean block)
1756
{
1757
        if (!block)
1758
                block_notify = FALSE;
1759
        else if (inc_is_active())
1760
                block_notify = TRUE;
1761
}
1762

    
1763
void inc_cancel_all(void)
1764
{
1765
        GList *cur;
1766

    
1767
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next)
1768
                inc_cancel((IncProgressDialog *)cur->data, TRUE);
1769
}
1770

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

    
1776
static void inc_cancel_all_cb(GtkWidget *widget, gpointer data)
1777
{
1778
        inc_cancel((IncProgressDialog *)data, TRUE);
1779
}
1780

    
1781
static gint inc_dialog_delete_cb(GtkWidget *widget, GdkEventAny *event,
1782
                                 gpointer data)
1783
{
1784
        IncProgressDialog *dialog = (IncProgressDialog *)data;
1785

    
1786
        if (dialog->queue_list == NULL)
1787
                inc_progress_dialog_destroy(dialog);
1788
        else
1789
                inc_cancel(dialog, TRUE);
1790

    
1791
        return TRUE;
1792
}
1793

    
1794
static gint inc_spool(void)
1795
{
1796
        gchar *spool_path;
1797
        gchar *mbox;
1798
        gint msgs;
1799

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

    
1812
        msgs = get_spool(folder_get_default_inbox(), mbox);
1813
        g_free(mbox);
1814

    
1815
        return msgs;
1816
}
1817

    
1818
static gint get_spool(FolderItem *dest, const gchar *mbox)
1819
{
1820
        gint msgs, size;
1821
        gint lockfd;
1822
        gchar tmp_mbox[MAXPATHLEN + 1];
1823
        GHashTable *folder_table = NULL;
1824

    
1825
        g_return_val_if_fail(dest != NULL, -1);
1826
        g_return_val_if_fail(mbox != NULL, -1);
1827

    
1828
        if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
1829
                debug_print("%s: no messages in local mailbox.\n", mbox);
1830
                return 0;
1831
        } else if (size < 0)
1832
                return -1;
1833

    
1834
        if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
1835
                return -1;
1836

    
1837
        g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
1838
                   get_tmp_dir(), G_DIR_SEPARATOR, mbox);
1839

    
1840
        if (copy_mbox(mbox, tmp_mbox) < 0) {
1841
                unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1842
                return -1;
1843
        }
1844

    
1845
        debug_print(_("Getting new messages from %s into %s...\n"),
1846
                    mbox, dest->path);
1847

    
1848
        folder_table = g_hash_table_new(NULL, NULL);
1849

    
1850
        msgs = proc_mbox_full(dest, tmp_mbox, folder_table,
1851
                              prefs_common.filter_on_inc,
1852
                              prefs_common.enable_junk &&
1853
                              prefs_common.filter_junk_on_recv);
1854

    
1855
        g_unlink(tmp_mbox);
1856
        if (msgs >= 0) empty_mbox(mbox);
1857
        unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1858

    
1859
        if (!prefs_common.scan_all_after_inc) {
1860
                inc_update_folder_foreach(folder_table);
1861
        }
1862

    
1863
        g_hash_table_destroy(folder_table);
1864

    
1865
        return msgs;
1866
}
1867

    
1868
void inc_lock(void)
1869
{
1870
        inc_lock_count++;
1871
}
1872

    
1873
void inc_unlock(void)
1874
{
1875
        if (inc_lock_count > 0)
1876
                inc_lock_count--;
1877
}
1878

    
1879
static guint autocheck_timer = 0;
1880
static gpointer autocheck_data = NULL;
1881

    
1882
void inc_autocheck_timer_init(MainWindow *mainwin)
1883
{
1884
        autocheck_data = mainwin;
1885
        inc_autocheck_timer_set();
1886
}
1887

    
1888
static void inc_autocheck_timer_set_interval(guint interval)
1889
{
1890
        inc_autocheck_timer_remove();
1891

    
1892
        if (prefs_common.autochk_newmail && autocheck_data) {
1893
                autocheck_timer = g_timeout_add_full
1894
                        (G_PRIORITY_LOW, interval, inc_autocheck_func,
1895
                         autocheck_data, NULL);
1896
                debug_print("added timer = %d\n", autocheck_timer);
1897
        }
1898
}
1899

    
1900
void inc_autocheck_timer_set(void)
1901
{
1902
        inc_autocheck_timer_set_interval(prefs_common.autochk_itv * 60000);
1903
}
1904

    
1905
void inc_autocheck_timer_remove(void)
1906
{
1907
        if (autocheck_timer) {
1908
                debug_print("removed timer = %d\n", autocheck_timer);
1909
                g_source_remove(autocheck_timer);
1910
                autocheck_timer = 0;
1911
        }
1912
}
1913

    
1914
static gint inc_autocheck_func(gpointer data)
1915
{
1916
        MainWindow *mainwin = (MainWindow *)data;
1917

    
1918
        gdk_threads_enter();
1919

    
1920
        if (inc_lock_count) {
1921
                debug_print("autocheck is locked.\n");
1922
                inc_autocheck_timer_set_interval(1000);
1923
                gdk_threads_leave();
1924
                return FALSE;
1925
        }
1926

    
1927
        inc_all_account_mail(mainwin, TRUE);
1928

    
1929
        gdk_threads_leave();
1930

    
1931
        return FALSE;
1932
}