예제 #1
0
파일: foldersel.c 프로젝트: twolife/claws
static gboolean foldersel_selected(GtkTreeSelection *selection,
				   GtkTreeModel *model, GtkTreePath *path,
				   gboolean currently_selected, gpointer data)
{
	GtkTreeIter iter;
	FolderItem *item = NULL;

	if (currently_selected)
		return TRUE;

	if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
		return TRUE;

	gtk_tree_model_get(GTK_TREE_MODEL(tree_store), &iter,
			   FOLDERSEL_FOLDERITEM, &item, -1);

	selected_item = item;
	if (selected_item && selected_item->path) {
		gchar *id;
		id = folder_item_get_identifier(selected_item);
		gtk_entry_set_text(GTK_ENTRY(entry), id);
		g_free(id);
	} else
	if (root_selectable && selected_item && selected_item->folder &&
			(FOLDER_TYPE(selected_item->folder) == F_MH ||
			 FOLDER_TYPE(selected_item->folder) == F_MBOX ||
			 FOLDER_TYPE(selected_item->folder) == F_IMAP)) {
		gchar *id = folder_get_identifier(selected_item->folder);
		gtk_entry_set_text(GTK_ENTRY(entry), id);
		g_free(id);
	} else
		gtk_entry_set_text(GTK_ENTRY(entry), "");

	return TRUE;
}
예제 #2
0
파일: foldersel.c 프로젝트: twolife/claws
static void foldersel_new_folder(GtkButton *button, gpointer data)
{
	FolderItem *new_item;
	gchar *new_folder;
	gchar *disp_name;
	gchar *p;
	GtkTreeIter selected, new_child;
	GtkTreePath *selected_p, *new_child_p;
	GtkTreeStore *store;
	GtkTreeModel *model;
	GtkTreeSelection *selection;

	if (!selected_item || FOLDER_TYPE(selected_item->folder) == F_NEWS)
		return;

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
	if (!gtk_tree_selection_get_selected(selection, &model, &selected))
		return;
	store = GTK_TREE_STORE(model);

	new_folder = input_dialog(_("New folder"),
				  _("Input the name of new folder:"),
				  _("NewFolder"));
	if (!new_folder) return;
	AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
예제 #3
0
파일: foldersel.c 프로젝트: twolife/claws
static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type)
{
	Folder *folder;
	GList *list;

	for (list = folder_get_list(); list != NULL; list = list->next) {
		folder = FOLDER(list->data);
		cm_return_if_fail(folder != NULL);

		if (type != FOLDER_SEL_ALL) {
			if (FOLDER_TYPE(folder) == F_NEWS)
				continue;
		}
		
		if (cur_folder && (cur_folder->klass != folder->klass
		    && strcmp2(cur_folder->name, folder->name) != 0))
		    continue;
		
		foldersel_insert_gnode_in_store(tree_store, folder->node, NULL);
	}

	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tree_store),
					     FOLDERSEL_FOLDERNAME,
					     GTK_SORT_ASCENDING);

	gtk_tree_view_expand_all(GTK_TREE_VIEW(treeview));
}
예제 #4
0
static void unsubscribe_newsgroup_cb(GtkAction *action, gpointer data)
{
	FolderView *folderview = (FolderView *)data;
	FolderItem *item;
	gchar *name;
	gchar *message;
	gchar *old_id;
	AlertValue avalue;
	MainWindow *mainwin = mainwindow_get_mainwindow();
	
	if (!folderview->selected) return;

	item = folderview_get_selected_item(folderview);
	cm_return_if_fail(item != NULL);

	if (mainwin->lock_count || news_folder_locked(item->folder))
		return;

	cm_return_if_fail(item->folder != NULL);
	cm_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
	cm_return_if_fail(item->folder->account != NULL);

	old_id = folder_item_get_identifier(item);

	name = trim_string(item->path, 32);
	message = g_strdup_printf(_("Really unsubscribe newsgroup '%s'?"), name);
	avalue = alertpanel_full(_("Unsubscribe newsgroup"), message,
		 	         GTK_STOCK_CANCEL, _("_Unsubscribe"), NULL,
							 ALERTFOCUS_FIRST, FALSE, NULL, ALERT_WARNING);
	g_free(message);
	g_free(name);
	if (avalue != G_ALERTALTERNATE) return;

	if (item == folderview_get_opened_item(folderview)) {
		summary_clear_all(folderview->summaryview);
		folderview_close_opened(folderview, TRUE);
	}

	if(item->folder->klass->remove_folder(item->folder, item) < 0) {
		folder_item_scan(item);
		alertpanel_error(_("Can't remove the folder '%s'."), name);
		g_free(old_id);
		return;
	}
	
	folder_write_list();
	
	prefs_filtering_delete_path(old_id);
	g_free(old_id);
}
예제 #5
0
파일: mh.c 프로젝트: ignatenkobrain/claws
static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist, 
			 GHashTable *relation)
{
	gboolean dest_need_scan = FALSE;
	gboolean src_need_scan = FALSE;
	FolderItem *src = NULL;
	gchar *srcfile;
	gchar *destfile;
	FolderItemPrefs *prefs;
	MsgInfo *msginfo = NULL;
	MsgInfoList *cur = NULL;
	gint curnum = 0, total = 0;
	gchar *srcpath = NULL;
	gboolean full_fetch = FALSE;
	time_t last_dest_mtime = (time_t)0;
	time_t last_src_mtime = (time_t)0;

	cm_return_val_if_fail(dest != NULL, -1);
	cm_return_val_if_fail(msglist != NULL, -1);
	
	msginfo = (MsgInfo *)msglist->data;

	cm_return_val_if_fail(msginfo != NULL, -1);

	if (msginfo->folder == dest) {
		g_warning("the src folder is identical to the dest.\n");
		return -1;
	}

	if (msginfo->folder->folder != dest->folder)
		full_fetch = TRUE;
	
	if (FOLDER_TYPE(msginfo->folder->folder) == F_MH) {
		src = msginfo->folder;
	}

	if (dest->last_num < 0) {
		mh_get_last_num(folder, dest);
		if (dest->last_num < 0) return -1;
	}

	prefs = dest->prefs;

	srcpath = folder_item_get_path(msginfo->folder);

	dest_need_scan = mh_scan_required(dest->folder, dest);
	last_dest_mtime = dest->mtime;

	if (src) {
		src_need_scan = mh_scan_required(src->folder, src);
		last_src_mtime = src->mtime;
	}

	total = g_slist_length(msglist);
	if (total > 100) {
		if (MSG_IS_MOVE(msginfo->flags))
			statusbar_print_all(_("Moving messages..."));
		else
			statusbar_print_all(_("Copying messages..."));
	}
	for (cur = msglist; cur; cur = cur->next) {
		msginfo = (MsgInfo *)cur->data;
		if (!msginfo) {
			goto err_reset_status;
		}
		if (!full_fetch) {
			srcfile = g_strconcat(srcpath, 
				G_DIR_SEPARATOR_S, 
				itos(msginfo->msgnum), NULL);
		} else {
			srcfile = procmsg_get_message_file(msginfo);
		}
		if (!srcfile) {
			goto err_reset_status;
		}
		destfile = mh_get_new_msg_filename(dest);
		if (!destfile) {
			g_free(srcfile);
			goto err_reset_status;
		}

		if (total > 100) {
			statusbar_progress_all(curnum, total, 100);
			if (curnum % 100 == 0)
				GTK_EVENTS_FLUSH();
			curnum++;
		}

		debug_print("Copying message %s%c%d to %s ...\n",
			    msginfo->folder->path, G_DIR_SEPARATOR,
			    msginfo->msgnum, dest->path);


		if (MSG_IS_MOVE(msginfo->flags)) {
			msginfo->flags.tmp_flags &= ~MSG_MOVE_DONE;
			if (move_file(srcfile, destfile, TRUE) < 0) {
				FILE_OP_ERROR(srcfile, "move");
				if (copy_file(srcfile, destfile, TRUE) < 0) {
					FILE_OP_ERROR(srcfile, "copy");
					g_free(srcfile);
					g_free(destfile);
					goto err_reset_status;
				}
			} else {
				/* say unlinking's not necessary */
				msginfo->flags.tmp_flags |= MSG_MOVE_DONE;
			}
		} else if (copy_file(srcfile, destfile, TRUE) < 0) {
			FILE_OP_ERROR(srcfile, "copy");
			g_free(srcfile);
			g_free(destfile);
			goto err_reset_status;
		} 
		if (prefs && prefs->enable_folder_chmod && prefs->folder_chmod) {
			if (chmod(destfile, prefs->folder_chmod) < 0)
				FILE_OP_ERROR(destfile, "chmod");
		}
		if (relation) {
			if (g_hash_table_lookup(relation, msginfo) != NULL)
				g_warning("already in : %p", msginfo);
			
			g_hash_table_insert(relation, msginfo, GINT_TO_POINTER(dest->last_num+1));
		}
		g_free(srcfile);
		g_free(destfile);
		dest->last_num++;
	}

	g_free(srcpath);
	mh_write_sequences(dest, TRUE);

	if (dest->mtime == last_dest_mtime && !dest_need_scan) {
		mh_set_mtime(folder, dest);
	}

	if (src && src->mtime == last_src_mtime && !src_need_scan) {
		mh_set_mtime(folder, src);
	}

	if (total > 100) {
		statusbar_progress_all(0,0,0);
		statusbar_pop_all();
	}
	return dest->last_num;
err_reset_status:
	g_free(srcpath);
	mh_write_sequences(dest, TRUE);
	if (total > 100) {
		statusbar_progress_all(0,0,0);
		statusbar_pop_all();
	}
	return -1;

}
예제 #6
0
static void bogofilter_do_filter(BogoFilterData *data)
{
	GPid bogo_pid;
	gint bogo_stdin, bogo_stdout;
	GError *error = NULL;
	gboolean bogo_forked;
	int status = 0;
	MsgInfo *msginfo;
	GSList *cur = NULL;
	int total = 0, curnum = 1;
	gchar *file = NULL;
	gchar buf[BUFSIZ];

	total = g_slist_length(data->msglist);

	bogo_forked = g_spawn_async_with_pipes(
			NULL, data->bogo_args,NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
			NULL, NULL, &bogo_pid, &bogo_stdin,
			&bogo_stdout, NULL, &error);
		
	if (bogo_forked == FALSE) {
		g_warning("%s", error ? error->message:"ERROR???");
		g_error_free(error);
		error = NULL;
		status = -1;
	} else {
	
		if (config.whitelist_ab) {
			gchar *ab_folderpath;

			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);
		}

		for (cur = data->msglist; cur; cur = cur->next) {
			gboolean whitelisted = FALSE;
			msginfo = (MsgInfo *)cur->data;
			debug_print("Filtering message %d (%d/%d)\n", msginfo->msgnum, curnum, total);

			if (message_callback != NULL)
				message_callback(NULL, total, curnum++, data->in_thread);

			if (config.whitelist_ab && msginfo->from && 
			    found_in_addressbook(msginfo->from))
				whitelisted = TRUE;

			/* can set flags (SCANNED, ATTACHMENT) but that's ok 
			 * as GUI updates are hooked not direct */

			file = procmsg_get_message_file(msginfo);

			if (file) {
				gchar *tmp = g_strdup_printf("%s\n",file);
				/* send filename to bogofilter */
				write_all(bogo_stdin, tmp, strlen(tmp));
				g_free(tmp);
				memset(buf, 0, sizeof(buf));
				/* get the result */
				if (read(bogo_stdout, buf, sizeof(buf)-1) < 0) {
					g_warning("bogofilter short read");
					debug_print("message %d is ham\n", msginfo->msgnum);
					data->mail_filtering_data->unfiltered = g_slist_prepend(
						data->mail_filtering_data->unfiltered, msginfo);
					data->new_hams = g_slist_prepend(data->new_hams, msginfo);
				} else {
					gchar **parts = NULL;

					buf[sizeof(buf) - 1] = '\0';
					if (strchr(buf, '/')) {
						tmp = strrchr(buf, '/')+1;
					} else {
						tmp = buf;
					}
					parts = g_strsplit(tmp, " ", 0);
					debug_print("read %s\n", buf);
					
					/* note the result if the header if needed */
					if (parts && parts[0] && parts[1] && parts[2] && 
					    FOLDER_TYPE(msginfo->folder->folder) == F_MH &&
					    config.insert_header) {
						gchar *tmpfile = get_tmp_file();
						FILE *input = claws_fopen(file, "r");
						FILE *output = claws_fopen(tmpfile, "w");
						if (strstr(parts[2], "\n"))
							*(strstr(parts[2], "\n")) = '\0';
						if (input && !output) 
							claws_fclose (input);
						else if (!input && output)
							claws_fclose (output);
						else if (input && output) {
							gchar tmpbuf[BUFFSIZE];
							gboolean err = FALSE;
							const gchar *bogosity = *parts[1] == 'S' ? "Spam":
										 (*parts[1] == 'H' ? "Ham":"Unsure");
							gchar *tmpstr = g_strdup_printf(
									"X-Bogosity: %s, spamicity=%s%s\n",
									bogosity, parts[2],
									whitelisted?" [whitelisted]":"");
							if (claws_fwrite(tmpstr, 1, strlen(tmpstr), output) < strlen(tmpstr)) {
								err = TRUE;
							} else {
								while (claws_fgets(tmpbuf, sizeof(buf), input)) {
									if (claws_fputs(tmpbuf, output) == EOF) {
										err = TRUE;
										break;
									}
								}
							}
							claws_fclose(input);
							if (claws_safe_fclose(output) == EOF)
								err = TRUE;
							if (!err)
								move_file(tmpfile, file, TRUE);
							g_free(tmpstr);
						}
						g_free(tmpfile);
					}

					/* file the mail */
					if (!whitelisted && parts && parts[0] && parts[1] && *parts[1] == 'S') {

						debug_print("message %d is spam\n", msginfo->msgnum);
						/* Spam will be filtered away, unless we want "mark only".
						 * In that case, we want it among unfiltered messages, so
						 * it gets processed further. */
						if (config.receive_spam == SPAM_MARK_ONLY) {
							data->mail_filtering_data->unfiltered = g_slist_prepend(
								data->mail_filtering_data->unfiltered, msginfo);
						} else {
							data->mail_filtering_data->filtered = g_slist_prepend(
								data->mail_filtering_data->filtered, msginfo);
						}
						data->new_spams = g_slist_prepend(data->new_spams, msginfo);

					} else if (whitelisted && parts && parts[0] && parts[1] && 
							(*parts[1] == 'S' || *parts[1] == 'U')) {

						debug_print("message %d is whitelisted %s\n", msginfo->msgnum,
							*parts[1] == 'S' ? "spam":"unsure");
						/* Whitelisted spam will *not* be filtered away, but continue
						 * their trip through filtering as if it was ham. */
						data->mail_filtering_data->unfiltered = g_slist_prepend(
							data->mail_filtering_data->unfiltered, msginfo);
						/* But it gets put in a different list, so that we 
						 * can still flag it and inform the user that it is
						 * considered a spam (so that he can teach bogo that 
						 * it was not). */
						data->whitelisted_new_spams = g_slist_prepend(data->whitelisted_new_spams, msginfo);

					} else if (config.save_unsure && parts && parts[0] && parts[1] && *parts[1] == 'U') {
						
						debug_print("message %d is unsure\n", msginfo->msgnum);
						/* Spam will be filtered away */
						data->mail_filtering_data->filtered = g_slist_prepend(
							data->mail_filtering_data->filtered, msginfo);
						data->new_unsure = g_slist_prepend(data->new_unsure, msginfo);

					} else {
						
						debug_print("message %d is ham\n", msginfo->msgnum);
						data->mail_filtering_data->unfiltered = g_slist_prepend(
							data->mail_filtering_data->unfiltered, msginfo);
						data->new_hams = g_slist_prepend(data->new_hams, msginfo);

					}
					g_strfreev(parts);
				}
				g_free(file);
			} else {
				data->mail_filtering_data->unfiltered = g_slist_prepend(
					data->mail_filtering_data->unfiltered, msginfo);
				data->new_hams = g_slist_prepend(data->new_hams, msginfo);
			}
		}
		if (config.whitelist_ab)
			end_address_completion();
	}
	if (status != -1) {
		close(bogo_stdout);
		close(bogo_stdin);
		waitpid(bogo_pid, &status, 0);
		if (!WIFEXITED(status))
			status = -1;
		else
			status = WEXITSTATUS(status);
	}

	to_filter_data->status = status; 
}
예제 #7
0
static void subscribe_newsgroup_cb(GtkAction *action, gpointer data)
{
	FolderView *folderview = (FolderView *)data;
	Folder *folder;
	FolderItem *item;
	FolderItem *rootitem;
	FolderItem *newitem;
	GSList *new_subscr;
	GSList *cur;
	GNode *gnode;
	MainWindow *mainwin = mainwindow_get_mainwindow();
	
	if ((item = folderview_get_selected_item(folderview)) == NULL) return;

	if (mainwin->lock_count || news_folder_locked(item->folder))
		return;

	folder = item->folder;
	cm_return_if_fail(folder != NULL);
	cm_return_if_fail(FOLDER_TYPE(folder) == F_NEWS);
	cm_return_if_fail(folder->account != NULL);

	if ((rootitem = folder_item_parent(item)) == NULL)
		rootitem = item;

	new_subscr = grouplist_dialog(folder);

	/* remove unsubscribed newsgroups */
	for (gnode = folder->node->children; gnode != NULL; ) {
		GNode *next = gnode->next;

		item = FOLDER_ITEM(gnode->data);
		if (g_slist_find_custom(new_subscr, item->path,
					(GCompareFunc)g_ascii_strcasecmp) != NULL) {
			gnode = next;
			continue;
		}

		if (folderview_get_opened_item(folderview) == item) {
			summary_clear_all(folderview->summaryview);
			folderview_close_opened(folderview, TRUE);
		}

		folderview_remove_item(folderview, item);
		folder_item_remove(item);

		gnode = next;
	}

	folderview_freeze(folderview);

	/* add subscribed newsgroups */
	for (cur = new_subscr; cur != NULL; cur = cur->next) {
		gchar *name = (gchar *)cur->data;
		FolderUpdateData hookdata;

		if (news_find_child_item(rootitem, name) != NULL)
			continue;

		newitem = folder_item_new(folder, name, name);
		folder_item_append(rootitem, newitem);

		hookdata.folder = newitem->folder;
		hookdata.update_flags = FOLDER_TREE_CHANGED | FOLDER_ADD_FOLDERITEM;
		hookdata.item = newitem;
		hookdata.item2 = NULL;
		hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
	}

	folderview_thaw(folderview);

	slist_free_strings_full(new_subscr);

	folder_write_list();
}