예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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();
}
예제 #4
0
파일: inc.c 프로젝트: mrvdb/claws-mail
/**
 * 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);
	}
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
파일: inc.c 프로젝트: mrvdb/claws-mail
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;
}
예제 #8
0
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);
}
예제 #9
0
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;
}
예제 #10
0
/* 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;
}