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