Statistics
| Revision:

root / src / inc.c @ 1

History | View | Annotate | Download (34.5 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2004 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 <gtk/gtkmain.h>
28
#include <gtk/gtkwindow.h>
29
#include <gtk/gtksignal.h>
30
#include <gtk/gtkprogressbar.h>
31
#include <stdio.h>
32
#include <unistd.h>
33
#include <string.h>
34
#include <time.h>
35
#include <sys/time.h>
36
#include <sys/types.h>
37
#include <sys/stat.h>
38
#include <sys/wait.h>
39
#include <signal.h>
40
#include <errno.h>
41

    
42
#include "intl.h"
43
#include "main.h"
44
#include "inc.h"
45
#include "mainwindow.h"
46
#include "folderview.h"
47
#include "summaryview.h"
48
#include "prefs_common.h"
49
#include "prefs_account.h"
50
#include "account.h"
51
#include "procmsg.h"
52
#include "socket.h"
53
#include "ssl.h"
54
#include "pop.h"
55
#include "recv.h"
56
#include "mbox.h"
57
#include "utils.h"
58
#include "gtkutils.h"
59
#include "statusbar.h"
60
#include "manage_window.h"
61
#include "stock_pixmap.h"
62
#include "progressdialog.h"
63
#include "inputdialog.h"
64
#include "alertpanel.h"
65
#include "filter.h"
66
#include "folder.h"
67

    
68
static GList *inc_dialog_list = NULL;
69

    
70
static guint inc_lock_count = 0;
71

    
72
static GdkPixmap *currentxpm;
73
static GdkBitmap *currentxpmmask;
74
static GdkPixmap *errorxpm;
75
static GdkBitmap *errorxpmmask;
76
static GdkPixmap *okxpm;
77
static GdkBitmap *okxpmmask;
78

    
79
#define MSGBUFSIZE        8192
80

    
81
static void inc_finished                (MainWindow                *mainwin,
82
                                         gboolean                 new_messages);
83
static gint inc_account_mail_real        (MainWindow                *mainwin,
84
                                         PrefsAccount                *account);
85

    
86
static IncProgressDialog *inc_progress_dialog_create
87
                                        (gboolean                 autocheck);
88
static void inc_progress_dialog_set_list(IncProgressDialog        *inc_dialog);
89
static void inc_progress_dialog_destroy        (IncProgressDialog        *inc_dialog);
90

    
91
static IncSession *inc_session_new        (PrefsAccount                *account);
92
static void inc_session_destroy                (IncSession                *session);
93
static gint inc_start                        (IncProgressDialog        *inc_dialog);
94
static IncState inc_pop3_session_do        (IncSession                *session);
95

    
96
static void inc_progress_dialog_update        (IncProgressDialog        *inc_dialog,
97
                                         IncSession                *inc_session);
98

    
99
static void inc_progress_dialog_set_label
100
                                        (IncProgressDialog        *inc_dialog,
101
                                         IncSession                *inc_session);
102
static void inc_progress_dialog_set_progress
103
                                        (IncProgressDialog        *inc_dialog,
104
                                         IncSession                *inc_session);
105

    
106
static void inc_update_folderview        (IncProgressDialog        *inc_dialog,
107
                                         IncSession                *inc_session);
108

    
109
static void inc_progress_dialog_update_periodic
110
                                        (IncProgressDialog        *inc_dialog,
111
                                         IncSession                *inc_session);
112
static void inc_update_folderview_periodic
113
                                        (IncProgressDialog        *inc_dialog,
114
                                         IncSession                *inc_session);
115

    
116
static gint inc_recv_data_progressive        (Session        *session,
117
                                         guint                 cur_len,
118
                                         guint                 total_len,
119
                                         gpointer         data);
120
static gint inc_recv_data_finished        (Session        *session,
121
                                         guint                 len,
122
                                         gpointer         data);
123
static gint inc_recv_message                (Session        *session,
124
                                         const gchar        *msg,
125
                                         gpointer         data);
126
static gint inc_drop_message                (Pop3Session        *session,
127
                                         const gchar        *file);
128

    
129
static void inc_put_error                (IncState         istate,
130
                                         const gchar        *msg);
131

    
132
static void inc_cancel_cb                (GtkWidget        *widget,
133
                                         gpointer         data);
134
static gint inc_dialog_delete_cb        (GtkWidget        *widget,
135
                                         GdkEventAny        *event,
136
                                         gpointer         data);
137

    
138
static gint inc_spool                        (void);
139
static gint get_spool                        (FolderItem        *dest,
140
                                         const gchar        *mbox);
141

    
142
static void inc_autocheck_timer_set_interval        (guint                 interval);
143
static gint inc_autocheck_func                        (gpointer         data);
144

    
145
/**
146
 * inc_finished:
147
 * @mainwin: Main window.
148
 * @new_messages: TRUE if some messages have been received.
149
 * 
150
 * Update the folder view and the summary view after receiving
151
 * messages.  If @new_messages is FALSE, this function avoids unneeded
152
 * updating.
153
 **/
154
static void inc_finished(MainWindow *mainwin, gboolean new_messages)
155
{
156
        FolderItem *item;
157

    
158
        if (prefs_common.scan_all_after_inc)
159
                folderview_check_new(NULL);
160

    
161
        if (!new_messages && !prefs_common.scan_all_after_inc) return;
162

    
163
        if (prefs_common.open_inbox_on_inc) {
164
                item = cur_account && cur_account->inbox
165
                        ? folder_find_item_from_identifier(cur_account->inbox)
166
                        : folder_get_default_inbox();
167
                folderview_unselect(mainwin->folderview);
168
                folderview_select(mainwin->folderview, item);
169
        } else if (prefs_common.scan_all_after_inc) {
170
                item = mainwin->summaryview->folder_item;
171
                folderview_update_item(item, TRUE);
172
        }
173
}
174

    
175
void inc_mail(MainWindow *mainwin)
176
{
177
        gint new_msgs = 0;
178

    
179
        if (inc_lock_count) return;
180

    
181
        if (!main_window_toggle_online_if_offline(mainwin))
182
                return;
183

    
184
        inc_autocheck_timer_remove();
185
        summary_write_cache(mainwin->summaryview);
186
        main_window_lock(mainwin);
187

    
188
        if (prefs_common.use_extinc && prefs_common.extinc_cmd) {
189
                /* external incorporating program */
190
                if (execute_command_line(prefs_common.extinc_cmd, FALSE) != 0) {
191
                        main_window_unlock(mainwin);
192
                        inc_autocheck_timer_set();
193
                        return;
194
                }
195

    
196
                if (prefs_common.inc_local)
197
                        new_msgs = inc_spool();
198
        } else {
199
                if (prefs_common.inc_local) {
200
                        new_msgs = inc_spool();
201
                        if (new_msgs < 0)
202
                                new_msgs = 0;
203
                }
204

    
205
                new_msgs += inc_account_mail_real(mainwin, cur_account);
206
        }
207

    
208
        inc_finished(mainwin, new_msgs > 0);
209
        main_window_unlock(mainwin);
210
        inc_autocheck_timer_set();
211
}
212

    
213
static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account)
214
{
215
        IncProgressDialog *inc_dialog;
216
        IncSession *session;
217

    
218
        if (account->protocol == A_IMAP4 || account->protocol == A_NNTP) {
219
                FolderItem *item = mainwin->summaryview->folder_item;
220

    
221
                folderview_check_new(FOLDER(account->folder));
222
                if (!prefs_common.scan_all_after_inc && item != NULL &&
223
                    FOLDER(account->folder) == item->folder)
224
                        folderview_update_item(item, TRUE);
225
                return 1;
226
        }
227

    
228
        session = inc_session_new(account);
229
        if (!session) return 0;
230

    
231
        inc_dialog = inc_progress_dialog_create(FALSE);
232
        inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session);
233
        inc_dialog->mainwin = mainwin;
234
        inc_progress_dialog_set_list(inc_dialog);
235

    
236
        main_window_set_toolbar_sensitive(mainwin);
237
        main_window_set_menu_sensitive(mainwin);
238

    
239
        return inc_start(inc_dialog);
240
}
241

    
242
gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account)
243
{
244
        gint new_msgs;
245

    
246
        if (inc_lock_count) return 0;
247

    
248
        if (!main_window_toggle_online_if_offline(mainwin))
249
                return 0;
250

    
251
        inc_autocheck_timer_remove();
252
        summary_write_cache(mainwin->summaryview);
253
        main_window_lock(mainwin);
254

    
255
        new_msgs = inc_account_mail_real(mainwin, account);
256

    
257
        inc_finished(mainwin, new_msgs > 0);
258
        main_window_unlock(mainwin);
259
        inc_autocheck_timer_set();
260

    
261
        return new_msgs;
262
}
263

    
264
void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck)
265
{
266
        GList *list, *queue_list = NULL;
267
        IncProgressDialog *inc_dialog;
268
        gint new_msgs = 0;
269

    
270
        if (inc_lock_count) return;
271

    
272
        if (!main_window_toggle_online_if_offline(mainwin))
273
                return;
274

    
275
        inc_autocheck_timer_remove();
276
        summary_write_cache(mainwin->summaryview);
277
        main_window_lock(mainwin);
278

    
279
        if (prefs_common.inc_local) {
280
                new_msgs = inc_spool();
281
                if (new_msgs < 0)
282
                        new_msgs = 0;
283
        }
284

    
285
        /* check IMAP4 / News folders */
286
        for (list = account_get_list(); list != NULL; list = list->next) {
287
                PrefsAccount *account = list->data;
288
                if ((account->protocol == A_IMAP4 ||
289
                     account->protocol == A_NNTP) && account->recv_at_getall) {
290
                        FolderItem *item = mainwin->summaryview->folder_item;
291

    
292
                        folderview_check_new(FOLDER(account->folder));
293
                        if (!prefs_common.scan_all_after_inc && item != NULL &&
294
                            FOLDER(account->folder) == item->folder)
295
                                folderview_update_item(item, TRUE);
296
                }
297
        }
298

    
299
        /* check POP3 accounts */
300
        for (list = account_get_list(); list != NULL; list = list->next) {
301
                IncSession *session;
302
                PrefsAccount *account = list->data;
303

    
304
                if (account->recv_at_getall) {
305
                        session = inc_session_new(account);
306
                        if (session)
307
                                queue_list = g_list_append(queue_list, session);
308
                }
309
        }
310

    
311
        if (queue_list) {
312
                inc_dialog = inc_progress_dialog_create(autocheck);
313
                inc_dialog->queue_list = queue_list;
314
                inc_dialog->mainwin = mainwin;
315
                inc_progress_dialog_set_list(inc_dialog);
316

    
317
                main_window_set_toolbar_sensitive(mainwin);
318
                main_window_set_menu_sensitive(mainwin);
319

    
320
                new_msgs += inc_start(inc_dialog);
321
        }
322

    
323
        inc_finished(mainwin, new_msgs > 0);
324
        main_window_unlock(mainwin);
325
        inc_autocheck_timer_set();
326
}
327

    
328
static IncProgressDialog *inc_progress_dialog_create(gboolean autocheck)
329
{
330
        IncProgressDialog *dialog;
331
        ProgressDialog *progress;
332

    
333
        dialog = g_new0(IncProgressDialog, 1);
334

    
335
        progress = progress_dialog_create();
336
        gtk_window_set_title(GTK_WINDOW(progress->window),
337
                             _("Retrieving new messages"));
338
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
339
                         G_CALLBACK(inc_cancel_cb), dialog);
340
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
341
                         G_CALLBACK(inc_dialog_delete_cb), dialog);
342
        /* manage_window_set_transient(GTK_WINDOW(progress->window)); */
343

    
344
        progress_dialog_set_value(progress, 0.0);
345

    
346
        stock_pixmap_gdk(progress->clist, STOCK_PIXMAP_COMPLETE,
347
                         &okxpm, &okxpmmask);
348
        stock_pixmap_gdk(progress->clist, STOCK_PIXMAP_CONTINUE,
349
                         &currentxpm, &currentxpmmask);
350
        stock_pixmap_gdk(progress->clist, STOCK_PIXMAP_ERROR,
351
                         &errorxpm, &errorxpmmask);
352

    
353
        if (prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS ||
354
            (prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL &&
355
             !autocheck)) {
356
                dialog->show_dialog = TRUE;
357
                gtk_widget_show_now(progress->window);
358
        }
359

    
360
        dialog->dialog = progress;
361
        gettimeofday(&dialog->progress_tv, NULL);
362
        gettimeofday(&dialog->folder_tv, NULL);
363
        dialog->queue_list = NULL;
364
        dialog->cur_row = 0;
365

    
366
        inc_dialog_list = g_list_append(inc_dialog_list, dialog);
367

    
368
        return dialog;
369
}
370

    
371
static void inc_progress_dialog_set_list(IncProgressDialog *inc_dialog)
372
{
373
        GList *list;
374

    
375
        for (list = inc_dialog->queue_list; list != NULL; list = list->next) {
376
                IncSession *session = list->data;
377
                Pop3Session *pop3_session = POP3_SESSION(session->session);
378
                gchar *text[3];
379

    
380
                session->data = inc_dialog;
381

    
382
                text[0] = NULL;
383
                text[1] = pop3_session->ac_prefs->account_name;
384
                text[2] = _("Standby");
385
                gtk_clist_append(GTK_CLIST(inc_dialog->dialog->clist), text);
386
        }
387
}
388

    
389
static void inc_progress_dialog_clear(IncProgressDialog *inc_dialog)
390
{
391
        progress_dialog_set_value(inc_dialog->dialog, 0.0);
392
        progress_dialog_set_label(inc_dialog->dialog, "");
393
        main_window_progress_off(inc_dialog->mainwin);
394
}
395

    
396
static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
397
{
398
        g_return_if_fail(inc_dialog != NULL);
399

    
400
        inc_dialog_list = g_list_remove(inc_dialog_list, inc_dialog);
401

    
402
        main_window_progress_off(inc_dialog->mainwin);
403
        progress_dialog_destroy(inc_dialog->dialog);
404

    
405
        g_free(inc_dialog);
406
}
407

    
408
static IncSession *inc_session_new(PrefsAccount *account)
409
{
410
        IncSession *session;
411

    
412
        g_return_val_if_fail(account != NULL, NULL);
413

    
414
        if (account->protocol != A_POP3)
415
                return NULL;
416
        if (!account->recv_server || !account->userid)
417
                return NULL;
418

    
419
        session = g_new0(IncSession, 1);
420

    
421
        session->session = pop3_session_new(account);
422
        session->session->data = session;
423
        POP3_SESSION(session->session)->drop_message = inc_drop_message;
424
        session_set_recv_message_notify(session->session,
425
                                        inc_recv_message, session);
426
        session_set_recv_data_progressive_notify(session->session,
427
                                                 inc_recv_data_progressive,
428
                                                 session);
429
        session_set_recv_data_notify(session->session,
430
                                     inc_recv_data_finished, session);
431

    
432
        session->folder_table = g_hash_table_new(NULL, NULL);
433
        session->tmp_folder_table = g_hash_table_new(NULL, NULL);
434

    
435
        return session;
436
}
437

    
438
static void inc_session_destroy(IncSession *session)
439
{
440
        g_return_if_fail(session != NULL);
441

    
442
        session_destroy(session->session);
443
        g_hash_table_destroy(session->folder_table);
444
        g_hash_table_destroy(session->tmp_folder_table);
445
        g_free(session);
446
}
447

    
448
static gint inc_start(IncProgressDialog *inc_dialog)
449
{
450
        IncSession *session;
451
        GtkCList *clist = GTK_CLIST(inc_dialog->dialog->clist);
452
        GList *qlist;
453
        Pop3Session *pop3_session;
454
        IncState inc_state;
455
        gint error_num = 0;
456
        gint new_msgs = 0;
457
        gchar *msg;
458
        gchar *fin_msg;
459

    
460
        qlist = inc_dialog->queue_list;
461
        while (qlist != NULL) {
462
                GList *next = qlist->next;
463

    
464
                session = qlist->data;
465
                pop3_session = POP3_SESSION(session->session); 
466
                pop3_session->user = g_strdup(pop3_session->ac_prefs->userid);
467
                if (pop3_session->ac_prefs->passwd)
468
                        pop3_session->pass =
469
                                g_strdup(pop3_session->ac_prefs->passwd);
470
                else if (pop3_session->ac_prefs->tmp_pass)
471
                        pop3_session->pass =
472
                                g_strdup(pop3_session->ac_prefs->tmp_pass);
473
                else {
474
                        gchar *pass;
475

    
476
                        if (inc_dialog->show_dialog)
477
                                manage_window_focus_in
478
                                        (inc_dialog->dialog->window,
479
                                         NULL, NULL);
480

    
481
                        pass = input_dialog_query_password
482
                                (pop3_session->ac_prefs->recv_server,
483
                                 pop3_session->user);
484

    
485
                        if (inc_dialog->show_dialog)
486
                                manage_window_focus_out
487
                                        (inc_dialog->dialog->window,
488
                                         NULL, NULL);
489

    
490
                        if (pass) {
491
                                pop3_session->ac_prefs->tmp_pass =
492
                                        g_strdup(pass);
493
                                pop3_session->pass = pass;
494
                        }
495
                }
496

    
497
                qlist = next;
498
        }
499

    
500
#define SET_PIXMAP_AND_TEXT(xpm, xpmmask, str)                                   \
501
{                                                                           \
502
        gtk_clist_set_pixmap(clist, inc_dialog->cur_row, 0, xpm, xpmmask); \
503
        gtk_clist_set_text(clist, inc_dialog->cur_row, 2, str);                   \
504
}
505

    
506
        for (; inc_dialog->queue_list != NULL; inc_dialog->cur_row++) {
507
                session = inc_dialog->queue_list->data;
508
                pop3_session = POP3_SESSION(session->session);
509

    
510
                if (pop3_session->pass == NULL) {
511
                        SET_PIXMAP_AND_TEXT(okxpm, okxpmmask, _("Cancelled"));
512
                        inc_session_destroy(session);
513
                        inc_dialog->queue_list =
514
                                g_list_remove(inc_dialog->queue_list, session);
515
                        continue;
516
                }
517

    
518
                inc_progress_dialog_clear(inc_dialog);
519
                gtk_clist_moveto(clist, inc_dialog->cur_row, -1, 1.0, 0.0);
520

    
521
                SET_PIXMAP_AND_TEXT(currentxpm, currentxpmmask,
522
                                    _("Retrieving"));
523

    
524
                /* begin POP3 session */
525
                inc_state = inc_pop3_session_do(session);
526

    
527
                switch (inc_state) {
528
                case INC_SUCCESS:
529
                        if (pop3_session->cur_total_num > 0)
530
                                msg = g_strdup_printf
531
                                        (_("Done (%d message(s) (%s) received)"),
532
                                         pop3_session->cur_total_num,
533
                                         to_human_readable(pop3_session->cur_total_recv_bytes));
534
                        else
535
                                msg = g_strdup_printf(_("Done (no new messages)"));
536
                        SET_PIXMAP_AND_TEXT(okxpm, okxpmmask, msg);
537
                        g_free(msg);
538
                        break;
539
                case INC_CONNECT_ERROR:
540
                        SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask,
541
                                            _("Connection failed"));
542
                        break;
543
                case INC_AUTH_FAILED:
544
                        SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask,
545
                                            _("Auth failed"));
546
                        break;
547
                case INC_LOCKED:
548
                        SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask,
549
                                            _("Locked"));
550
                        break;
551
                case INC_ERROR:
552
                case INC_NO_SPACE:
553
                case INC_IO_ERROR:
554
                case INC_SOCKET_ERROR:
555
                case INC_EOF:
556
                        SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask, _("Error"));
557
                        break;
558
                case INC_TIMEOUT:
559
                        SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask, _("Timeout"));
560
                        break;
561
                case INC_CANCEL:
562
                        SET_PIXMAP_AND_TEXT(okxpm, okxpmmask, _("Cancelled"));
563
                        break;
564
                default:
565
                        break;
566
                }
567

    
568
                new_msgs += pop3_session->cur_total_num;
569

    
570
                if (!prefs_common.scan_all_after_inc) {
571
                        folder_item_scan_foreach(session->folder_table);
572
                        folderview_update_item_foreach
573
                                (session->folder_table,
574
                                 !prefs_common.open_inbox_on_inc);
575
                }
576

    
577
                if (pop3_session->error_val == PS_AUTHFAIL &&
578
                    pop3_session->ac_prefs->tmp_pass) {
579
                        g_free(pop3_session->ac_prefs->tmp_pass);
580
                        pop3_session->ac_prefs->tmp_pass = NULL;
581
                }
582

    
583
                pop3_write_uidl_list(pop3_session);
584

    
585
                if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) {
586
                        error_num++;
587
                        if (inc_dialog->show_dialog)
588
                                manage_window_focus_in
589
                                        (inc_dialog->dialog->window,
590
                                         NULL, NULL);
591
                        inc_put_error(inc_state, pop3_session->error_msg);
592
                        if (inc_dialog->show_dialog)
593
                                manage_window_focus_out
594
                                        (inc_dialog->dialog->window,
595
                                         NULL, NULL);
596
                        if (inc_state == INC_NO_SPACE ||
597
                            inc_state == INC_IO_ERROR)
598
                                break;
599
                }
600

    
601
                inc_session_destroy(session);
602
                inc_dialog->queue_list =
603
                        g_list_remove(inc_dialog->queue_list, session);
604
        }
605

    
606
#undef SET_PIXMAP_AND_TEXT
607

    
608
        if (new_msgs > 0)
609
                fin_msg = g_strdup_printf(_("Finished (%d new message(s))"),
610
                                          new_msgs);
611
        else
612
                fin_msg = g_strdup_printf(_("Finished (no new messages)"));
613

    
614
        progress_dialog_set_label(inc_dialog->dialog, fin_msg);
615

    
616
#if 0
617
        if (error_num && !prefs_common.no_recv_err_panel) {
618
                if (inc_dialog->show_dialog)
619
                        manage_window_focus_in(inc_dialog->dialog->window,
620
                                               NULL, NULL);
621
                alertpanel_error(_("Some errors occurred while getting mail."));
622
                if (inc_dialog->show_dialog)
623
                        manage_window_focus_out(inc_dialog->dialog->window,
624
                                                NULL, NULL);
625
        }
626
#endif
627

    
628
        while (inc_dialog->queue_list != NULL) {
629
                session = inc_dialog->queue_list->data;
630
                inc_session_destroy(session);
631
                inc_dialog->queue_list =
632
                        g_list_remove(inc_dialog->queue_list, session);
633
        }
634

    
635
        if (prefs_common.close_recv_dialog || !inc_dialog->show_dialog)
636
                inc_progress_dialog_destroy(inc_dialog);
637
        else {
638
                gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
639
                                     fin_msg);
640
                gtk_label_set_text(GTK_LABEL(GTK_BIN(inc_dialog->dialog->cancel_btn)->child),
641
                                   _("Close"));
642
        }
643

    
644
        g_free(fin_msg);
645

    
646
        return new_msgs;
647
}
648

    
649
static IncState inc_pop3_session_do(IncSession *session)
650
{
651
        Pop3Session *pop3_session = POP3_SESSION(session->session);
652
        IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data;
653
        gchar *server;
654
        gushort port;
655
        gchar *buf;
656

    
657
        debug_print(_("getting new messages of account %s...\n"),
658
                    pop3_session->ac_prefs->account_name);
659

    
660
        buf = g_strdup_printf(_("%s: Retrieving new messages"),
661
                              pop3_session->ac_prefs->recv_server);
662
        gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf);
663
        g_free(buf);
664

    
665
        server = pop3_session->ac_prefs->recv_server;
666
#if USE_SSL
667
        port = pop3_session->ac_prefs->set_popport ?
668
                pop3_session->ac_prefs->popport :
669
                pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110;
670
        SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop;
671
        if (pop3_session->ac_prefs->ssl_pop != SSL_NONE)
672
                SESSION(pop3_session)->nonblocking =
673
                        pop3_session->ac_prefs->use_nonblocking_ssl;
674
#else
675
        port = pop3_session->ac_prefs->set_popport ?
676
                pop3_session->ac_prefs->popport : 110;
677
#endif
678

    
679
        buf = g_strdup_printf(_("Connecting to POP3 server: %s..."), server);
680
        log_message("%s\n", buf);
681
        progress_dialog_set_label(inc_dialog->dialog, buf);
682
        g_free(buf);
683

    
684
        session_set_timeout(SESSION(pop3_session),
685
                            prefs_common.io_timeout_secs * 1000);
686

    
687
        if (session_connect(SESSION(pop3_session), server, port) < 0) {
688
                log_warning(_("Can't connect to POP3 server: %s:%d\n"),
689
                            server, port);
690
                session->inc_state = INC_CONNECT_ERROR;
691
                statusbar_pop_all();
692
                return INC_CONNECT_ERROR;
693
        }
694

    
695
        while (session_is_connected(SESSION(pop3_session)) &&
696
               session->inc_state != INC_CANCEL)
697
                gtk_main_iteration();
698

    
699
        if (session->inc_state == INC_SUCCESS) {
700
                switch (pop3_session->error_val) {
701
                case PS_SUCCESS:
702
                        switch (SESSION(pop3_session)->state) {
703
                        case SESSION_ERROR:
704
                                if (pop3_session->state == POP3_READY)
705
                                        session->inc_state = INC_CONNECT_ERROR;
706
                                else
707
                                        session->inc_state = INC_ERROR;
708
                                break;
709
                        case SESSION_EOF:
710
                                session->inc_state = INC_EOF;
711
                                break;
712
                        case SESSION_TIMEOUT:
713
                                session->inc_state = INC_TIMEOUT;
714
                                break;
715
                        default:
716
                                session->inc_state = INC_SUCCESS;
717
                                break;
718
                        }
719
                        break;
720
                case PS_AUTHFAIL:
721
                        session->inc_state = INC_AUTH_FAILED;
722
                        break;
723
                case PS_IOERR:
724
                        session->inc_state = INC_IO_ERROR;
725
                        break;
726
                case PS_SOCKET:
727
                        session->inc_state = INC_SOCKET_ERROR;
728
                        break;
729
                case PS_LOCKBUSY:
730
                        session->inc_state = INC_LOCKED;
731
                        break;
732
                default:
733
                        session->inc_state = INC_ERROR;
734
                        break;
735
                }
736
        }
737

    
738
        session_disconnect(SESSION(pop3_session));
739
        statusbar_pop_all();
740

    
741
        return session->inc_state;
742
}
743

    
744
static void inc_progress_dialog_update(IncProgressDialog *inc_dialog,
745
                                       IncSession *inc_session)
746
{
747
        inc_progress_dialog_set_label(inc_dialog, inc_session);
748
        inc_progress_dialog_set_progress(inc_dialog, inc_session);
749
}
750

    
751
static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
752
                                          IncSession *inc_session)
753
{
754
        ProgressDialog *dialog = inc_dialog->dialog;
755
        Pop3Session *session;
756

    
757
        g_return_if_fail(inc_session != NULL);
758

    
759
        session = POP3_SESSION(inc_session->session);
760

    
761
        switch (session->state) {
762
        case POP3_GREETING:
763
                break;
764
        case POP3_GETAUTH_USER:
765
        case POP3_GETAUTH_PASS:
766
        case POP3_GETAUTH_APOP:
767
                progress_dialog_set_label(dialog, _("Authenticating..."));
768
                statusbar_print_all(_("Retrieving messages from %s..."),
769
                                    SESSION(session)->server);
770
                break;
771
        case POP3_GETRANGE_STAT:
772
                progress_dialog_set_label
773
                        (dialog, _("Getting the number of new messages (STAT)..."));
774
                break;
775
        case POP3_GETRANGE_LAST:
776
                progress_dialog_set_label
777
                        (dialog, _("Getting the number of new messages (LAST)..."));
778
                break;
779
        case POP3_GETRANGE_UIDL:
780
                progress_dialog_set_label
781
                        (dialog, _("Getting the number of new messages (UIDL)..."));
782
                break;
783
        case POP3_GETSIZE_LIST:
784
                progress_dialog_set_label
785
                        (dialog, _("Getting the size of messages (LIST)..."));
786
                break;
787
        case POP3_RETR:
788
        case POP3_RETR_RECV:
789
                break;
790
        case POP3_DELETE:
791
#if 0
792
                if (session->msg[session->cur_msg].recv_time <
793
                        session->current_time) {
794
                        gchar buf[MSGBUFSIZE];
795
                        g_snprintf(buf, sizeof(buf), _("Deleting message %d"),
796
                                   session->cur_msg);
797
                        progress_dialog_set_label(dialog, buf);
798
                }
799
#endif
800
                break;
801
        case POP3_LOGOUT:
802
                progress_dialog_set_label(dialog, _("Quitting"));
803
                break;
804
        default:
805
                break;
806
        }
807
}
808

    
809
static void inc_progress_dialog_set_progress(IncProgressDialog *inc_dialog,
810
                                             IncSession *inc_session)
811
{
812
        gchar buf[MSGBUFSIZE];
813
        Pop3Session *pop3_session = POP3_SESSION(inc_session->session);
814
        gchar *total_size_str;
815
        gint cur_total;
816
        gint total;
817

    
818
        if (!pop3_session->new_msg_exist) return;
819

    
820
        cur_total = inc_session->cur_total_bytes;
821
        total = pop3_session->total_bytes;
822
        if (pop3_session->state == POP3_RETR ||
823
            pop3_session->state == POP3_RETR_RECV ||
824
            pop3_session->state == POP3_DELETE) {
825
                Xstrdup_a(total_size_str, to_human_readable(total), return);
826
                g_snprintf(buf, sizeof(buf),
827
                           _("Retrieving message (%d / %d) (%s / %s)"),
828
                           pop3_session->cur_msg, pop3_session->count,
829
                           to_human_readable(cur_total), total_size_str);
830
                progress_dialog_set_label(inc_dialog->dialog, buf);
831
        }
832

    
833
        progress_dialog_set_percentage
834
                (inc_dialog->dialog,(gfloat)cur_total / (gfloat)total);
835

    
836
        gtk_progress_set_show_text
837
                (GTK_PROGRESS(inc_dialog->mainwin->progressbar), TRUE);
838
        g_snprintf(buf, sizeof(buf), "%d / %d",
839
                   pop3_session->cur_msg, pop3_session->count);
840
        gtk_progress_set_format_string
841
                (GTK_PROGRESS(inc_dialog->mainwin->progressbar), buf);
842
        gtk_progress_bar_update
843
                (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar),
844
                 (gfloat)cur_total / (gfloat)total);
845

    
846
        if (pop3_session->cur_total_num > 0) {
847
                g_snprintf(buf, sizeof(buf),
848
                           _("Retrieving (%d message(s) (%s) received)"),
849
                           pop3_session->cur_total_num,
850
                           to_human_readable
851
                           (pop3_session->cur_total_recv_bytes));
852
                gtk_clist_set_text(GTK_CLIST(inc_dialog->dialog->clist),
853
                                   inc_dialog->cur_row, 2, buf);
854
        }
855
}
856

    
857
static gboolean hash_remove_func(gpointer key, gpointer value, gpointer data)
858
{
859
        return TRUE;
860
}
861

    
862
static void inc_update_folderview(IncProgressDialog *inc_dialog,
863
                                  IncSession *inc_session)
864
{
865
        if (g_hash_table_size(inc_session->tmp_folder_table) > 0) {
866
                folderview_update_item_foreach(inc_session->tmp_folder_table,
867
                                               FALSE);
868
                g_hash_table_foreach_remove(inc_session->tmp_folder_table,
869
                                            hash_remove_func, NULL);
870
        }
871
}
872

    
873
static void inc_progress_dialog_update_periodic(IncProgressDialog *inc_dialog,
874
                                                IncSession *inc_session)
875
{
876
        struct timeval tv_cur;
877
        struct timeval tv_result;
878
        gint msec;
879

    
880
        gettimeofday(&tv_cur, NULL);
881

    
882
        tv_result.tv_sec = tv_cur.tv_sec - inc_dialog->progress_tv.tv_sec;
883
        tv_result.tv_usec = tv_cur.tv_usec - inc_dialog->progress_tv.tv_usec;
884
        if (tv_result.tv_usec < 0) {
885
                tv_result.tv_sec--;
886
                tv_result.tv_usec += 1000000;
887
        }
888

    
889
        msec = tv_result.tv_sec * 1000 + tv_result.tv_usec / 1000;
890
        if (msec > PROGRESS_UPDATE_INTERVAL) {
891
                inc_progress_dialog_update(inc_dialog, inc_session);
892
                inc_dialog->progress_tv.tv_sec = tv_cur.tv_sec;
893
                inc_dialog->progress_tv.tv_usec = tv_cur.tv_usec;
894
        }
895
}
896

    
897
static void inc_update_folderview_periodic(IncProgressDialog *inc_dialog,
898
                                           IncSession *inc_session)
899
{
900
        struct timeval tv_cur;
901
        struct timeval tv_result;
902
        gint msec;
903

    
904
        gettimeofday(&tv_cur, NULL);
905

    
906
        tv_result.tv_sec = tv_cur.tv_sec - inc_dialog->folder_tv.tv_sec;
907
        tv_result.tv_usec = tv_cur.tv_usec - inc_dialog->folder_tv.tv_usec;
908
        if (tv_result.tv_usec < 0) {
909
                tv_result.tv_sec--;
910
                tv_result.tv_usec += 1000000;
911
        }
912

    
913
        msec = tv_result.tv_sec * 1000 + tv_result.tv_usec / 1000;
914
        if (msec > FOLDER_UPDATE_INTERVAL) {
915
                inc_update_folderview(inc_dialog, inc_session);
916
                inc_dialog->folder_tv.tv_sec = tv_cur.tv_sec;
917
                inc_dialog->folder_tv.tv_usec = tv_cur.tv_usec;
918
        }
919
}
920

    
921
static gint inc_recv_data_progressive(Session *session, guint cur_len,
922
                                      guint total_len, gpointer data)
923
{
924
        IncSession *inc_session = (IncSession *)data;
925
        Pop3Session *pop3_session = POP3_SESSION(session);
926
        IncProgressDialog *inc_dialog;
927
        gint cur_total;
928

    
929
        g_return_val_if_fail(inc_session != NULL, -1);
930

    
931
        if (pop3_session->state != POP3_RETR &&
932
            pop3_session->state != POP3_RETR_RECV &&
933
            pop3_session->state != POP3_DELETE &&
934
            pop3_session->state != POP3_LOGOUT) return 0;
935

    
936
        if (!pop3_session->new_msg_exist) return 0;
937

    
938
        cur_total = pop3_session->cur_total_bytes + cur_len;
939
        if (cur_total > pop3_session->total_bytes)
940
                cur_total = pop3_session->total_bytes;
941
        inc_session->cur_total_bytes = cur_total;
942

    
943
        inc_dialog = (IncProgressDialog *)inc_session->data;
944
        inc_progress_dialog_update_periodic(inc_dialog, inc_session);
945
        inc_update_folderview_periodic(inc_dialog, inc_session);
946

    
947
        return 0;
948
}
949

    
950
static gint inc_recv_data_finished(Session *session, guint len, gpointer data)
951
{
952
        IncSession *inc_session = (IncSession *)data;
953
        IncProgressDialog *inc_dialog;
954

    
955
        g_return_val_if_fail(inc_session != NULL, -1);
956

    
957
        inc_dialog = (IncProgressDialog *)inc_session->data;
958

    
959
        inc_recv_data_progressive(session, 0, 0, inc_session);
960

    
961
        if (POP3_SESSION(session)->state == POP3_LOGOUT) {
962
                inc_progress_dialog_update(inc_dialog, inc_session);
963
                inc_update_folderview(inc_dialog, inc_session);
964
        }
965

    
966
        return 0;
967
}
968

    
969
static gint inc_recv_message(Session *session, const gchar *msg, gpointer data)
970
{
971
        IncSession *inc_session = (IncSession *)data;
972
        IncProgressDialog *inc_dialog;
973

    
974
        g_return_val_if_fail(inc_session != NULL, -1);
975

    
976
        inc_dialog = (IncProgressDialog *)inc_session->data;
977

    
978
        switch (POP3_SESSION(session)->state) {
979
        case POP3_GETAUTH_USER:
980
        case POP3_GETAUTH_PASS:
981
        case POP3_GETAUTH_APOP:
982
        case POP3_GETRANGE_STAT:
983
        case POP3_GETRANGE_LAST:
984
        case POP3_GETRANGE_UIDL:
985
        case POP3_GETSIZE_LIST:
986
                inc_progress_dialog_update(inc_dialog, inc_session);
987
                break;
988
        case POP3_RETR:
989
                inc_recv_data_progressive(session, 0, 0, inc_session);
990
                break;
991
        case POP3_LOGOUT:
992
                inc_progress_dialog_update(inc_dialog, inc_session);
993
                inc_update_folderview(inc_dialog, inc_session);
994
                break;
995
        default:
996
                break;
997
        }
998

    
999
        return 0;
1000
}
1001

    
1002
static gint inc_drop_message(Pop3Session *session, const gchar *file)
1003
{
1004
        FolderItem *inbox;
1005
        GSList *cur;
1006
        FilterInfo *fltinfo;
1007
        IncSession *inc_session = (IncSession *)(SESSION(session)->data);
1008
        gint val;
1009

    
1010
        g_return_val_if_fail(inc_session != NULL, DROP_ERROR);
1011

    
1012
        if (session->ac_prefs->inbox) {
1013
                inbox = folder_find_item_from_identifier
1014
                        (session->ac_prefs->inbox);
1015
                if (!inbox)
1016
                        inbox = folder_get_default_inbox();
1017
        } else
1018
                inbox = folder_get_default_inbox();
1019
        if (!inbox)
1020
                return DROP_ERROR;
1021

    
1022
        fltinfo = filter_info_new();
1023
        fltinfo->account = session->ac_prefs;
1024
        fltinfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
1025
        fltinfo->flags.tmp_flags = MSG_RECEIVED;
1026

    
1027
        if (session->ac_prefs->filter_on_recv)
1028
                filter_apply(prefs_common.fltlist, file, fltinfo);
1029

    
1030
        if (!fltinfo->drop_done) {
1031
                if (folder_item_add_msg
1032
                        (inbox, file, &fltinfo->flags, FALSE) < 0) {
1033
                        filter_info_free(fltinfo);
1034
                        return DROP_ERROR;
1035
                }
1036
                fltinfo->dest_list = g_slist_append(fltinfo->dest_list, inbox);
1037
        }
1038

    
1039
        for (cur = fltinfo->dest_list; cur != NULL; cur = cur->next) {
1040
                FolderItem *drop_folder = (FolderItem *)cur->data;
1041

    
1042
                val = GPOINTER_TO_INT(g_hash_table_lookup
1043
                                      (inc_session->folder_table, drop_folder));
1044
                if (val == 0) {
1045
                        /* force updating */
1046
                        if (FOLDER_IS_LOCAL(drop_folder->folder))
1047
                                drop_folder->mtime = 0;
1048
                        g_hash_table_insert(inc_session->folder_table, drop_folder,
1049
                                            GINT_TO_POINTER(1));
1050
                }
1051
                g_hash_table_insert(inc_session->tmp_folder_table, drop_folder,
1052
                                    GINT_TO_POINTER(1));
1053
        }
1054

    
1055
        if (fltinfo->actions[FLT_ACTION_NOT_RECEIVE] == TRUE)
1056
                val = DROP_DONT_RECEIVE;
1057
        else if (fltinfo->actions[FLT_ACTION_DELETE] == TRUE)
1058
                val = DROP_DELETE;
1059
        else
1060
                val = DROP_OK;
1061

    
1062
        filter_info_free(fltinfo);
1063

    
1064
        return val;
1065
}
1066

    
1067
static void inc_put_error(IncState istate, const gchar *msg)
1068
{
1069
        gchar *log_msg = NULL;
1070
        gchar *err_msg = NULL;
1071
        gboolean fatal_error = FALSE;
1072

    
1073
        switch (istate) {
1074
        case INC_CONNECT_ERROR:
1075
                log_msg = _("Connection failed.");
1076
                if (prefs_common.no_recv_err_panel)
1077
                        break;
1078
                err_msg = g_strdup(log_msg);
1079
                break;
1080
        case INC_ERROR:
1081
                log_msg = _("Error occurred while processing mail.");
1082
                if (prefs_common.no_recv_err_panel)
1083
                        break;
1084
                if (msg)
1085
                        err_msg = g_strdup_printf
1086
                                (_("Error occurred while processing mail:\n%s"),
1087
                                 msg);
1088
                else
1089
                        err_msg = g_strdup(log_msg);
1090
                break;
1091
        case INC_NO_SPACE:
1092
                log_msg = _("No disk space left.");
1093
                err_msg = g_strdup(log_msg);
1094
                fatal_error = TRUE;
1095
                break;
1096
        case INC_IO_ERROR:
1097
                log_msg = _("Can't write file.");
1098
                err_msg = g_strdup(log_msg);
1099
                fatal_error = TRUE;
1100
                break;
1101
        case INC_SOCKET_ERROR:
1102
                log_msg = _("Socket error.");
1103
                if (prefs_common.no_recv_err_panel)
1104
                        break;
1105
                err_msg = g_strdup(log_msg);
1106
                break;
1107
        case INC_EOF:
1108
                log_msg = _("Connection closed by the remote host.");
1109
                if (prefs_common.no_recv_err_panel)
1110
                        break;
1111
                err_msg = g_strdup(log_msg);
1112
                break;
1113
        case INC_LOCKED:
1114
                log_msg = _("Mailbox is locked.");
1115
                if (prefs_common.no_recv_err_panel)
1116
                        break;
1117
                if (msg)
1118
                        err_msg = g_strdup_printf(_("Mailbox is locked:\n%s"),
1119
                                                  msg);
1120
                else
1121
                        err_msg = g_strdup(log_msg);
1122
                break;
1123
        case INC_AUTH_FAILED:
1124
                log_msg = _("Authentication failed.");
1125
                if (prefs_common.no_recv_err_panel)
1126
                        break;
1127
                if (msg)
1128
                        err_msg = g_strdup_printf
1129
                                (_("Authentication failed:\n%s"), msg);
1130
                else
1131
                        err_msg = g_strdup(log_msg);
1132
                break;
1133
        case INC_TIMEOUT:
1134
                log_msg = _("Session timed out.");
1135
                if (prefs_common.no_recv_err_panel)
1136
                        break;
1137
                err_msg = g_strdup(log_msg);
1138
                break;
1139
        default:
1140
                break;
1141
        }
1142

    
1143
        if (log_msg) {
1144
                if (fatal_error)
1145
                        log_error("%s\n", log_msg);
1146
                else
1147
                        log_warning("%s\n", log_msg);
1148
        }
1149
        if (err_msg) {
1150
                alertpanel_error(err_msg);
1151
                g_free(err_msg);
1152
        }
1153
}
1154

    
1155
static void inc_cancel(IncProgressDialog *dialog)
1156
{
1157
        IncSession *session;
1158

    
1159
        g_return_if_fail(dialog != NULL);
1160

    
1161
        if (dialog->queue_list == NULL) {
1162
                inc_progress_dialog_destroy(dialog);
1163
                return;
1164
        }
1165

    
1166
        session = dialog->queue_list->data;
1167

    
1168
        session->inc_state = INC_CANCEL;
1169

    
1170
        log_message(_("Incorporation cancelled\n"));
1171
}
1172

    
1173
gboolean inc_is_active(void)
1174
{
1175
        return (inc_dialog_list != NULL);
1176
}
1177

    
1178
void inc_cancel_all(void)
1179
{
1180
        GList *cur;
1181

    
1182
        for (cur = inc_dialog_list; cur != NULL; cur = cur->next)
1183
                inc_cancel((IncProgressDialog *)cur->data);
1184
}
1185

    
1186
static void inc_cancel_cb(GtkWidget *widget, gpointer data)
1187
{
1188
        inc_cancel((IncProgressDialog *)data);
1189
}
1190

    
1191
static gint inc_dialog_delete_cb(GtkWidget *widget, GdkEventAny *event,
1192
                                 gpointer data)
1193
{
1194
        IncProgressDialog *dialog = (IncProgressDialog *)data;
1195

    
1196
        if (dialog->queue_list == NULL)
1197
                inc_progress_dialog_destroy(dialog);
1198

    
1199
        return TRUE;
1200
}
1201

    
1202
static gint inc_spool(void)
1203
{
1204
        gchar *spool_path;
1205
        gchar *mbox;
1206
        gint msgs;
1207

    
1208
        spool_path = prefs_common.spool_path
1209
                ? prefs_common.spool_path : DEFAULT_SPOOL_PATH;
1210
        if (is_file_exist(spool_path))
1211
                mbox = g_strdup(spool_path);
1212
        else if (is_dir_exist(spool_path))
1213
                mbox = g_strconcat(spool_path, G_DIR_SEPARATOR_S,
1214
                                   g_get_user_name(), NULL);
1215
        else {
1216
                debug_print("%s: local mailbox not found.\n", spool_path);
1217
                return -1;
1218
        }
1219

    
1220
        msgs = get_spool(folder_get_default_inbox(), mbox);
1221
        g_free(mbox);
1222

    
1223
        return msgs;
1224
}
1225

    
1226
static gint get_spool(FolderItem *dest, const gchar *mbox)
1227
{
1228
        gint msgs, size;
1229
        gint lockfd;
1230
        gchar tmp_mbox[MAXPATHLEN + 1];
1231
        GHashTable *folder_table = NULL;
1232

    
1233
        g_return_val_if_fail(dest != NULL, -1);
1234
        g_return_val_if_fail(mbox != NULL, -1);
1235

    
1236
        if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
1237
                debug_print("%s: no messages in local mailbox.\n", mbox);
1238
                return 0;
1239
        } else if (size < 0)
1240
                return -1;
1241

    
1242
        if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
1243
                return -1;
1244

    
1245
        g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
1246
                   get_tmp_dir(), G_DIR_SEPARATOR, mbox);
1247

    
1248
        if (copy_mbox(mbox, tmp_mbox) < 0) {
1249
                unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1250
                return -1;
1251
        }
1252

    
1253
        debug_print(_("Getting new messages from %s into %s...\n"),
1254
                    mbox, dest->path);
1255

    
1256
        if (prefs_common.filter_on_inc)
1257
                folder_table = g_hash_table_new(NULL, NULL);
1258
        msgs = proc_mbox(dest, tmp_mbox, folder_table);
1259

    
1260
        unlink(tmp_mbox);
1261
        if (msgs >= 0) empty_mbox(mbox);
1262
        unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1263

    
1264
        if (folder_table) {
1265
                if (!prefs_common.scan_all_after_inc) {
1266
                        folder_item_scan_foreach(folder_table);
1267
                        folderview_update_item_foreach
1268
                                (folder_table, !prefs_common.open_inbox_on_inc);
1269
                }
1270
                g_hash_table_destroy(folder_table);
1271
        } else if (!prefs_common.scan_all_after_inc) {
1272
                folder_item_scan(dest);
1273
                folderview_update_item(dest, TRUE);
1274
        }
1275

    
1276
        return msgs;
1277
}
1278

    
1279
void inc_lock(void)
1280
{
1281
        inc_lock_count++;
1282
}
1283

    
1284
void inc_unlock(void)
1285
{
1286
        if (inc_lock_count > 0)
1287
                inc_lock_count--;
1288
}
1289

    
1290
static guint autocheck_timer = 0;
1291
static gpointer autocheck_data = NULL;
1292

    
1293
void inc_autocheck_timer_init(MainWindow *mainwin)
1294
{
1295
        autocheck_data = mainwin;
1296
        inc_autocheck_timer_set();
1297
}
1298

    
1299
static void inc_autocheck_timer_set_interval(guint interval)
1300
{
1301
        inc_autocheck_timer_remove();
1302

    
1303
        if (prefs_common.autochk_newmail && autocheck_data) {
1304
                autocheck_timer = gtk_timeout_add
1305
                        (interval, inc_autocheck_func, autocheck_data);
1306
                debug_print("added timer = %d\n", autocheck_timer);
1307
        }
1308
}
1309

    
1310
void inc_autocheck_timer_set(void)
1311
{
1312
        inc_autocheck_timer_set_interval(prefs_common.autochk_itv * 60000);
1313
}
1314

    
1315
void inc_autocheck_timer_remove(void)
1316
{
1317
        if (autocheck_timer) {
1318
                debug_print("removed timer = %d\n", autocheck_timer);
1319
                gtk_timeout_remove(autocheck_timer);
1320
                autocheck_timer = 0;
1321
        }
1322
}
1323

    
1324
static gint inc_autocheck_func(gpointer data)
1325
{
1326
        MainWindow *mainwin = (MainWindow *)data;
1327

    
1328
        if (inc_lock_count) {
1329
                debug_print("autocheck is locked.\n");
1330
                inc_autocheck_timer_set_interval(1000);
1331
                return FALSE;
1332
        }
1333

    
1334
        inc_all_account_mail(mainwin, TRUE);
1335

    
1336
        return FALSE;
1337
}