FolderItem *bogofilter_get_spam_folder(MsgInfo *msginfo) { FolderItem *item = folder_find_item_from_identifier(config.save_folder); if (item || msginfo == NULL || msginfo->folder == NULL) return item; if (msginfo->folder->folder && msginfo->folder->folder->account && msginfo->folder->folder->account->set_trash_folder) { item = folder_find_item_from_identifier( msginfo->folder->folder->account->trash_folder); } if (item == NULL && msginfo->folder->folder && msginfo->folder->folder->trash) item = msginfo->folder->folder->trash; if (item == NULL) item = folder_get_default_trash(); debug_print("bogo spam dir: %s\n", folder_item_get_path(item)); return item; }
void partial_delete_old(const gchar *file) { gchar *id = g_strdup(file); gchar *snum = strrchr(file, ':'); int num = 0; FolderItem *item = NULL; debug_print("too big message updated, should remove %s\n", file?file:"(null)"); if (snum) { snum++; } else { g_free(id); return; /* not a real problem */ } num = atoi(snum); if (strrchr(id, ':')) *(strrchr(id, ':'))='\0'; item = folder_find_item_from_identifier(id); if (item) { debug_print("removing %d in %s\n", num, id); folder_item_remove_msg(item, num); } g_free(id); }
static void import_ok_cb(GtkWidget *widget, gpointer data) { const gchar *utf8mbox, *destdir; FolderItem *dest; gchar *mbox; utf8mbox = gtk_entry_get_text(GTK_ENTRY(file_entry)); destdir = gtk_entry_get_text(GTK_ENTRY(dest_entry)); if (utf8mbox && !*utf8mbox) { alertpanel_error(_("Source mbox filename can't be left empty.")); gtk_widget_grab_focus(file_entry); return; } if (destdir && !*destdir) { if (alertpanel(_("Import mbox file"), _("Destination folder is not set.\nImport mbox file to the Inbox folder?"), GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL, ALERTFOCUS_FIRST) == G_ALERTALTERNATE) { gtk_widget_grab_focus(dest_entry); return; } } mbox = g_filename_from_utf8(utf8mbox, -1, NULL, NULL, NULL); if (!mbox) { g_warning("import_ok_cb(): failed to convert character set."); mbox = g_strdup(utf8mbox); } if (!destdir || !*destdir) { dest = folder_find_item_from_path(INBOX_DIR); } else { dest = folder_find_item_from_identifier (destdir); } if (!dest) { alertpanel_error(_("Can't find the destination folder.")); gtk_widget_grab_focus(dest_entry); g_free(mbox); return; } else { import_ok = proc_mbox(dest, mbox, FALSE, NULL); } g_free(mbox); if (gtk_main_level() > 1) gtk_main_quit(); }
/** * inc_finished: * @mainwin: Main window. * @new_messages: TRUE if some messages have been received. * * Update the folder view and the summary view after receiving * messages. If @new_messages is FALSE, this function avoids unneeded * updating. **/ static void inc_finished(MainWindow *mainwin, gboolean new_messages, gboolean autocheck) { if (prefs_common.scan_all_after_inc) folderview_check_new(NULL); if (!autocheck && new_messages && prefs_common.open_inbox_on_inc) { FolderItem *item = NULL; if (cur_account && cur_account->inbox) item = folder_find_item_from_identifier(cur_account->inbox); if (item == NULL && cur_account && cur_account->folder) item = cur_account->folder->inbox; if (item == NULL) item = folder_get_default_inbox(); folderview_unselect(mainwin->folderview); folderview_select(mainwin->folderview, item); } }
static gboolean mail_filtering_hook(gpointer source, gpointer data) { MailFilteringData *mail_filtering_data = (MailFilteringData *) source; MsgInfo *msginfo = mail_filtering_data->msginfo; MimeInfo *mimeinfo; struct clamd_result result; if (!config.clamav_enable) return FALSE; mimeinfo = procmime_scan_message(msginfo); if (!mimeinfo) return FALSE; debug_print("Scanning message %d for viruses\n", msginfo->msgnum); if (message_callback != NULL) message_callback(_("ClamAV: scanning message...")); g_node_traverse(mimeinfo->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, scan_func, &result); debug_print("status: %d\n", result.status); if (result.status == VIRUS) { if (config.clamav_recv_infected) { FolderItem *clamav_save_folder; if ((!config.clamav_save_folder) || (config.clamav_save_folder[0] == '\0') || ((clamav_save_folder = folder_find_item_from_identifier(config.clamav_save_folder)) == NULL)) clamav_save_folder = folder_get_default_trash(); procmsg_msginfo_unset_flags(msginfo, ~0, 0); msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = clamav_save_folder; } else { folder_item_remove_msg(msginfo->folder, msginfo->msgnum); } } procmime_mimeinfo_free_all(mimeinfo); return (result.status == OK) ? FALSE : TRUE; }
static gboolean mail_filtering_hook(gpointer source, gpointer data) { MailFilteringData *mail_filtering_data = (MailFilteringData *) source; MsgInfo *msginfo = mail_filtering_data->msginfo; GSList *msglist = mail_filtering_data->msglist; GSList *cur = NULL; static gboolean warned_error = FALSE; int status = 0; int total = 0, curnum = 0; GSList *new_hams = NULL, *new_spams = NULL; GSList *new_unsure, *whitelisted_new_spams = NULL; gchar *bogo_exec = (config.bogopath && *config.bogopath) ? config.bogopath:"bogofilter"; gchar *bogo_args[4]; gboolean ok_to_thread = TRUE; bogo_args[0] = bogo_exec; bogo_args[1] = "-T"; bogo_args[2] = "-b"; bogo_args[3] = NULL; if (!config.process_emails) { return FALSE; } if (msglist == NULL && msginfo != NULL) { g_warning("wrong call to bogofilter mail_filtering_hook"); return FALSE; } total = g_slist_length(msglist); /* we have to make sure the mails are cached - or it'll break on IMAP */ if (message_callback != NULL) message_callback(_("Bogofilter: fetching bodies..."), total, 0, FALSE); for (cur = msglist; cur; cur = cur->next) { gchar *file = procmsg_get_message_file((MsgInfo *)cur->data); if (file == NULL) ok_to_thread = FALSE; if (message_callback != NULL) message_callback(NULL, total, curnum++, FALSE); g_free(file); } if (message_callback != NULL) message_callback(NULL, 0, 0, FALSE); if (message_callback != NULL) message_callback(_("Bogofilter: filtering messages..."), total, 0, FALSE); #ifdef USE_PTHREAD while (pthread_mutex_trylock(&list_mutex) != 0) { GTK_EVENTS_FLUSH(); usleep(100); } #endif to_filter_data = g_new0(BogoFilterData, 1); to_filter_data->msglist = msglist; to_filter_data->mail_filtering_data = mail_filtering_data; to_filter_data->new_hams = NULL; to_filter_data->new_unsure = NULL; to_filter_data->new_spams = NULL; to_filter_data->whitelisted_new_spams = NULL; to_filter_data->done = FALSE; to_filter_data->status = -1; to_filter_data->bogo_args = bogo_args; #ifdef USE_PTHREAD to_filter_data->in_thread = (filter_th != 0 && ok_to_thread); #else to_filter_data->in_thread = FALSE; #endif #ifdef USE_PTHREAD pthread_mutex_unlock(&list_mutex); if (filter_th != 0 && ok_to_thread) { debug_print("waking thread to let it filter things\n"); pthread_mutex_lock(&wait_mutex); pthread_cond_broadcast(&wait_cond); pthread_mutex_unlock(&wait_mutex); while (!to_filter_data->done) { GTK_EVENTS_FLUSH(); usleep(100); } } while (pthread_mutex_trylock(&list_mutex) != 0) { GTK_EVENTS_FLUSH(); usleep(100); } if (filter_th == 0 || !ok_to_thread) bogofilter_do_filter(to_filter_data); #else bogofilter_do_filter(to_filter_data); #endif new_hams = to_filter_data->new_hams; new_unsure = to_filter_data->new_unsure; new_spams = to_filter_data->new_spams; whitelisted_new_spams = to_filter_data->whitelisted_new_spams; status = to_filter_data->status; g_free(to_filter_data); to_filter_data = NULL; #ifdef USE_PTHREAD pthread_mutex_unlock(&list_mutex); #endif /* unflag hams */ for (cur = new_hams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("unflagging ham: %d\n", msginfo->msgnum); } /* unflag unsure */ for (cur = new_unsure; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("unflagging unsure: %d\n", msginfo->msgnum); } if (config.learn_from_whitelist && whitelisted_new_spams) { /* flag whitelisted spams */ for (cur = whitelisted_new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); debug_print("flagging whitelisted non-ham: %d\n", msginfo->msgnum); } /* correct bogo */ bogofilter_learn(NULL, whitelisted_new_spams, FALSE); /* unflag them */ for (cur = whitelisted_new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("unflagging whitelisted non-ham: %d\n", msginfo->msgnum); } } else { for (cur = whitelisted_new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("not flagging whitelisted non-ham: %d\n", msginfo->msgnum); } } /* flag spams and delete them if config.receive_spam == 0 * (if config.receive_spam is set to 1, we'll move them later, * mark as spam only if set to 2) */ for (cur = new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; if (config.receive_spam != SPAM_DELETE) { if (config.mark_as_read) procmsg_msginfo_unset_flags(msginfo, ~0, 0); procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); } else { folder_item_remove_msg(msginfo->folder, msginfo->msgnum); } } if (status < 0 || status > 2) { /* I/O or other errors */ gchar *msg = NULL; if (status == 3) msg = g_strdup_printf(_("The Bogofilter plugin couldn't filter " "a message. The probable cause of the " "error is that it didn't learn from any mail.\n" "Use \"/Mark/Mark as spam\" and \"/Mark/Mark as " "ham\" to train Bogofilter with a few hundred " "spam and ham messages.")); else msg = g_strdup_printf(_("The Bogofilter plugin couldn't filter " "a message. The command `%s %s %s` couldn't be run."), bogo_args[0], bogo_args[1], bogo_args[2]); if (!prefs_common_get_prefs()->no_recv_err_panel) { if (!warned_error) { alertpanel_error("%s", msg); } warned_error = TRUE; } else { log_error(LOG_PROTOCOL, "%s\n", msg); } g_free(msg); } if (status < 0 || status > 2) { g_slist_free(mail_filtering_data->filtered); g_slist_free(mail_filtering_data->unfiltered); mail_filtering_data->filtered = NULL; mail_filtering_data->unfiltered = NULL; } else { if (config.receive_spam == SPAM_MARK_AND_SAVE && new_spams) { FolderItem *save_folder = NULL; if ((!config.save_folder) || (config.save_folder[0] == '\0') || ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL)) { if (mail_filtering_data->account && mail_filtering_data->account->set_trash_folder) { save_folder = folder_find_item_from_identifier( mail_filtering_data->account->trash_folder); if (save_folder) debug_print("found trash folder from account's advanced settings\n"); } if (save_folder == NULL && mail_filtering_data->account && mail_filtering_data->account->folder) { save_folder = mail_filtering_data->account->folder->trash; if (save_folder) debug_print("found trash folder from account's trash\n"); } if (save_folder == NULL && mail_filtering_data->account && !mail_filtering_data->account->folder) { if (mail_filtering_data->account->inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's inbox\n"); } } if (!save_folder && mail_filtering_data->account->local_inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->local_inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's local_inbox\n"); } } } if (save_folder == NULL) { debug_print("using default trash folder\n"); save_folder = folder_get_default_trash(); } } if (save_folder) { for (cur = new_spams; cur; cur = cur->next) { msginfo = (MsgInfo *)cur->data; msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = save_folder; } } } if (config.save_unsure && new_unsure) { FolderItem *save_unsure_folder = NULL; if ((!config.save_unsure_folder) || (config.save_unsure_folder[0] == '\0') || ((save_unsure_folder = folder_find_item_from_identifier(config.save_unsure_folder)) == NULL)) { if (mail_filtering_data->account) save_unsure_folder = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (save_unsure_folder == NULL && mail_filtering_data->account && mail_filtering_data->account->folder) save_unsure_folder = mail_filtering_data->account->folder->inbox; if (save_unsure_folder == NULL && mail_filtering_data->account && !mail_filtering_data->account->folder) { if (mail_filtering_data->account->inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (item) { save_unsure_folder = item; } } if (!save_unsure_folder && mail_filtering_data->account->local_inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->local_inbox); if (item) { save_unsure_folder = item; } } } if (save_unsure_folder == NULL) save_unsure_folder = folder_get_default_inbox(); } if (save_unsure_folder) { for (cur = new_unsure; cur; cur = cur->next) { msginfo = (MsgInfo *)cur->data; msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = save_unsure_folder; } } } } g_slist_free(new_hams); g_slist_free(new_unsure); g_slist_free(new_spams); g_slist_free(whitelisted_new_spams); if (message_callback != NULL) message_callback(NULL, 0, 0, FALSE); mail_filtering_data->filtered = g_slist_reverse( mail_filtering_data->filtered); mail_filtering_data->unfiltered = g_slist_reverse( mail_filtering_data->unfiltered); return FALSE; }
static gint inc_start(IncProgressDialog *inc_dialog) { IncSession *session; GList *qlist; Pop3Session *pop3_session; IncState inc_state; gint error_num = 0; gint new_msgs = 0; gchar *msg; gchar *fin_msg; FolderItem *processing, *inbox; GSList *msglist, *msglist_element; gboolean cancelled = FALSE; qlist = inc_dialog->queue_list; while (qlist != NULL) { GList *next = qlist->next; session = qlist->data; pop3_session = POP3_SESSION(session->session); pop3_session->user = g_strdup(pop3_session->ac_prefs->userid); if (pop3_session->ac_prefs->passwd) pop3_session->pass = g_strdup(pop3_session->ac_prefs->passwd); else { gchar *pass; if (inc_dialog->show_dialog) manage_window_focus_in (inc_dialog->dialog->window, NULL, NULL); pass = input_dialog_query_password_keep (pop3_session->ac_prefs->recv_server, pop3_session->user, &(pop3_session->ac_prefs->session_passwd)); if (inc_dialog->show_dialog) manage_window_focus_out (inc_dialog->dialog->window, NULL, NULL); if (pass) { pop3_session->pass = pass; } } qlist = next; } #define SET_PIXMAP_AND_TEXT(pix, str) \ { \ progress_dialog_list_set(inc_dialog->dialog, \ inc_dialog->cur_row, \ pix, \ NULL, \ str); \ } for (; inc_dialog->queue_list != NULL && !cancelled; inc_dialog->cur_row++) { session = inc_dialog->queue_list->data; pop3_session = POP3_SESSION(session->session); GSList *filtered, *unfiltered; if (pop3_session->pass == NULL) { SET_PIXMAP_AND_TEXT(okpix, _("Cancelled")); inc_session_destroy(session); inc_dialog->queue_list = g_list_remove(inc_dialog->queue_list, session); continue; } inc_progress_dialog_clear(inc_dialog); progress_dialog_scroll_to_row(inc_dialog->dialog, inc_dialog->cur_row); SET_PIXMAP_AND_TEXT(currentpix, _("Retrieving")); /* begin POP3 session */ inc_state = inc_pop3_session_do(session); switch (inc_state) { case INC_SUCCESS: if (pop3_session->cur_total_num > 0) msg = g_strdup_printf( ngettext("Done (%d message (%s) received)", "Done (%d messages (%s) received)", pop3_session->cur_total_num), pop3_session->cur_total_num, to_human_readable((goffset)pop3_session->cur_total_recv_bytes)); else msg = g_strdup_printf(_("Done (no new messages)")); SET_PIXMAP_AND_TEXT(okpix, msg); g_free(msg); break; case INC_CONNECT_ERROR: SET_PIXMAP_AND_TEXT(errorpix, _("Connection failed")); break; case INC_AUTH_FAILED: SET_PIXMAP_AND_TEXT(errorpix, _("Auth failed")); if (pop3_session->ac_prefs->session_passwd) { g_free(pop3_session->ac_prefs->session_passwd); pop3_session->ac_prefs->session_passwd = NULL; } break; case INC_LOCKED: SET_PIXMAP_AND_TEXT(errorpix, _("Locked")); break; case INC_ERROR: case INC_NO_SPACE: case INC_IO_ERROR: case INC_SOCKET_ERROR: case INC_EOF: SET_PIXMAP_AND_TEXT(errorpix, _("Error")); break; case INC_TIMEOUT: SET_PIXMAP_AND_TEXT(errorpix, _("Timeout")); break; case INC_CANCEL: SET_PIXMAP_AND_TEXT(okpix, _("Cancelled")); if (!inc_dialog->show_dialog) cancelled = TRUE; break; default: break; } if (pop3_session->error_val == PS_AUTHFAIL) { if(!prefs_common.no_recv_err_panel) { if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) || ((prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL) && focus_window)) manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL); } } /* CLAWS: perform filtering actions on dropped message */ /* CLAWS: get default inbox (perhaps per account) */ if (pop3_session->ac_prefs->inbox) { /* CLAWS: get destination folder / mailbox */ inbox = folder_find_item_from_identifier(pop3_session->ac_prefs->inbox); if (!inbox) inbox = folder_get_default_inbox(); } else inbox = folder_get_default_inbox(); /* get list of messages in processing */ processing = folder_get_default_processing(); folder_item_scan(processing); msglist = folder_item_get_msg_list(processing); /* process messages */ folder_item_update_freeze(); procmsg_msglist_filter(msglist, pop3_session->ac_prefs, &filtered, &unfiltered, pop3_session->ac_prefs->filter_on_recv); filtering_move_and_copy_msgs(msglist); if (unfiltered != NULL) folder_item_move_msgs(inbox, unfiltered); for(msglist_element = msglist; msglist_element != NULL; msglist_element = msglist_element->next) { MsgInfo *msginfo = (MsgInfo *)msglist_element->data; procmsg_msginfo_free(msginfo); } folder_item_update_thaw(); g_slist_free(msglist); g_slist_free(filtered); g_slist_free(unfiltered); statusbar_pop_all(); new_msgs += pop3_session->cur_total_num; pop3_write_uidl_list(pop3_session); if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) { error_num++; if (inc_dialog->show_dialog) manage_window_focus_in (inc_dialog->dialog->window, NULL, NULL); inc_put_error(inc_state, pop3_session); if (inc_dialog->show_dialog) manage_window_focus_out (inc_dialog->dialog->window, NULL, NULL); if (inc_state == INC_NO_SPACE || inc_state == INC_IO_ERROR) break; } folder_item_free_cache(processing, TRUE); inc_session_destroy(session); inc_dialog->queue_list = g_list_remove(inc_dialog->queue_list, session); } #undef SET_PIXMAP_AND_TEXT if (new_msgs > 0) fin_msg = g_strdup_printf(ngettext("Finished (%d new message)", "Finished (%d new messages)", new_msgs), new_msgs); else fin_msg = g_strdup_printf(_("Finished (no new messages)")); progress_dialog_set_label(inc_dialog->dialog, fin_msg); while (inc_dialog->queue_list != NULL) { session = inc_dialog->queue_list->data; inc_session_destroy(session); inc_dialog->queue_list = g_list_remove(inc_dialog->queue_list, session); } if (prefs_common.close_recv_dialog || !inc_dialog->show_dialog) inc_progress_dialog_destroy(inc_dialog); else { gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), fin_msg); gtk_button_set_label(GTK_BUTTON(inc_dialog->dialog->cancel_btn), GTK_STOCK_CLOSE); } g_free(fin_msg); return new_msgs; }
gint procmsg_send_message_queue(const gchar *file) { static HeaderEntry qentry[] = {{"S:", NULL, FALSE}, {"SSV:", NULL, FALSE}, {"R:", NULL, FALSE}, {"NG:", NULL, FALSE}, {"MAID:", NULL, FALSE}, {"NAID:", NULL, FALSE}, {"SCF:", NULL, FALSE}, {"RMID:", NULL, FALSE}, {"FMID:", NULL, FALSE}, {"X-Sylpheed-Privacy-System:", NULL, FALSE}, {"X-Sylpheed-Encrypt:", NULL, FALSE}, {"X-Sylpheed-Encrypt-Data:", NULL, FALSE}, {NULL, NULL, FALSE}}; FILE *fp; gint filepos; gint mailval = 0, newsval = 0; gchar *from = NULL; gchar *smtpserver = NULL; GSList *to_list = NULL; GSList *newsgroup_list = NULL; gchar *savecopyfolder = NULL; gchar *replymessageid = NULL; gchar *fwdmessageid = NULL; gchar *privacy_system = NULL; gboolean encrypt = FALSE; gchar *encrypt_data = NULL; gchar buf[BUFFSIZE]; gint hnum; PrefsAccount *mailac = NULL, *newsac = NULL; gboolean save_clear_text = TRUE; gchar *tmp_enc_file = NULL; int local = 0; g_return_val_if_fail(file != NULL, -1); if ((fp = fopen(file, "rb")) == NULL) { FILE_OP_ERROR(file, "fopen"); return -1; } while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, qentry)) != -1) { gchar *p = buf + strlen(qentry[hnum].name); switch (hnum) { case Q_SENDER: if (from == NULL) from = g_strdup(p); break; case Q_SMTPSERVER: if (smtpserver == NULL) smtpserver = g_strdup(p); break; case Q_RECIPIENTS: to_list = address_list_append(to_list, p); break; case Q_NEWSGROUPS: newsgroup_list = newsgroup_list_append(newsgroup_list, p); break; case Q_MAIL_ACCOUNT_ID: mailac = account_find_from_id(atoi(p)); break; case Q_NEWS_ACCOUNT_ID: newsac = account_find_from_id(atoi(p)); break; case Q_SAVE_COPY_FOLDER: if (savecopyfolder == NULL) savecopyfolder = g_strdup(p); break; case Q_REPLY_MESSAGE_ID: if (replymessageid == NULL) replymessageid = g_strdup(p); break; case Q_FWD_MESSAGE_ID: if (fwdmessageid == NULL) fwdmessageid = g_strdup(p); break; case Q_PRIVACY_SYSTEM: if (privacy_system == NULL) privacy_system = g_strdup(p); break; case Q_ENCRYPT: if (p[0] == '1') encrypt = TRUE; break; case Q_ENCRYPT_DATA: if (encrypt_data == NULL) encrypt_data = g_strdup(p); break; } } filepos = ftell(fp); if (encrypt) { MimeInfo *mimeinfo; save_clear_text = (mailac != NULL && mailac->save_encrypted_as_clear_text); fclose(fp); fp = NULL; mimeinfo = procmime_scan_queue_file(file); if (!privacy_encrypt(privacy_system, mimeinfo, encrypt_data) || (fp = my_tmpfile()) == NULL || procmime_write_mimeinfo(mimeinfo, fp) < 0) { if (fp) fclose(fp); procmime_mimeinfo_free_all(mimeinfo); g_free(from); g_free(smtpserver); slist_free_strings(to_list); g_slist_free(to_list); slist_free_strings(newsgroup_list); g_slist_free(newsgroup_list); g_free(savecopyfolder); g_free(replymessageid); g_free(fwdmessageid); g_free(privacy_system); g_free(encrypt_data); return -1; } rewind(fp); if (!save_clear_text) { gchar *content = NULL; FILE *tmpfp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmp_enc_file); if (tmpfp) { fclose(tmpfp); content = file_read_stream_to_str(fp); rewind(fp); str_write_to_file(content, tmp_enc_file); g_free(content); } else { g_warning("couldn't get tempfile\n"); } } procmime_mimeinfo_free_all(mimeinfo); filepos = 0; } if (to_list) { debug_print("Sending message by mail\n"); if (!from) { g_warning("Queued message header is broken.\n"); mailval = -1; } else if (mailac && mailac->use_mail_command && mailac->mail_command && (* mailac->mail_command)) { mailval = send_message_local(mailac->mail_command, fp); local = 1; } else { if (!mailac) { mailac = account_find_from_smtp_server(from, smtpserver); if (!mailac) { g_warning("Account not found. " "Using current account...\n"); mailac = cur_account; } } if (mailac) mailval = send_message_smtp(mailac, to_list, fp); else { PrefsAccount tmp_ac; g_warning("Account not found.\n"); memset(&tmp_ac, 0, sizeof(PrefsAccount)); tmp_ac.address = from; tmp_ac.smtp_server = smtpserver; tmp_ac.smtpport = SMTP_PORT; mailval = send_message_smtp(&tmp_ac, to_list, fp); } } } fseek(fp, filepos, SEEK_SET); if (newsgroup_list && (mailval == 0)) { Folder *folder; gchar *tmp = NULL; FILE *tmpfp; /* write to temporary file */ tmp = g_strdup_printf("%s%ctmp%d", g_get_tmp_dir(), G_DIR_SEPARATOR, (gint)file); if ((tmpfp = fopen(tmp, "wb")) == NULL) { FILE_OP_ERROR(tmp, "fopen"); newsval = -1; alertpanel_error(_("Could not create temporary file for news sending.")); } else { if (change_file_mode_rw(tmpfp, tmp) < 0) { FILE_OP_ERROR(tmp, "chmod"); g_warning("can't change file mode\n"); } while ((newsval == 0) && fgets(buf, sizeof(buf), fp) != NULL) { if (fputs(buf, tmpfp) == EOF) { FILE_OP_ERROR(tmp, "fputs"); newsval = -1; alertpanel_error(_("Error when writing temporary file for news sending.")); } } fclose(tmpfp); if (newsval == 0) { debug_print("Sending message by news\n"); folder = FOLDER(newsac->folder); newsval = news_post(folder, tmp); if (newsval < 0) { alertpanel_error(_("Error occurred while posting the message to %s ."), newsac->nntp_server); } } unlink(tmp); } g_free(tmp); } fclose(fp); /* save message to outbox */ if (mailval == 0 && newsval == 0 && savecopyfolder) { FolderItem *outbox; debug_print("saving sent message...\n"); outbox = folder_find_item_from_identifier(savecopyfolder); if (!outbox) outbox = folder_get_default_outbox(); if (save_clear_text || tmp_enc_file == NULL) { procmsg_save_to_outbox(outbox, file, TRUE); } else { procmsg_save_to_outbox(outbox, tmp_enc_file, FALSE); } } if (tmp_enc_file != NULL) { unlink(tmp_enc_file); free(tmp_enc_file); tmp_enc_file = NULL; } if (replymessageid != NULL || fwdmessageid != NULL) { gchar **tokens; FolderItem *item; if (replymessageid != NULL) tokens = g_strsplit(replymessageid, "\x7f", 0); else tokens = g_strsplit(fwdmessageid, "\x7f", 0); item = folder_find_item_from_identifier(tokens[0]); /* check if queued message has valid folder and message id */ if (item != NULL && tokens[2] != NULL) { MsgInfo *msginfo; msginfo = folder_item_get_msginfo(item, atoi(tokens[1])); /* check if referring message exists and has a message id */ if ((msginfo != NULL) && (msginfo->msgid != NULL) && (strcmp(msginfo->msgid, tokens[2]) != 0)) { procmsg_msginfo_free(msginfo); msginfo = NULL; } if (msginfo == NULL) { msginfo = folder_item_get_msginfo_by_msgid(item, tokens[2]); } if (msginfo != NULL) { if (replymessageid != NULL) { procmsg_msginfo_unset_flags(msginfo, MSG_FORWARDED, 0); procmsg_msginfo_set_flags(msginfo, MSG_REPLIED, 0); } else { procmsg_msginfo_unset_flags(msginfo, MSG_REPLIED, 0); procmsg_msginfo_set_flags(msginfo, MSG_FORWARDED, 0); } procmsg_msginfo_free(msginfo); } } g_strfreev(tokens); } g_free(from); g_free(smtpserver); slist_free_strings(to_list); g_slist_free(to_list); slist_free_strings(newsgroup_list); g_slist_free(newsgroup_list); g_free(savecopyfolder); g_free(replymessageid); g_free(fwdmessageid); g_free(privacy_system); g_free(encrypt_data); return (newsval != 0 ? newsval : mailval); }
static gboolean mail_filtering_hook(gpointer source, gpointer data) { MailFilteringData *mail_filtering_data = (MailFilteringData *) source; MsgInfo *msginfo = mail_filtering_data->msginfo; gboolean is_spam = FALSE, error = FALSE; static gboolean warned_error = FALSE; FILE *fp = NULL; int pid = 0; int status; /* SPAMASSASSIN_DISABLED : keep test for compatibility purpose */ if (!config.enable || config.transport == SPAMASSASSIN_DISABLED) { log_warning(LOG_PROTOCOL, _("SpamAssassin plugin is disabled by its preferences.\n")); return FALSE; } debug_print("Filtering message %d\n", msginfo->msgnum); if (message_callback != NULL) message_callback(_("SpamAssassin: filtering message...")); if ((fp = procmsg_open_message(msginfo)) == NULL) { debug_print("failed to open message file\n"); return FALSE; } if (config.whitelist_ab) { gchar *ab_folderpath; gboolean whitelisted = FALSE; if (*config.whitelist_ab_folder == '\0' || strcasecmp(config.whitelist_ab_folder, "Any") == 0) { /* match the whole addressbook */ ab_folderpath = NULL; } else { /* match the specific book/folder of the addressbook */ ab_folderpath = config.whitelist_ab_folder; } start_address_completion(ab_folderpath); if (msginfo->from && sa_found_in_addressbook(msginfo->from)) whitelisted = TRUE; end_address_completion(); if (whitelisted) { debug_print("message is ham (whitelisted)\n"); fclose(fp); return FALSE; } } pid = fork(); if (pid == 0) { _exit(msg_is_spam(fp)); } else { gint running = 0; running |= CHILD_RUNNING; g_timeout_add(50, timeout_func, &running); running |= TIMEOUT_RUNNING; while(running & CHILD_RUNNING) { int ret; ret = waitpid(pid, &status, WNOHANG); if (ret == pid) { if (WIFEXITED(status)) { MsgStatus result = MSG_IS_HAM; running &= ~CHILD_RUNNING; result = WEXITSTATUS(status); is_spam = (result == MSG_IS_SPAM) ? TRUE : FALSE; error = (result == MSG_FILTERING_ERROR); } } if (ret < 0) { running &= ~CHILD_RUNNING; } /* ret == 0 continue */ g_main_context_iteration(NULL, TRUE); } while (running & TIMEOUT_RUNNING) g_main_context_iteration(NULL, TRUE); } fclose(fp); if (is_spam) { debug_print("message is spam\n"); procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); if (config.receive_spam) { FolderItem *save_folder = NULL; if ((!config.save_folder) || (config.save_folder[0] == '\0') || ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL)) { if (mail_filtering_data->account && mail_filtering_data->account->set_trash_folder) { save_folder = folder_find_item_from_identifier( mail_filtering_data->account->trash_folder); if (save_folder) debug_print("found trash folder from account's advanced settings\n"); } if (save_folder == NULL && mail_filtering_data->account && mail_filtering_data->account->folder) { save_folder = mail_filtering_data->account->folder->trash; if (save_folder) debug_print("found trash folder from account's trash\n"); } if (save_folder == NULL && mail_filtering_data->account && !mail_filtering_data->account->folder) { if (mail_filtering_data->account->inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's inbox\n"); } } if (!save_folder && mail_filtering_data->account->local_inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->local_inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's local_inbox\n"); } } } if (save_folder == NULL) { debug_print("using default trash folder\n"); save_folder = folder_get_default_trash(); } } if (config.mark_as_read) procmsg_msginfo_unset_flags(msginfo, ~0, 0); procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = save_folder; } else { folder_item_remove_msg(msginfo->folder, msginfo->msgnum); } return TRUE; } else { debug_print("message is ham\n"); procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); } if (error) { gchar *msg = _("The SpamAssassin plugin couldn't filter " "a message. The probable cause of the error " "is an unreachable spamd daemon. Please make " "sure spamd is running and accessible."); if (!prefs_common_get_prefs()->no_recv_err_panel) { if (!warned_error) { alertpanel_error("%s", msg); } warned_error = TRUE; } else { log_error(LOG_PROTOCOL, "%s\n", msg); } } return FALSE; }
/* Read selections from a common xml-file. Called when loading the plugin. * Returns TRUE if data has been read, FALSE if no data is available * or an error occurred. * This is analog to folder.h::folder_read_list. */ gboolean notification_foldercheck_read_array(void) { gchar *path; GNode *rootnode, *node, *branchnode; XMLNode *xmlnode; gboolean success = FALSE; path = foldercheck_get_array_path(); if(!is_file_exist(path)) { path = NULL; return FALSE; } /* We don't do merging, so if the file existed, clear what we have stored in memory right now.. */ notification_free_folder_specific_array(); /* .. and evaluate the file */ rootnode = xml_parse_file(path); path = NULL; if(!rootnode) return FALSE; xmlnode = rootnode->data; /* Check that root entry is "foldercheckarray" */ if(strcmp2(xmlnode->tag->tag, "foldercheckarray") != 0) { g_warning("wrong foldercheck array file"); xml_free_tree(rootnode); return FALSE; } /* Process branch entries */ for(branchnode = rootnode->children; branchnode != NULL; branchnode = branchnode->next) { GList *list; guint id; SpecificFolderArrayEntry *entry = NULL; xmlnode = branchnode->data; if(strcmp2(xmlnode->tag->tag, "branch") != 0) { g_warning("tag name != \"branch\""); return FALSE; } /* Attributes of the branch nodes */ list = xmlnode->tag->attr; for(; list != NULL; list = list->next) { XMLAttr *attr = list->data; if(attr && attr->name && attr->value && !strcmp2(attr->name, "name")) { id = notification_register_folder_specific_list(attr->value); entry = foldercheck_get_entry_from_id(id); /* We have found something */ success = TRUE; break; } } if((list == NULL) || (entry == NULL)) { g_warning("Did not find attribute \"name\" in tag \"branch\""); continue; /* with next branch */ } /* Now descent into the children of the brach, which are the folderitems */ for(node = branchnode->children; node != NULL; node = node->next) { FolderItem *item = NULL; /* These should all be leaves. */ if(!G_NODE_IS_LEAF(node)) g_warning("Subnodes in \"branch\" nodes should all be leaves. " "Ignoring deeper subnodes."); /* Check if tag is "folderitem" */ xmlnode = node->data; if(strcmp2(xmlnode->tag->tag, "folderitem") != 0) { g_warning("tag name != \"folderitem\""); continue; /* to next node in branch */ } /* Attributes of the leaf nodes */ list = xmlnode->tag->attr; for(; list != NULL; list = list->next) { XMLAttr *attr = list->data; if(attr && attr->name && attr->value && !strcmp2(attr->name, "identifier")) { item = folder_find_item_from_identifier(attr->value); break; } } if((list == NULL) || (item == NULL)) { g_warning("Did not find attribute \"identifier\" in tag " "\"folderitem\""); continue; /* with next leaf node */ } /* Store all FolderItems in the list */ /* We started with a cleared array, so we don't need to check if it's already in there. */ entry->list = g_slist_prepend(entry->list, item); } /* for all subnodes in branch */ } /* for all branches */ return success; }