2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2003 Hiroyuki Yamamoto
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.
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.
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.
27 #include <gtk/gtkmain.h>
28 #include <gtk/gtkwindow.h>
29 #include <gtk/gtksignal.h>
30 #include <gtk/gtkprogressbar.h>
35 #include <sys/types.h>
44 #include "mainwindow.h"
45 #include "folderview.h"
46 #include "summaryview.h"
47 #include "prefs_common.h"
48 #include "prefs_account.h"
58 #include "statusbar.h"
59 #include "manage_window.h"
60 #include "stock_pixmap.h"
61 #include "progressdialog.h"
62 #include "inputdialog.h"
63 #include "alertpanel.h"
65 #include "filtering.h"
69 static GList *inc_dialog_list = NULL;
71 static guint inc_lock_count = 0;
73 static GdkPixmap *currentxpm;
74 static GdkBitmap *currentxpmmask;
75 static GdkPixmap *errorxpm;
76 static GdkBitmap *errorxpmmask;
77 static GdkPixmap *okxpm;
78 static GdkBitmap *okxpmmask;
80 #define MSGBUFSIZE 8192
82 static void inc_finished (MainWindow *mainwin,
83 gboolean new_messages);
84 static gint inc_account_mail (PrefsAccount *account,
87 static IncProgressDialog *inc_progress_dialog_create (void);
88 static void inc_progress_dialog_set_list(IncProgressDialog *inc_dialog);
89 static void inc_progress_dialog_destroy (IncProgressDialog *inc_dialog);
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);
96 static void inc_progress_dialog_set_label
97 (IncProgressDialog *inc_dialog,
98 IncSession *inc_session);
100 static gint inc_recv_data_progressive (Session *session,
104 static gint inc_recv_data_finished (Session *session,
107 static gint inc_recv_message (Session *session,
111 static void inc_put_error (IncState istate,
114 static void inc_cancel_cb (GtkWidget *widget,
116 static gint inc_dialog_delete_cb (GtkWidget *widget,
120 static gint inc_spool (void);
121 static gint get_spool (FolderItem *dest,
124 static gint inc_spool_account(PrefsAccount *account);
125 static gint inc_all_spool(void);
126 static void inc_autocheck_timer_set_interval (guint interval);
127 static gint inc_autocheck_func (gpointer data);
129 static void inc_notify_cmd (gint new_msgs,
134 * @mainwin: Main window.
135 * @new_messages: TRUE if some messages have been received.
137 * Update the folder view and the summary view after receiving
138 * messages. If @new_messages is FALSE, this function avoids unneeded
141 static void inc_finished(MainWindow *mainwin, gboolean new_messages)
145 if (prefs_common.scan_all_after_inc)
146 folderview_check_new(NULL);
148 if (!new_messages && !prefs_common.scan_all_after_inc) return;
150 if (prefs_common.open_inbox_on_inc) {
151 item = cur_account && cur_account->inbox
152 ? folder_find_item_from_identifier(cur_account->inbox)
153 : folder_get_default_inbox();
157 void inc_mail(MainWindow *mainwin, gboolean notify)
160 gint account_new_msgs = 0;
162 if (inc_lock_count) return;
164 if (prefs_common.work_offline)
165 if (alertpanel(_("Offline warning"),
166 _("You're working offline. Override?"),
167 _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
171 inc_autocheck_timer_remove();
172 main_window_lock(mainwin);
174 if (prefs_common.use_extinc && prefs_common.extinc_cmd) {
175 /* external incorporating program */
176 if (execute_command_line(prefs_common.extinc_cmd, FALSE) < 0) {
177 main_window_unlock(mainwin);
178 inc_autocheck_timer_set();
182 if (prefs_common.inc_local) {
183 account_new_msgs = inc_spool();
184 if (account_new_msgs > 0)
185 new_msgs += account_new_msgs;
188 if (prefs_common.inc_local) {
189 account_new_msgs = inc_spool();
190 if (account_new_msgs > 0)
191 new_msgs += account_new_msgs;
194 account_new_msgs = inc_account_mail(cur_account, mainwin);
195 if (account_new_msgs > 0)
196 new_msgs += account_new_msgs;
199 inc_finished(mainwin, new_msgs > 0);
200 main_window_unlock(mainwin);
201 inc_notify_cmd(new_msgs, notify);
202 inc_autocheck_timer_set();
206 void inc_pop_before_smtp(PrefsAccount *acc)
208 /* FIXME: assumes to attach to first main window */
209 inc_account_mail(acc, mainwindow_get_mainwindow());
212 static gint inc_account_mail(PrefsAccount *account, MainWindow *mainwin)
214 IncProgressDialog *inc_dialog;
216 FolderItem *item = NULL;
218 if(mainwin && mainwin->summaryview)
219 item = mainwin->summaryview->folder_item;
221 switch (account->protocol) {
225 * FIXME: it should return foldeview_check_new() value.
226 * TODO: do it when bug [19] is fixed (IMAP folder sets
227 * an incorrect new message count)
229 folderview_check_new(FOLDER(account->folder));
233 session = inc_session_new(account);
234 if (!session) return 0;
236 inc_dialog = inc_progress_dialog_create();
237 inc_dialog->queue_list = g_list_append(inc_dialog->queue_list,
239 inc_dialog->mainwin = mainwin;
240 inc_progress_dialog_set_list(inc_dialog);
243 toolbar_main_set_sensitive(mainwin);
244 main_window_set_menu_sensitive(mainwin);
247 return inc_start(inc_dialog);
250 return inc_spool_account(account);
258 void inc_all_account_mail(MainWindow *mainwin, gboolean notify)
260 GList *list, *queue_list = NULL;
261 IncProgressDialog *inc_dialog;
263 gint account_new_msgs = 0;
265 if (prefs_common.work_offline)
266 if (alertpanel(_("Offline warning"),
267 _("You're working offline. Override?"),
268 _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
271 if (inc_lock_count) return;
273 inc_autocheck_timer_remove();
274 main_window_lock(mainwin);
276 if (prefs_common.inc_local) {
277 account_new_msgs = inc_spool();
278 if (account_new_msgs > 0)
279 new_msgs += account_new_msgs;
282 list = account_get_list();
284 inc_finished(mainwin, new_msgs > 0);
285 main_window_unlock(mainwin);
286 inc_notify_cmd(new_msgs, notify);
287 inc_autocheck_timer_set();
291 /* check local folders */
292 account_new_msgs = inc_all_spool();
293 if (account_new_msgs > 0)
294 new_msgs += account_new_msgs;
296 /* check IMAP4 folders */
297 for (; list != NULL; list = list->next) {
298 PrefsAccount *account = list->data;
299 if ((account->protocol == A_IMAP4 ||
300 account->protocol == A_NNTP) && account->recv_at_getall) {
301 new_msgs += folderview_check_new(FOLDER(account->folder));
305 /* check POP3 accounts */
306 for (list = account_get_list(); list != NULL; list = list->next) {
308 PrefsAccount *account = list->data;
310 if (account->recv_at_getall) {
311 session = inc_session_new(account);
313 queue_list = g_list_append(queue_list, session);
318 inc_finished(mainwin, new_msgs > 0);
319 main_window_unlock(mainwin);
320 inc_notify_cmd(new_msgs, notify);
321 inc_autocheck_timer_set();
325 inc_dialog = inc_progress_dialog_create();
326 inc_dialog->queue_list = queue_list;
327 inc_dialog->mainwin = mainwin;
328 inc_progress_dialog_set_list(inc_dialog);
330 toolbar_main_set_sensitive(mainwin);
331 main_window_set_menu_sensitive(mainwin);
333 new_msgs += inc_start(inc_dialog);
334 inc_finished(mainwin, new_msgs > 0);
335 main_window_unlock(mainwin);
336 inc_notify_cmd(new_msgs, notify);
337 inc_autocheck_timer_set();
340 static IncProgressDialog *inc_progress_dialog_create(void)
342 IncProgressDialog *dialog;
343 ProgressDialog *progress;
345 dialog = g_new0(IncProgressDialog, 1);
347 progress = progress_dialog_create();
348 gtk_window_set_title(GTK_WINDOW(progress->window),
349 _("Retrieving new messages"));
350 gtk_signal_connect(GTK_OBJECT(progress->cancel_btn), "clicked",
351 GTK_SIGNAL_FUNC(inc_cancel_cb), dialog);
352 gtk_signal_connect(GTK_OBJECT(progress->window), "delete_event",
353 GTK_SIGNAL_FUNC(inc_dialog_delete_cb), dialog);
354 /* manage_window_set_transient(GTK_WINDOW(progress->window)); */
356 progress_dialog_set_value(progress, 0.0);
358 stock_pixmap_gdk(progress->clist, STOCK_PIXMAP_COMPLETE,
360 stock_pixmap_gdk(progress->clist, STOCK_PIXMAP_CONTINUE,
361 ¤txpm, ¤txpmmask);
362 stock_pixmap_gdk(progress->clist, STOCK_PIXMAP_ERROR,
363 &errorxpm, &errorxpmmask);
365 if (prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS ||
366 (prefs_common.recv_dialog_mode == RECV_DIALOG_ACTIVE &&
367 manage_window_get_focus_window())) {
368 dialog->show_dialog = TRUE;
369 gtk_widget_show_now(progress->window);
372 dialog->dialog = progress;
373 dialog->queue_list = NULL;
376 inc_dialog_list = g_list_append(inc_dialog_list, dialog);
381 static void inc_progress_dialog_set_list(IncProgressDialog *inc_dialog)
385 for (list = inc_dialog->queue_list; list != NULL; list = list->next) {
386 IncSession *session = list->data;
387 Pop3Session *pop3_session = POP3_SESSION(session->session);
390 session->data = inc_dialog;
393 text[1] = pop3_session->ac_prefs->account_name;
394 text[2] = _("Standby");
395 gtk_clist_append(GTK_CLIST(inc_dialog->dialog->clist), text);
399 static void inc_progress_dialog_clear(IncProgressDialog *inc_dialog)
401 progress_dialog_set_value(inc_dialog->dialog, 0.0);
402 progress_dialog_set_label(inc_dialog->dialog, "");
403 if (inc_dialog->mainwin)
404 gtk_progress_set_show_text
405 (GTK_PROGRESS(inc_dialog->mainwin->progressbar), FALSE);
406 gtk_progress_bar_update
407 (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar), 0.0);
410 static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
412 g_return_if_fail(inc_dialog != NULL);
414 inc_dialog_list = g_list_remove(inc_dialog_list, inc_dialog);
416 if (inc_dialog->mainwin)
417 gtk_progress_set_show_text
418 (GTK_PROGRESS(inc_dialog->mainwin->progressbar), FALSE);
419 gtk_progress_bar_update
420 (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar), 0.0);
422 progress_dialog_destroy(inc_dialog->dialog);
427 static IncSession *inc_session_new(PrefsAccount *account)
431 g_return_val_if_fail(account != NULL, NULL);
433 if (account->protocol != A_POP3 && account->protocol != A_APOP)
435 if (!account->recv_server || !account->userid)
438 session = g_new0(IncSession, 1);
439 session->session = pop3_session_new(account);
440 session->session->data = session;
445 static void inc_session_destroy(IncSession *session)
447 g_return_if_fail(session != NULL);
449 session_destroy(session->session);
453 static gint inc_start(IncProgressDialog *inc_dialog)
456 GtkCList *clist = GTK_CLIST(inc_dialog->dialog->clist);
458 Pop3Session *pop3_session;
464 FolderItem *processing, *inbox;
466 GSList *msglist, *msglist_element;
468 qlist = inc_dialog->queue_list;
469 while (qlist != NULL) {
470 GList *next = qlist->next;
472 session = qlist->data;
473 pop3_session = POP3_SESSION(session->session);
474 pop3_session->user = g_strdup(pop3_session->ac_prefs->userid);
475 if (pop3_session->ac_prefs->passwd)
477 g_strdup(pop3_session->ac_prefs->passwd);
478 else if (pop3_session->ac_prefs->tmp_pass)
480 g_strdup(pop3_session->ac_prefs->tmp_pass);
484 if (inc_dialog->show_dialog)
485 manage_window_focus_in
486 (inc_dialog->dialog->window,
489 pass = input_dialog_query_password
490 (pop3_session->ac_prefs->recv_server,
493 if (inc_dialog->show_dialog)
494 manage_window_focus_out
495 (inc_dialog->dialog->window,
499 pop3_session->ac_prefs->tmp_pass =
501 pop3_session->pass = pass;
508 #define SET_PIXMAP_AND_TEXT(xpm, xpmmask, str) \
510 gtk_clist_set_pixmap(clist, inc_dialog->cur_row, 0, xpm, xpmmask); \
511 gtk_clist_set_text(clist, inc_dialog->cur_row, 2, str); \
514 for (; inc_dialog->queue_list != NULL; inc_dialog->cur_row++) {
515 session = inc_dialog->queue_list->data;
516 pop3_session = POP3_SESSION(session->session);
518 if (pop3_session->pass == NULL) {
519 SET_PIXMAP_AND_TEXT(okxpm, okxpmmask, _("Cancelled"));
520 inc_session_destroy(session);
521 inc_dialog->queue_list =
522 g_list_remove(inc_dialog->queue_list, session);
526 inc_progress_dialog_clear(inc_dialog);
527 gtk_clist_moveto(clist, inc_dialog->cur_row, -1, 1.0, 0.0);
529 SET_PIXMAP_AND_TEXT(currentxpm, currentxpmmask,
532 session_set_recv_message_notify(session->session,
533 inc_recv_message, session);
534 session_set_recv_data_progressive_notify
535 (session->session, inc_recv_data_progressive, session);
536 session_set_recv_data_notify(session->session,
537 inc_recv_data_finished, session);
539 /* begin POP3 session */
540 inc_state = inc_pop3_session_do(session);
544 if (pop3_session->cur_total_num > 0)
545 msg = g_strdup_printf
546 (_("Done (%d message(s) (%s) received)"),
547 pop3_session->cur_total_num,
548 to_human_readable(pop3_session->cur_total_recv_bytes));
550 msg = g_strdup_printf(_("Done (no new messages)"));
551 SET_PIXMAP_AND_TEXT(okxpm, okxpmmask, msg);
554 case INC_CONNECT_ERROR:
555 SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask,
556 _("Connection failed"));
558 case INC_AUTH_FAILED:
559 SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask,
563 SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask,
569 case INC_SOCKET_ERROR:
571 SET_PIXMAP_AND_TEXT(errorxpm, errorxpmmask, _("Error"));
574 SET_PIXMAP_AND_TEXT(okxpm, okxpmmask, _("Cancelled"));
580 if (pop3_session->error_val == PS_AUTHFAIL) {
581 if(!prefs_common.no_recv_err_panel) {
582 if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) ||
583 ((prefs_common.recv_dialog_mode == RECV_DIALOG_ACTIVE) && focus_window)) {
584 manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
587 (_("Authorization for %s on %s failed"),
589 pop3_session->ac_prefs->recv_server);
593 /* CLAWS: perform filtering actions on dropped message */
594 /* CLAWS: get default inbox (perhaps per account) */
595 if (pop3_session->ac_prefs->inbox) {
596 /* CLAWS: get destination folder / mailbox */
597 inbox = folder_find_item_from_identifier(pop3_session->ac_prefs->inbox);
599 inbox = folder_get_default_inbox();
601 inbox = folder_get_default_inbox();
603 /* get list of messages in processing */
604 processing = folder_get_default_processing();
605 folder_item_scan(processing);
606 msglist = folder_item_get_msg_list(processing);
608 folder_item_update_freeze();
610 /* process messages */
611 for(msglist_element = msglist; msglist_element != NULL; msglist_element = msglist_element->next) {
612 msginfo = (MsgInfo *) msglist_element->data;
613 if (!pop3_session->ac_prefs->filter_on_recv || !procmsg_msginfo_filter(msginfo))
614 folder_item_move_msg(inbox, msginfo);
615 procmsg_msginfo_free(msginfo);
617 g_slist_free(msglist);
619 folder_item_update_thaw();
623 new_msgs += pop3_session->cur_total_num;
625 if (pop3_session->error_val == PS_AUTHFAIL &&
626 pop3_session->ac_prefs->tmp_pass) {
627 g_free(pop3_session->ac_prefs->tmp_pass);
628 pop3_session->ac_prefs->tmp_pass = NULL;
631 pop3_write_uidl_list(pop3_session);
633 if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) {
635 if (inc_dialog->show_dialog)
636 manage_window_focus_in
637 (inc_dialog->dialog->window,
639 inc_put_error(inc_state, pop3_session->error_msg);
640 if (inc_dialog->show_dialog)
641 manage_window_focus_out
642 (inc_dialog->dialog->window,
644 if (inc_state == INC_NO_SPACE ||
645 inc_state == INC_IO_ERROR)
649 inc_session_destroy(session);
650 inc_dialog->queue_list =
651 g_list_remove(inc_dialog->queue_list, session);
654 #undef SET_PIXMAP_AND_TEXT
657 fin_msg = g_strdup_printf(_("Finished (%d new message(s))"),
660 fin_msg = g_strdup_printf(_("Finished (no new messages)"));
662 progress_dialog_set_label(inc_dialog->dialog, fin_msg);
665 if (error_num && !prefs_common.no_recv_err_panel) {
666 if (inc_dialog->show_dialog)
667 manage_window_focus_in(inc_dialog->dialog->window,
669 alertpanel_error_log(_("Some errors occurred while getting mail."));
670 if (inc_dialog->show_dialog)
671 manage_window_focus_out(inc_dialog->dialog->window,
676 while (inc_dialog->queue_list != NULL) {
677 session = inc_dialog->queue_list->data;
678 inc_session_destroy(session);
679 inc_dialog->queue_list =
680 g_list_remove(inc_dialog->queue_list, session);
683 if (prefs_common.close_recv_dialog)
684 inc_progress_dialog_destroy(inc_dialog);
686 gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window),
688 gtk_label_set_text(GTK_LABEL(GTK_BIN(inc_dialog->dialog->cancel_btn)->child),
697 static IncState inc_pop3_session_do(IncSession *session)
699 Pop3Session *pop3_session = POP3_SESSION(session->session);
700 IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data;
705 debug_print("getting new messages of account %s...\n",
706 pop3_session->ac_prefs->account_name);
708 pop3_session->ac_prefs->last_pop_login_time = time(NULL);
710 buf = g_strdup_printf(_("%s: Retrieving new messages"),
711 pop3_session->ac_prefs->recv_server);
712 gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf);
715 server = pop3_session->ac_prefs->recv_server;
717 port = pop3_session->ac_prefs->set_popport ?
718 pop3_session->ac_prefs->popport :
719 pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110;
720 SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop;
721 if (pop3_session->ac_prefs->ssl_pop != SSL_NONE)
722 SESSION(pop3_session)->nonblocking =
723 pop3_session->ac_prefs->use_nonblocking_ssl;
725 port = pop3_session->ac_prefs->set_popport ?
726 pop3_session->ac_prefs->popport : 110;
729 buf = g_strdup_printf(_("Connecting to POP3 server: %s..."), server);
730 log_message("%s\n", buf);
732 progress_dialog_set_label(inc_dialog->dialog, buf);
735 if (session_connect(SESSION(pop3_session), server, port) < 0) {
736 log_warning(_("Can't connect to POP3 server: %s:%d\n"),
738 if(!prefs_common.no_recv_err_panel) {
739 if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) ||
740 ((prefs_common.recv_dialog_mode == RECV_DIALOG_ACTIVE) && focus_window)) {
741 manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
743 alertpanel_error(_("Can't connect to POP3 server: %s:%d"),
745 manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL);
747 session->inc_state = INC_CONNECT_ERROR;
749 return INC_CONNECT_ERROR;
752 while (session_is_connected(SESSION(pop3_session)) &&
753 session->inc_state != INC_CANCEL)
754 gtk_main_iteration();
758 if (session->inc_state == INC_SUCCESS) {
759 switch (pop3_session->error_val) {
761 if (SESSION(pop3_session)->state == SESSION_ERROR) {
762 if (pop3_session->state == POP3_READY)
763 session->inc_state = INC_CONNECT_ERROR;
765 session->inc_state = INC_ERROR;
766 } else if (SESSION(pop3_session)->state == SESSION_EOF)
767 session->inc_state = INC_EOF;
769 session->inc_state = INC_SUCCESS;
772 session->inc_state = INC_AUTH_FAILED;
775 session->inc_state = INC_IO_ERROR;
778 session->inc_state = INC_SOCKET_ERROR;
781 session->inc_state = INC_LOCKED;
784 session->inc_state = INC_ERROR;
789 return session->inc_state;
792 static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog,
793 IncSession *inc_session)
795 gchar buf[MSGBUFSIZE];
796 ProgressDialog *dialog = inc_dialog->dialog;
797 Pop3Session *session;
799 g_return_if_fail(inc_session != NULL);
801 session = POP3_SESSION(inc_session->session);
803 switch (session->state) {
806 case POP3_GETAUTH_USER:
807 case POP3_GETAUTH_PASS:
808 case POP3_GETAUTH_APOP:
809 progress_dialog_set_label(dialog, _("Authenticating..."));
810 statusbar_print_all(_("Retrieving messages from %s..."),
811 SESSION(session)->server);
813 case POP3_GETRANGE_STAT:
814 progress_dialog_set_label
815 (dialog, _("Getting the number of new messages (STAT)..."));
817 case POP3_GETRANGE_LAST:
818 progress_dialog_set_label
819 (dialog, _("Getting the number of new messages (LAST)..."));
821 case POP3_GETRANGE_UIDL:
822 progress_dialog_set_label
823 (dialog, _("Getting the number of new messages (UIDL)..."));
825 case POP3_GETSIZE_LIST:
826 progress_dialog_set_label
827 (dialog, _("Getting the size of messages (LIST)..."));
830 gtk_progress_set_show_text
831 (GTK_PROGRESS(inc_dialog->mainwin->progressbar), TRUE);
832 g_snprintf(buf, sizeof(buf), "%d / %d",
833 session->cur_msg, session->count);
834 gtk_progress_set_format_string
835 (GTK_PROGRESS(inc_dialog->mainwin->progressbar), buf);
836 inc_recv_data_progressive
837 (SESSION(session), 0,
838 session->msg[session->cur_msg].size,
842 if (session->msg[session->cur_msg].recv_time <
843 session->current_time) {
844 g_snprintf(buf, sizeof(buf), _("Deleting message %d"),
846 progress_dialog_set_label(dialog, buf);
850 progress_dialog_set_label(dialog, _("Quitting"));
857 static gint inc_recv_data_progressive(Session *session, guint cur_len,
858 guint total_len, gpointer data)
860 gchar buf[MSGBUFSIZE];
861 IncSession *inc_session = (IncSession *)data;
862 Pop3Session *pop3_session = POP3_SESSION(session);
863 IncProgressDialog *inc_dialog;
864 ProgressDialog *dialog;
868 g_return_val_if_fail(inc_session != NULL, -1);
870 if (pop3_session->state != POP3_RETR &&
871 pop3_session->state != POP3_RETR_RECV &&
872 pop3_session->state != POP3_DELETE &&
873 pop3_session->state != POP3_LOGOUT) return 0;
875 if (!pop3_session->new_msg_exist) return 0;
877 inc_dialog = (IncProgressDialog *)inc_session->data;
878 dialog = inc_dialog->dialog;
880 cur_total = pop3_session->cur_total_bytes + cur_len;
881 if (cur_total > pop3_session->total_bytes)
882 cur_total = pop3_session->total_bytes;
884 Xstrdup_a(total_size, to_human_readable(pop3_session->total_bytes),
886 g_snprintf(buf, sizeof(buf),
887 _("Retrieving message (%d / %d) (%s / %s)"),
888 pop3_session->cur_msg, pop3_session->count,
889 to_human_readable(cur_total), total_size);
890 progress_dialog_set_label(dialog, buf);
891 progress_dialog_set_percentage
892 (dialog, (gfloat)cur_total / (gfloat)pop3_session->total_bytes);
893 if (inc_dialog->mainwin)
894 gtk_progress_bar_update
895 (GTK_PROGRESS_BAR(inc_dialog->mainwin->progressbar),
896 (gfloat)cur_total / (gfloat)pop3_session->total_bytes);
901 static gint inc_recv_data_finished(Session *session, guint len, gpointer data)
903 IncSession *inc_session = (IncSession *)data;
904 Pop3Session *pop3_session = POP3_SESSION(session);
905 IncProgressDialog *inc_dialog;
908 g_return_val_if_fail(inc_session != NULL, -1);
910 inc_dialog = (IncProgressDialog *)inc_session->data;
911 inc_recv_data_progressive(session, 0, len, inc_session);
912 inc_progress_dialog_set_label(inc_dialog, inc_session);
914 if (pop3_session->cur_total_num == 0) return 0;
916 msg = g_strdup_printf(_("Retrieving (%d message(s) (%s) received)"),
917 pop3_session->cur_total_num,
919 (pop3_session->cur_total_recv_bytes));
920 gtk_clist_set_text(GTK_CLIST(inc_dialog->dialog->clist),
921 inc_dialog->cur_row, 2, msg);
927 static gint inc_recv_message(Session *session, const gchar *msg, gpointer data)
929 IncSession *inc_session = (IncSession *)data;
930 IncProgressDialog *inc_dialog;
932 g_return_val_if_fail(inc_session != NULL, -1);
934 inc_dialog = (IncProgressDialog *)inc_session->data;
935 inc_progress_dialog_set_label(inc_dialog, inc_session);
940 gint inc_drop_message(const gchar *file, Pop3Session *session)
943 FolderItem *dropfolder;
946 if (session->ac_prefs->inbox) {
947 inbox = folder_find_item_from_identifier
948 (session->ac_prefs->inbox);
950 inbox = folder_get_default_inbox();
952 inbox = folder_get_default_inbox();
958 /* CLAWS: claws uses a global .processing folder for the filtering. */
959 dropfolder = folder_get_default_processing();
961 /* add msg file to drop folder */
962 if ((msgnum = folder_item_add_msg(dropfolder, file, NULL, TRUE)) < 0) {
970 static void inc_put_error(IncState istate, const gchar *msg)
972 gchar *log_msg = NULL;
973 gchar *err_msg = NULL;
974 gboolean fatal_error = FALSE;
977 case INC_CONNECT_ERROR:
978 log_msg = _("Connection failed.");
979 if (prefs_common.no_recv_err_panel)
981 err_msg = g_strdup(log_msg);
984 log_msg = _("Error occurred while processing mail.");
985 if (prefs_common.no_recv_err_panel)
988 err_msg = g_strdup_printf
989 (_("Error occurred while processing mail:\n%s"),
992 err_msg = g_strdup(log_msg);
995 log_msg = _("No disk space left.");
996 err_msg = g_strdup(log_msg);
1000 log_msg = _("Can't write file.");
1001 err_msg = g_strdup(log_msg);
1004 case INC_SOCKET_ERROR:
1005 log_msg = _("Socket error.");
1006 if (prefs_common.no_recv_err_panel)
1008 err_msg = g_strdup(log_msg);
1011 log_msg = _("Connection closed by the remote host.");
1012 if (prefs_common.no_recv_err_panel)
1014 err_msg = g_strdup(log_msg);
1017 log_msg = _("Mailbox is locked.");
1018 if (prefs_common.no_recv_err_panel)
1021 err_msg = g_strdup_printf(_("Mailbox is locked:\n%s"),
1024 err_msg = g_strdup(log_msg);
1026 case INC_AUTH_FAILED:
1027 log_msg = _("Authentication failed.");
1028 if (prefs_common.no_recv_err_panel)
1031 err_msg = g_strdup_printf
1032 (_("Authentication failed:\n%s"), msg);
1034 err_msg = g_strdup(log_msg);
1042 log_error("%s\n", log_msg);
1044 log_warning("%s\n", log_msg);
1047 alertpanel_error_log(err_msg);
1052 static void inc_cancel(IncProgressDialog *dialog)
1054 IncSession *session;
1056 g_return_if_fail(dialog != NULL);
1058 if (dialog->queue_list == NULL) {
1059 inc_progress_dialog_destroy(dialog);
1063 session = dialog->queue_list->data;
1065 session->inc_state = INC_CANCEL;
1067 log_message(_("Incorporation cancelled\n"));
1070 gboolean inc_is_active(void)
1072 return (inc_dialog_list != NULL);
1075 void inc_cancel_all(void)
1079 for (cur = inc_dialog_list; cur != NULL; cur = cur->next)
1080 inc_cancel((IncProgressDialog *)cur->data);
1083 static void inc_cancel_cb(GtkWidget *widget, gpointer data)
1085 inc_cancel((IncProgressDialog *)data);
1088 static gint inc_dialog_delete_cb(GtkWidget *widget, GdkEventAny *event,
1091 IncProgressDialog *dialog = (IncProgressDialog *)data;
1093 if (dialog->queue_list == NULL)
1094 inc_progress_dialog_destroy(dialog);
1099 static gint inc_spool(void)
1101 gchar *mbox, *logname;
1104 logname = g_get_user_name();
1105 mbox = g_strconcat(prefs_common.spool_path
1106 ? prefs_common.spool_path : DEFAULT_SPOOL_PATH,
1107 G_DIR_SEPARATOR_S, logname, NULL);
1108 msgs = get_spool(folder_get_default_inbox(), mbox);
1114 static gint inc_spool_account(PrefsAccount *account)
1118 if (account->inbox) {
1119 inbox = folder_find_item_from_path(account->inbox);
1121 inbox = folder_get_default_inbox();
1123 inbox = folder_get_default_inbox();
1125 return get_spool(inbox, account->local_mbox);
1128 static gint inc_all_spool(void)
1132 gint account_new_msgs = 0;
1134 list = account_get_list();
1135 if (!list) return 0;
1137 for (; list != NULL; list = list->next) {
1138 PrefsAccount *account = list->data;
1140 if ((account->protocol == A_LOCAL) &&
1141 (account->recv_at_getall)) {
1142 account_new_msgs = inc_spool_account(account);
1143 if (account_new_msgs > 0)
1144 new_msgs += account_new_msgs;
1151 static gint get_spool(FolderItem *dest, const gchar *mbox)
1155 gchar tmp_mbox[MAXPATHLEN + 1];
1157 g_return_val_if_fail(dest != NULL, -1);
1158 g_return_val_if_fail(mbox != NULL, -1);
1160 if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
1161 debug_print("no messages in local mailbox.\n");
1163 } else if (size < 0)
1166 if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
1169 g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%08x",
1170 get_tmp_dir(), G_DIR_SEPARATOR, (gint)mbox);
1172 if (copy_mbox(mbox, tmp_mbox) < 0) {
1173 unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1177 debug_print("Getting new messages from %s into %s...\n",
1180 msgs = proc_mbox(dest, tmp_mbox);
1183 if (msgs >= 0) empty_mbox(mbox);
1184 unlock_mbox(mbox, lockfd, LOCK_FLOCK);
1194 void inc_unlock(void)
1196 if (inc_lock_count > 0)
1200 static guint autocheck_timer = 0;
1201 static gpointer autocheck_data = NULL;
1203 static void inc_notify_cmd(gint new_msgs, gboolean notify)
1208 if (!(new_msgs && notify && prefs_common.newmail_notify_cmd &&
1209 *prefs_common.newmail_notify_cmd))
1211 if ((buf = strchr(prefs_common.newmail_notify_cmd, '%')) &&
1212 buf[1] == 'd' && !strchr(&buf[1], '%'))
1213 buf = g_strdup_printf(prefs_common.newmail_notify_cmd,
1216 buf = g_strdup(prefs_common.newmail_notify_cmd);
1218 execute_command_line(buf, TRUE);
1223 void inc_autocheck_timer_init(MainWindow *mainwin)
1225 autocheck_data = mainwin;
1226 inc_autocheck_timer_set();
1229 static void inc_autocheck_timer_set_interval(guint interval)
1231 inc_autocheck_timer_remove();
1232 /* last test is to avoid re-enabling auto_check after modifying
1233 the common preferences */
1234 if (prefs_common.autochk_newmail && autocheck_data
1235 && prefs_common.work_offline == FALSE) {
1236 autocheck_timer = gtk_timeout_add
1237 (interval, inc_autocheck_func, autocheck_data);
1238 debug_print("added timer = %d\n", autocheck_timer);
1242 void inc_autocheck_timer_set(void)
1244 inc_autocheck_timer_set_interval(prefs_common.autochk_itv * 60000);
1247 void inc_autocheck_timer_remove(void)
1249 if (autocheck_timer) {
1250 debug_print("removed timer = %d\n", autocheck_timer);
1251 gtk_timeout_remove(autocheck_timer);
1252 autocheck_timer = 0;
1256 static gint inc_autocheck_func(gpointer data)
1258 MainWindow *mainwin = (MainWindow *)data;
1260 if (inc_lock_count) {
1261 debug_print("autocheck is locked.\n");
1262 inc_autocheck_timer_set_interval(1000);
1266 inc_all_account_mail(mainwin, prefs_common.newmail_notify_auto);