static void alertpanel_show(void) { gint x, y, w, h, sx, sy; value = G_ALERTWAIT; inc_lock(); sx = gdk_screen_width(); sy = gdk_screen_height(); gdk_window_get_origin(dialog->window, &x, &y); w = dialog->allocation.width; h = dialog->allocation.height; if (x < 0 || y < 0 || x + w > sx || y + h > sy) { debug_print("sx, sy, x, y, w, h = %d, %d, %d, %d, %d, %d\n", sx, sy, x, y, w, h); debug_print("alert dialog position out of range\n"); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ALWAYS); } while ((value & G_ALERT_VALUE_MASK) == G_ALERTWAIT) gtk_main_iteration(); gtk_widget_destroy(dialog); GTK_EVENTS_FLUSH(); alertpanel_is_open = FALSE; inc_unlock(); }
static gint mh_remove_msgs(Folder *folder, FolderItem *item, MsgInfoList *msglist, GHashTable *relation) { gboolean need_scan = FALSE; gchar *path, *file; time_t last_mtime = (time_t)0; MsgInfoList *cur; gint total = 0, curnum = 0; cm_return_val_if_fail(item != NULL, -1); path = folder_item_get_path(item); need_scan = mh_scan_required(folder, item); last_mtime = item->mtime; total = g_slist_length(msglist); if (total > 100) { statusbar_print_all(_("Deleting messages...")); } for (cur = msglist; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; if (msginfo == NULL) continue; if (MSG_IS_MOVE(msginfo->flags) && MSG_IS_MOVE_DONE(msginfo->flags)) { msginfo->flags.tmp_flags &= ~MSG_MOVE_DONE; continue; } if (total > 100) { statusbar_progress_all(curnum, total, 100); if (curnum % 100 == 0) GTK_EVENTS_FLUSH(); curnum++; } file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL); if (file == NULL) continue; if (claws_unlink(file) < 0) { g_free(file); continue; } g_free(file); } if (total > 100) { statusbar_progress_all(0,0,0); statusbar_pop_all(); } if (item->mtime == last_mtime && !need_scan) { mh_set_mtime(folder, item); } g_free(path); return 0; }
static gchar *news_fetch_msg(Folder *folder, FolderItem *item, gint num) { gchar *path, *filename; NewsSession *session; gint ok; cm_return_val_if_fail(folder != NULL, NULL); cm_return_val_if_fail(item != NULL, NULL); path = folder_item_get_path(item); if (!is_dir_exist(path)) make_dir_hier(path); filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL); g_free(path); if (is_file_exist(filename)) { debug_print("article %d has been already cached.\n", num); return filename; } session = news_session_get(folder); if (!session) { g_free(filename); return NULL; } ok = news_select_group(folder, item->path, NULL, NULL, NULL); if (ok != NEWSNNTP_NO_ERROR) { if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; } g_free(filename); return NULL; } debug_print("getting article %d...\n", num); ok = news_get_article(folder, num, filename); if (ok != NEWSNNTP_NO_ERROR) { g_warning("can't read article %d", num); if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; } g_free(filename); return NULL; } GTK_EVENTS_FLUSH(); return filename; }
static gboolean grouplist_recv_func(SockInfo *sock, gint count, gint read_bytes, gpointer data) { gchar buf[BUFFSIZE]; g_snprintf(buf, sizeof(buf), _("%d newsgroups received (%s read)"), count, to_human_readable((goffset)read_bytes)); gtk_label_set_text(GTK_LABEL(status_label), buf); GTK_EVENTS_FLUSH(); if (ack == FALSE) return FALSE; else return TRUE; }
GSList *grouplist_dialog(Folder *folder) { GNode *node; FolderItem *item; if (dialog && gtk_widget_get_visible(dialog)) return NULL; if (!dialog) grouplist_dialog_create(); news_folder = folder; gtk_widget_show(dialog); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); manage_window_set_transient(GTK_WINDOW(dialog)); gtk_widget_grab_focus(ok_button); gtk_widget_grab_focus(ctree); GTK_EVENTS_FLUSH(); subscribed = NULL; for (node = folder->node->children; node != NULL; node = node->next) { item = FOLDER_ITEM(node->data); subscribed = g_slist_append(subscribed, g_strdup(item->path)); } grouplist_dialog_set_list(NULL, TRUE); if (ack) gtk_main(); manage_window_focus_out(dialog, NULL, NULL); gtk_widget_hide(dialog); if (!ack) { slist_free_strings_full(subscribed); subscribed = NULL; for (node = folder->node->children; node != NULL; node = node->next) { item = FOLDER_ITEM(node->data); subscribed = g_slist_append(subscribed, g_strdup(item->path)); } } grouplist_clear(); return subscribed; }
static gchar *input_dialog_open(const gchar *title, const gchar *message, const gchar *default_string) { gchar *str; gtkut_box_set_reverse_order(GTK_BOX(confirm_area), !prefs_common.comply_gnome_hig); input_dialog_set(title, message, default_string); gtk_widget_show(dialog); ack = fin = FALSE; inc_lock(); while (fin == FALSE) gtk_main_iteration(); manage_window_focus_out(dialog, NULL, NULL); if (ack) { GtkEditable *editable; if (type == INPUT_DIALOG_COMBO) editable = GTK_EDITABLE(GTK_COMBO(combo)->entry); else editable = GTK_EDITABLE(entry); str = gtk_editable_get_chars(editable, 0, -1); if (str && *str == '\0') { g_free(str); str = NULL; } } else str = NULL; gtk_widget_destroy(dialog); dialog = msg_label = entry = combo = confirm_area = ok_button = NULL; GTK_EVENTS_FLUSH(); inc_unlock(); if (type != INPUT_DIALOG_INVISIBLE) debug_print("return string = %s\n", str ? str : "(none)"); return str; }
static gboolean gtk_message_callback(gpointer data) { BsCbData *cbdata = (BsCbData *)data; if (cbdata->message) statusbar_print_all("%s", cbdata->message); else if (cbdata->total == 0) { statusbar_pop_all(); } if (cbdata->total && cbdata->done) statusbar_progress_all(cbdata->done, cbdata->total, 10); else statusbar_progress_all(0,0,0); g_free(cbdata->message); g_free(cbdata); GTK_EVENTS_FLUSH(); return FALSE; }
static void bogofilter_stop_thread(void) { void *res; while (pthread_mutex_trylock(&list_mutex) != 0) { GTK_EVENTS_FLUSH(); usleep(100); } if (filter_th != 0) { filter_th_done = TRUE; debug_print("waking thread up\n"); pthread_mutex_lock(&wait_mutex); pthread_cond_broadcast(&wait_cond); pthread_mutex_unlock(&wait_mutex); pthread_join(filter_th, &res); filter_th = 0; } pthread_mutex_unlock(&list_mutex); debug_print("thread done\n"); }
static void mh_get_last_num(Folder *folder, FolderItem *item) { gchar *path; GDir *dp; const gchar *d; GError *error = NULL; gint max = 0; gint num; cm_return_if_fail(item != NULL); debug_print("mh_get_last_num(): Scanning %s ...\n", item->path?item->path:"(null)"); path = folder_item_get_path(item); cm_return_if_fail(path != NULL); if (change_dir(path) < 0) { g_free(path); return; } g_free(path); if ((dp = g_dir_open(".", 0, &error)) == NULL) { g_message("Couldn't open current directory: %s (%d).\n", error->message, error->code); g_error_free(error); return; } while ((d = g_dir_read_name(dp)) != NULL) { if ((num = to_number(d)) > 0 && g_file_test(d, G_FILE_TEST_IS_REGULAR)) { if (max < num) max = num; } if (num % 2000 == 0) GTK_EVENTS_FLUSH(); } g_dir_close(dp); debug_print("Last number in dir %s = %d\n", item->path?item->path:"(null)", max); item->last_num = max; }
static void alertpanel_show(void) { gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); manage_window_set_transient(GTK_WINDOW(dialog)); gtk_widget_show_all(dialog); value = G_ALERTWAIT; if (gdk_pointer_is_grabbed()) gdk_pointer_ungrab(GDK_CURRENT_TIME); inc_lock(); while ((value & G_ALERT_VALUE_MASK) == G_ALERTWAIT) gtk_main_iteration(); gtk_widget_destroy(dialog); GTK_EVENTS_FLUSH(); alertpanel_is_open = FALSE; hooks_invoke(ALERTPANEL_OPENED_HOOKLIST, &alertpanel_is_open); inc_unlock(); }
static void mh_get_last_num(Folder *folder, FolderItem *item) { gchar *path; DIR *dp; struct dirent *d; gint max = 0; gint num; cm_return_if_fail(item != NULL); debug_print("mh_get_last_num(): Scanning %s ...\n", item->path?item->path:"(null)"); path = folder_item_get_path(item); cm_return_if_fail(path != NULL); if (change_dir(path) < 0) { g_free(path); return; } g_free(path); if ((dp = opendir(".")) == NULL) { FILE_OP_ERROR(item->path, "opendir"); return; } while ((d = readdir(dp)) != NULL) { if ((num = to_number(d->d_name)) > 0 && dirent_is_regular_file(d)) { if (max < num) max = num; } if (num % 2000 == 0) GTK_EVENTS_FLUSH(); } closedir(dp); debug_print("Last number in dir %s = %d\n", item->path?item->path:"(null)", max); item->last_num = max; }
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 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 IncState inc_pop3_session_do(IncSession *session) { Pop3Session *pop3_session = POP3_SESSION(session->session); IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data; gchar *server; gchar *account_name; gushort port; gchar *buf; debug_print("getting new messages of account %s...\n", pop3_session->ac_prefs->account_name); pop3_session->ac_prefs->last_pop_login_time = time(NULL); buf = g_strdup_printf(_("%s: Retrieving new messages"), pop3_session->ac_prefs->recv_server); gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf); g_free(buf); server = pop3_session->ac_prefs->recv_server; account_name = pop3_session->ac_prefs->account_name; #ifdef USE_GNUTLS port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110; SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop; if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) SESSION(pop3_session)->nonblocking = pop3_session->ac_prefs->use_nonblocking_ssl; #else if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) { if (alertpanel_full(_("Insecure connection"), _("This connection is configured to be secured " "using SSL, but SSL is not available in this " "build of Claws Mail. \n\n" "Do you want to continue connecting to this " "server? The communication would not be " "secure."), GTK_STOCK_CANCEL, _("Con_tinue connecting"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) return INC_CANCEL; } port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : 110; #endif buf = g_strdup_printf(_("Account '%s': Connecting to POP3 server: %s:%d..."), account_name, server, port); statuswindow_print_all("%s", buf); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(inc_dialog->dialog, buf); GTK_EVENTS_FLUSH(); g_free(buf); session_set_timeout(SESSION(pop3_session), prefs_common.io_timeout_secs * 1000); if (session_connect(SESSION(pop3_session), server, port) < 0) { 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); } alertpanel_error(_("Can't connect to POP3 server: %s:%d"), server, port); manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL); } else { log_error(LOG_PROTOCOL, _("Can't connect to POP3 server: %s:%d\n"), server, port); } session->inc_state = INC_CONNECT_ERROR; statuswindow_pop_all(); return INC_CONNECT_ERROR; } while (session_is_running(SESSION(pop3_session)) && session->inc_state != INC_CANCEL) gtk_main_iteration(); if (session->inc_state == INC_SUCCESS) { switch (pop3_session->error_val) { case PS_SUCCESS: switch (SESSION(pop3_session)->state) { case SESSION_ERROR: if (pop3_session->state == POP3_READY) session->inc_state = INC_CONNECT_ERROR; else session->inc_state = INC_ERROR; break; case SESSION_EOF: session->inc_state = INC_EOF; break; case SESSION_TIMEOUT: session->inc_state = INC_TIMEOUT; break; default: session->inc_state = INC_SUCCESS; break; } break; case PS_AUTHFAIL: session->inc_state = INC_AUTH_FAILED; break; case PS_IOERR: session->inc_state = INC_IO_ERROR; break; case PS_SOCKET: session->inc_state = INC_SOCKET_ERROR; break; case PS_LOCKBUSY: session->inc_state = INC_LOCKED; break; default: session->inc_state = INC_ERROR; break; } } session_disconnect(SESSION(pop3_session)); statusbar_pop_all(); return session->inc_state; }
gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter, PrefsAccount *account) /* return values: -1 error, >=0 number of msgs added */ { FILE *mbox_fp; gchar buf[MESSAGEBUFSIZE]; gchar *tmp_file; gint msgs = 0; gint lines; MsgInfo *msginfo; gboolean more; GSList *to_filter = NULL, *filtered = NULL, *unfiltered = NULL, *cur, *to_add = NULL; gboolean printed = FALSE; FolderItem *dropfolder; cm_return_val_if_fail(dest != NULL, -1); cm_return_val_if_fail(mbox != NULL, -1); debug_print("Getting messages from %s into %s...\n", mbox, dest->path); if ((mbox_fp = g_fopen(mbox, "rb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); alertpanel_error(_("Could not open mbox file:\n%s\n"), mbox); return -1; } /* ignore empty lines on the head */ do { if (fgets(buf, sizeof(buf), mbox_fp) == NULL) { g_warning("can't read mbox file.\n"); fclose(mbox_fp); return -1; } } while (buf[0] == '\n' || buf[0] == '\r'); if (strncmp(buf, "From ", 5) != 0) { g_warning("invalid mbox format: %s\n", mbox); fclose(mbox_fp); return -1; } tmp_file = get_tmp_file(); folder_item_update_freeze(); if (apply_filter) dropfolder = folder_get_default_processing(); else dropfolder = dest; do { FILE *tmp_fp; gint empty_lines; gint msgnum; if (msgs > 0 && msgs%500 == 0) { if (printed) statusbar_pop_all(); statusbar_print_all( ngettext("Importing from mbox... (%d mail imported)", "Importing from mbox... (%d mails imported)", msgs), msgs); printed=TRUE; GTK_EVENTS_FLUSH(); } if ((tmp_fp = g_fopen(tmp_file, "wb")) == NULL) { FILE_OP_ERROR(tmp_file, "fopen"); g_warning("can't open temporary file\n"); fclose(mbox_fp); g_free(tmp_file); return -1; } if (change_file_mode_rw(tmp_fp, tmp_file) < 0) { FILE_OP_ERROR(tmp_file, "chmod"); } empty_lines = 0; lines = 0; /* process all lines from mboxrc file */ while (fgets(buf, sizeof(buf), mbox_fp) != NULL) { int offset; /* eat empty lines */ if (buf[0] == '\n' || buf[0] == '\r') { empty_lines++; continue; } /* From separator or quoted From */ offset = 0; /* detect leading '>' char(s) */ while ((buf[offset] == '>')) { offset++; } if (!strncmp(buf+offset, "From ", 5)) { /* From separator: */ if (offset == 0) { /* expect next mbox item */ break; } /* quoted From: */ /* flush any eaten empty line */ if (empty_lines > 0) { while (empty_lines-- > 0) { FPUTS_TO_TMP_ABORT_IF_FAIL("\n"); } empty_lines = 0; } /* store the unquoted line */ FPUTS_TO_TMP_ABORT_IF_FAIL(buf + 1); continue; } /* other line */ /* flush any eaten empty line */ if (empty_lines > 0) { while (empty_lines-- > 0) { FPUTS_TO_TMP_ABORT_IF_FAIL("\n"); } empty_lines = 0; } /* store the line itself */ FPUTS_TO_TMP_ABORT_IF_FAIL(buf); } /* end of mbox item or end of mbox */ /* flush any eaten empty line (but the last one) */ if (empty_lines > 0) { while (--empty_lines > 0) { FPUTS_TO_TMP_ABORT_IF_FAIL("\n"); } } /* more emails to expect? */ more = !feof(mbox_fp); /* warn if email part is empty (it's the minimum check we can do */ if (lines == 0) { g_warning("malformed mbox: %s: message %d is empty\n", mbox, msgs); fclose(tmp_fp); fclose(mbox_fp); claws_unlink(tmp_file); return -1; } if (fclose(tmp_fp) == EOF) { FILE_OP_ERROR(tmp_file, "fclose"); g_warning("can't write to temporary file\n"); fclose(mbox_fp); claws_unlink(tmp_file); g_free(tmp_file); return -1; } if (apply_filter) { if ((msgnum = folder_item_add_msg(dropfolder, tmp_file, NULL, TRUE)) < 0) { fclose(mbox_fp); claws_unlink(tmp_file); g_free(tmp_file); return -1; } msginfo = folder_item_get_msginfo(dropfolder, msgnum); to_filter = g_slist_prepend(to_filter, msginfo); } else { MsgFileInfo *finfo = g_new0(MsgFileInfo, 1); finfo->file = tmp_file; to_add = g_slist_prepend(to_add, finfo); tmp_file = get_tmp_file(); /* flush every 500 */ if (msgs > 0 && msgs % 500 == 0) { folder_item_add_msgs(dropfolder, to_add, TRUE); procmsg_message_file_list_free(to_add); to_add = NULL; } } msgs++; } while (more); if (printed) statusbar_pop_all(); if (apply_filter) { folder_item_set_batch(dropfolder, FALSE); procmsg_msglist_filter(to_filter, account, &filtered, &unfiltered, TRUE); folder_item_set_batch(dropfolder, TRUE); filtering_move_and_copy_msgs(to_filter); for (cur = filtered; cur; cur = g_slist_next(cur)) { MsgInfo *info = (MsgInfo *)cur->data; procmsg_msginfo_free(info); } unfiltered = g_slist_reverse(unfiltered); if (unfiltered) { folder_item_move_msgs(dest, unfiltered); for (cur = unfiltered; cur; cur = g_slist_next(cur)) { MsgInfo *info = (MsgInfo *)cur->data; procmsg_msginfo_free(info); } } g_slist_free(unfiltered); g_slist_free(filtered); g_slist_free(to_filter); } else if (to_add) { folder_item_add_msgs(dropfolder, to_add, TRUE); procmsg_message_file_list_free(to_add); to_add = NULL; } folder_item_update_thaw(); g_free(tmp_file); fclose(mbox_fp); debug_print("%d messages found.\n", msgs); return msgs; }
gint lock_mbox(const gchar *base, LockType type) { #ifdef G_OS_UNIX gint retval = 0; if (type == LOCK_FILE) { gchar *lockfile, *locklink; gint retry = 0; FILE *lockfp; lockfile = g_strdup_printf("%s.%d", base, getpid()); if ((lockfp = g_fopen(lockfile, "wb")) == NULL) { FILE_OP_ERROR(lockfile, "fopen"); g_warning("can't create lock file %s\n", lockfile); g_warning("use 'flock' instead of 'file' if possible.\n"); g_free(lockfile); return -1; } if (fprintf(lockfp, "%d\n", getpid()) < 0) { FILE_OP_ERROR(lockfile, "fprintf"); g_free(lockfile); fclose(lockfp); return -1; } if (fclose(lockfp) == EOF) { FILE_OP_ERROR(lockfile, "fclose"); g_free(lockfile); return -1; } locklink = g_strconcat(base, ".lock", NULL); while (link(lockfile, locklink) < 0) { FILE_OP_ERROR(lockfile, "link"); if (retry >= 5) { g_warning("can't create %s\n", lockfile); claws_unlink(lockfile); g_free(lockfile); return -1; } if (retry == 0) g_warning("mailbox is owned by another" " process, waiting...\n"); retry++; sleep(5); } claws_unlink(lockfile); g_free(lockfile); } else if (type == LOCK_FLOCK) { gint lockfd; gboolean fcntled = FALSE; #if HAVE_FCNTL_H && !defined(G_OS_WIN32) struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; #endif #if HAVE_FLOCK if ((lockfd = g_open(base, O_RDWR, 0)) < 0) { #else if ((lockfd = g_open(base, O_RDWR, 0)) < 0) { #endif FILE_OP_ERROR(base, "open"); return -1; } #if HAVE_FCNTL_H && !defined(G_OS_WIN32) if (fcntl(lockfd, F_SETLK, &fl) == -1) { g_warning("can't fnctl %s (%s)", base, strerror(errno)); return -1; } else { fcntled = TRUE; } #endif #if HAVE_FLOCK if (flock(lockfd, LOCK_EX|LOCK_NB) < 0 && !fcntled) { perror("flock"); #else #if HAVE_LOCKF if (lockf(lockfd, F_TLOCK, 0) < 0 && !fcntled) { perror("lockf"); #else { #endif #endif /* HAVE_FLOCK */ g_warning("can't lock %s\n", base); if (close(lockfd) < 0) perror("close"); return -1; } retval = lockfd; } else { g_warning("invalid lock type\n"); return -1; } return retval; #else return -1; #endif /* G_OS_UNIX */ } gint unlock_mbox(const gchar *base, gint fd, LockType type) { if (type == LOCK_FILE) { gchar *lockfile; lockfile = g_strconcat(base, ".lock", NULL); if (claws_unlink(lockfile) < 0) { FILE_OP_ERROR(lockfile, "unlink"); g_free(lockfile); return -1; } g_free(lockfile); return 0; } else if (type == LOCK_FLOCK) { gboolean fcntled = FALSE; #if HAVE_FCNTL_H && !defined(G_OS_WIN32) struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; if (fcntl(fd, F_SETLK, &fl) == -1) { g_warning("can't fnctl %s", base); } else { fcntled = TRUE; } #endif #if HAVE_FLOCK if (flock(fd, LOCK_UN) < 0 && !fcntled) { perror("flock"); #else #if HAVE_LOCKF if (lockf(fd, F_ULOCK, 0) < 0 && !fcntled) { perror("lockf"); #else { #endif #endif /* HAVE_FLOCK */ g_warning("can't unlock %s\n", base); if (close(fd) < 0) perror("close"); return -1; } if (close(fd) < 0) { perror("close"); return -1; } return 0; } g_warning("invalid lock type\n"); return -1; } gint copy_mbox(gint srcfd, const gchar *dest) { FILE *dest_fp; ssize_t n_read; gchar buf[BUFSIZ]; gboolean err = FALSE; int save_errno = 0; if (srcfd < 0) { return -1; } if ((dest_fp = g_fopen(dest, "wb")) == NULL) { FILE_OP_ERROR(dest, "fopen"); return -1; } if (change_file_mode_rw(dest_fp, dest) < 0) { FILE_OP_ERROR(dest, "chmod"); g_warning("can't change file mode\n"); } while ((n_read = read(srcfd, buf, sizeof(buf))) > 0) { if (n_read == -1 && errno != 0) { save_errno = errno; break; } if (fwrite(buf, 1, n_read, dest_fp) < n_read) { g_warning("writing to %s failed.\n", dest); fclose(dest_fp); claws_unlink(dest); return -1; } } if (save_errno != 0) { g_warning("error %d reading mbox: %s\n", save_errno, strerror(save_errno)); err = TRUE; } if (fclose(dest_fp) == EOF) { FILE_OP_ERROR(dest, "fclose"); err = TRUE; } if (err) { claws_unlink(dest); return -1; } return 0; } void empty_mbox(const gchar *mbox) { FILE *fp; if ((fp = g_fopen(mbox, "wb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); g_warning("can't truncate mailbox to zero.\n"); return; } fclose(fp); } gint export_list_to_mbox(GSList *mlist, const gchar *mbox) /* return values: -2 skipped, -1 error, 0 OK */ { GSList *cur; MsgInfo *msginfo; FILE *msg_fp; FILE *mbox_fp; gchar buf[BUFFSIZE]; int err = 0; gint msgs = 1, total = g_slist_length(mlist); if (g_file_test(mbox, G_FILE_TEST_EXISTS) == TRUE) { if (alertpanel_full(_("Overwrite mbox file"), _("This file already exists. Do you want to overwrite it?"), GTK_STOCK_CANCEL, _("Overwrite"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) { return -2; } } if ((mbox_fp = g_fopen(mbox, "wb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); alertpanel_error(_("Could not create mbox file:\n%s\n"), mbox); return -1; } #ifdef HAVE_FGETS_UNLOCKED flockfile(mbox_fp); #endif statuswindow_print_all(_("Exporting to mbox...")); for (cur = mlist; cur != NULL; cur = cur->next) { int len; gchar buft[BUFFSIZE]; msginfo = (MsgInfo *)cur->data; msg_fp = procmsg_open_message(msginfo); if (!msg_fp) { continue; } #ifdef HAVE_FGETS_UNLOCKED flockfile(msg_fp); #endif strncpy2(buf, msginfo->from ? msginfo->from : cur_account && cur_account->address ? cur_account->address : "unknown", sizeof(buf)); extract_address(buf); if (fprintf(mbox_fp, "From %s %s", buf, ctime_r(&msginfo->date_t, buft)) < 0) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } buf[0] = '\0'; /* write email to mboxrc */ while (SC_FGETS(buf, sizeof(buf), msg_fp) != NULL) { /* quote any From, >From, >>From, etc., according to mbox format specs */ int offset; offset = 0; /* detect leading '>' char(s) */ while ((buf[offset] == '>')) { offset++; } if (!strncmp(buf+offset, "From ", 5)) { if (SC_FPUTC('>', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } if (SC_FPUTS(buf, mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } /* force last line to end w/ a newline */ len = strlen(buf); if (len > 0) { len--; if ((buf[len] != '\n') && (buf[len] != '\r')) { if (SC_FPUTC('\n', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } } /* add a trailing empty line */ if (SC_FPUTC('\n', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); statusbar_progress_all(msgs++,total, 500); if (msgs%500 == 0) GTK_EVENTS_FLUSH(); } out: statusbar_progress_all(0,0,0); statuswindow_pop_all(); #ifdef HAVE_FGETS_UNLOCKED funlockfile(mbox_fp); #endif fclose(mbox_fp); return err; }
gint send_message_smtp_full(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp, gboolean keep_session) { Session *session; SMTPSession *smtp_session; gushort port = 0; gchar buf[BUFFSIZE]; gint ret = 0; gboolean was_inited = FALSE; MsgInfo *tmp_msginfo = NULL; MsgFlags flags = {0, 0}; long fp_pos = 0; gchar spec_from[BUFFSIZE]; ProxyInfo *proxy_info = NULL; cm_return_val_if_fail(ac_prefs != NULL, -1); cm_return_val_if_fail(ac_prefs->address != NULL, -1); cm_return_val_if_fail(ac_prefs->smtp_server != NULL, -1); cm_return_val_if_fail(to_list != NULL, -1); cm_return_val_if_fail(fp != NULL, -1); /* get the From address used, not necessarily the ac_prefs', * because it's editable. */ fp_pos = ftell(fp); if (fp_pos < 0) { perror("ftell"); return -1; } tmp_msginfo = procheader_parse_stream(fp, flags, TRUE, FALSE); if (fseek(fp, fp_pos, SEEK_SET) < 0) { perror("fseek"); return -1; } if (tmp_msginfo && tmp_msginfo->extradata && tmp_msginfo->extradata->resent_from) { strncpy2(spec_from, tmp_msginfo->extradata->resent_from, BUFFSIZE-1); extract_address(spec_from); } else if (tmp_msginfo && tmp_msginfo->from) { strncpy2(spec_from, tmp_msginfo->from, BUFFSIZE-1); extract_address(spec_from); } else { strncpy2(spec_from, ac_prefs->address, BUFFSIZE-1); } if (tmp_msginfo) { procmsg_msginfo_free(&tmp_msginfo); } if (!ac_prefs->session) { /* we can't reuse a previously initialised session */ session = smtp_session_new(ac_prefs); session->ssl_cert_auto_accept = ac_prefs->ssl_certs_auto_accept; smtp_session = SMTP_SESSION(session); if (ac_prefs->set_domain && ac_prefs->domain && strlen(ac_prefs->domain)) { smtp_session->hostname = g_strdup(ac_prefs->domain); } else { smtp_session->hostname = NULL; } #ifdef USE_GNUTLS port = ac_prefs->set_smtpport ? ac_prefs->smtpport : ac_prefs->ssl_smtp == SSL_TUNNEL ? SSMTP_PORT : SMTP_PORT; session->ssl_type = ac_prefs->ssl_smtp; if (ac_prefs->ssl_smtp != SSL_NONE) session->nonblocking = ac_prefs->use_nonblocking_ssl; if (ac_prefs->set_gnutls_priority && ac_prefs->gnutls_priority && strlen(ac_prefs->gnutls_priority)) session->gnutls_priority = g_strdup(ac_prefs->gnutls_priority); session->use_tls_sni = ac_prefs->use_tls_sni; #else if (ac_prefs->ssl_smtp != SSL_NONE) { if (alertpanel_full(_("Insecure connection"), _("This connection is configured to be secured " "using SSL/TLS, but SSL/TLS is not available " "in this build of Claws Mail. \n\n" "Do you want to continue connecting to this " "server? The communication would not be " "secure."), GTK_STOCK_CANCEL, _("Con_tinue connecting"), NULL, ALERTFOCUS_FIRST, FALSE, NULL, ALERT_WARNING) != G_ALERTALTERNATE) { session_destroy(session); return -1; } } port = ac_prefs->set_smtpport ? ac_prefs->smtpport : SMTP_PORT; #endif if (ac_prefs->use_smtp_auth) { smtp_session->forced_auth_type = ac_prefs->smtp_auth_type; if (ac_prefs->smtp_userid && strlen(ac_prefs->smtp_userid)) { smtp_session->user = g_strdup(ac_prefs->smtp_userid); if (password_get(smtp_session->user, ac_prefs->smtp_server, "smtp", port, &(smtp_session->pass))) { /* NOP */; } else if ((smtp_session->pass = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_SEND)) == NULL) { smtp_session->pass = input_dialog_query_password_keep (ac_prefs->smtp_server, smtp_session->user, &(ac_prefs->session_smtp_passwd)); if (!smtp_session->pass) { session_destroy(session); return -1; } } } else { smtp_session->user = g_strdup(ac_prefs->userid); if (password_get(smtp_session->user, ac_prefs->smtp_server, "smtp", port, &(smtp_session->pass))) { /* NOP */; } else if ((smtp_session->pass = passwd_store_get_account( ac_prefs->account_id, PWS_ACCOUNT_RECV)) == NULL) { smtp_session->pass = input_dialog_query_password_keep (ac_prefs->smtp_server, smtp_session->user, &(ac_prefs->session_smtp_passwd)); if (!smtp_session->pass) { session_destroy(session); return -1; } } } } else { smtp_session->user = NULL; smtp_session->pass = NULL; } send_dialog = send_progress_dialog_create(); send_dialog->session = session; smtp_session->dialog = send_dialog; progress_dialog_list_set(send_dialog->dialog, 0, NULL, ac_prefs->smtp_server, _("Connecting")); if (ac_prefs->pop_before_smtp && (ac_prefs->protocol == A_POP3) && (time(NULL) - ac_prefs->last_pop_login_time) > (60 * ac_prefs->pop_before_smtp_timeout)) { g_snprintf(buf, sizeof(buf), _("Doing POP before SMTP...")); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(send_dialog->dialog, buf); progress_dialog_list_set_status(send_dialog->dialog, 0, _("POP before SMTP")); GTK_EVENTS_FLUSH(); inc_pop_before_smtp(ac_prefs); } g_snprintf(buf, sizeof(buf), _("Account '%s': Connecting to SMTP server: %s:%d..."), ac_prefs->account_name, ac_prefs->smtp_server, port); progress_dialog_set_label(send_dialog->dialog, buf); log_message(LOG_PROTOCOL, "%s\n", buf); session_set_recv_message_notify(session, send_recv_message, send_dialog); session_set_send_data_progressive_notify (session, send_send_data_progressive, send_dialog); session_set_send_data_notify(session, send_send_data_finished, send_dialog); } else { /* everything is ready to start at MAIL FROM:, just * reinit useful variables. */ session = SESSION(ac_prefs->session); ac_prefs->session = NULL; smtp_session = SMTP_SESSION(session); smtp_session->state = SMTP_HELO; send_dialog = (SendProgressDialog *)smtp_session->dialog; was_inited = TRUE; } /* This has to be initialised for every mail sent */ smtp_session->from = g_strdup(spec_from); smtp_session->to_list = to_list; smtp_session->cur_to = to_list; smtp_session->send_data = (guchar *)get_outgoing_rfc2822_str(fp); smtp_session->send_data_len = strlen((gchar *)smtp_session->send_data); if (ac_prefs->use_proxy && ac_prefs->use_proxy_for_send) { if (ac_prefs->use_default_proxy) { proxy_info = (ProxyInfo *)&(prefs_common.proxy_info); if (proxy_info->use_proxy_auth) proxy_info->proxy_pass = passwd_store_get(PWS_CORE, PWS_CORE_PROXY, PWS_CORE_PROXY_PASS); } else { proxy_info = (ProxyInfo *)&(ac_prefs->proxy_info); if (proxy_info->use_proxy_auth) proxy_info->proxy_pass = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_PROXY_PASS); } } SESSION(smtp_session)->proxy_info = proxy_info; session_set_timeout(session, prefs_common.io_timeout_secs * 1000); /* connect if necessary */ if (!was_inited && session_connect(session, ac_prefs->smtp_server, port) < 0) { session_destroy(session); send_progress_dialog_destroy(send_dialog); ac_prefs->session = NULL; return -1; } debug_print("send_message_smtp(): begin event loop\n"); if (was_inited) { /* as the server is quiet, start sending ourselves */ smtp_from(smtp_session); } while (session_is_running(session) && send_dialog->cancelled == FALSE && SMTP_SESSION(session)->state != SMTP_MAIL_SENT_OK) gtk_main_iteration(); if (SMTP_SESSION(session)->error_val == SM_AUTHFAIL) { if (ac_prefs->session_smtp_passwd) { g_free(ac_prefs->session_smtp_passwd); ac_prefs->session_smtp_passwd = NULL; } ret = -1; } else if (SMTP_SESSION(session)->state == SMTP_MAIL_SENT_OK) { log_message(LOG_PROTOCOL, "%s\n", _("Mail sent successfully.")); ret = 0; } else if (session->state == SESSION_EOF && SMTP_SESSION(session)->state == SMTP_QUIT) { /* consider EOF right after QUIT successful */ log_warning(LOG_PROTOCOL, "%s\n", _("Connection closed by the remote host.")); ret = 0; } else if (session->state == SESSION_ERROR || session->state == SESSION_EOF || session->state == SESSION_TIMEOUT || SMTP_SESSION(session)->state == SMTP_ERROR || SMTP_SESSION(session)->error_val != SM_OK) ret = -1; else if (send_dialog->cancelled == TRUE) ret = -1; if (ret == -1) { manage_window_focus_in(send_dialog->dialog->window, NULL, NULL); send_put_error(session); manage_window_focus_out(send_dialog->dialog->window, NULL, NULL); } /* if we should close the connection, let's do it. * Close it in case of error, too, as it helps reinitializing things * easier. */ if (!keep_session || ret != 0) { if (session_is_connected(session)) smtp_quit(smtp_session); while (session_is_connected(session) && !send_dialog->cancelled) gtk_main_iteration(); session_destroy(session); ac_prefs->session = NULL; send_progress_dialog_destroy(send_dialog); } else { g_free(smtp_session->from); g_free(smtp_session->send_data); g_free(smtp_session->error_msg); } if (keep_session && ret == 0 && ac_prefs->session == NULL) ac_prefs->session = SMTP_SESSION(session); statusbar_pop_all(); statusbar_verbosity_set(FALSE); return ret; }
static gchar *input_dialog_open(const gchar *title, const gchar *message, const gchar *checkbtn_label, const gchar *default_string, gboolean default_checkbtn_state, gboolean *remember) { gchar *str; if (dialog && gtk_widget_get_visible(dialog)) return NULL; if (!dialog) input_dialog_create(FALSE); if (checkbtn_label) gtk_button_set_label(GTK_BUTTON(remember_checkbtn), checkbtn_label); else gtk_button_set_label(GTK_BUTTON(remember_checkbtn), _("Remember this")); input_dialog_set(title, message, default_string); gtk_window_present(GTK_WINDOW(dialog)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remember_checkbtn), default_checkbtn_state); if (remember) gtk_widget_show(remember_checkbtn); else gtk_widget_hide(remember_checkbtn); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); manage_window_set_transient(GTK_WINDOW(dialog)); ack = fin = FALSE; while (fin == FALSE) gtk_main_iteration(); manage_window_focus_out(dialog, NULL, NULL); if (ack) { GtkEditable *editable; if (type == INPUT_DIALOG_COMBO) editable = GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((combo)))); else editable = GTK_EDITABLE(entry); str = gtk_editable_get_chars(editable, 0, -1); if (str && *str == '\0' && !is_pass) { g_free(str); str = NULL; } } else str = NULL; GTK_EVENTS_FLUSH(); if (remember) { *remember = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(remember_checkbtn)); } gtk_widget_destroy(dialog); dialog = NULL; if (is_pass) debug_print("return string = %s\n", str ? "********": ("none")); else debug_print("return string = %s\n", str ? str : "(none)"); return str; }
void master_passphrase_change_dialog() { static PangoFontDescription *font_desc; GtkWidget *dialog; GtkWidget *vbox, *hbox; GtkWidget *icon, *table, *label; GtkWidget *msg_title; GtkWidget *entry_old, *entry_new1, *entry_new2; GtkWidget *confirm_area; GtkWidget *ok_button, *cancel_button; struct _ctx *ctx; dialog = gtk_dialog_new(); gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); gtk_window_set_default_size(GTK_WINDOW(dialog), 375, 100); gtk_window_set_title(GTK_WINDOW(dialog), ""); MANAGE_WINDOW_SIGNALS_CONNECT(dialog); vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 14); hbox = gtk_hbox_new(FALSE, 12); gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); gtk_widget_show(hbox); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0.0); gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0); vbox = gtk_vbox_new(FALSE, 12); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); gtk_widget_show(vbox); msg_title = gtk_label_new(_("Changing master passphrase")); gtk_misc_set_alignment(GTK_MISC(msg_title), 0, 0.5); gtk_label_set_justify(GTK_LABEL(msg_title), GTK_JUSTIFY_LEFT); gtk_label_set_use_markup (GTK_LABEL (msg_title), TRUE); gtk_box_pack_start(GTK_BOX(vbox), msg_title, FALSE, FALSE, 0); gtk_label_set_line_wrap(GTK_LABEL(msg_title), TRUE); if (!font_desc) { gint size; size = pango_font_description_get_size (gtk_widget_get_style(msg_title)->font_desc); font_desc = pango_font_description_new(); pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD); pango_font_description_set_size (font_desc, size * PANGO_SCALE_LARGE); } if (font_desc) gtk_widget_modify_font(msg_title, font_desc); label = gtk_label_new( _("If a master passphrase is currently active, it\n" "needs to be entered.") ); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); table = gtk_table_new(4, 2, FALSE); /* Old passphrase */ label = gtk_label_new(_("Old passphrase:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); entry_old = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(entry_old), FALSE); gtk_table_attach(GTK_TABLE(table), entry_old, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); /* Separator */ gtk_table_attach(GTK_TABLE(table), gtk_hseparator_new(), 0, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 5); /* New passphrase */ label = gtk_label_new(_("New passphrase:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0); entry_new1 = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(entry_new1), FALSE); gtk_table_attach(GTK_TABLE(table), entry_new1, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); /* New passphrase again */ label = gtk_label_new(_("Confirm passphrase:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, 0, 0, 0); entry_new2 = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(entry_new2), FALSE); gtk_table_attach(GTK_TABLE(table), entry_new2, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 0, 0); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); /* Dialog buttons */ gtkut_stock_button_set_create(&confirm_area, &cancel_button, GTK_STOCK_CANCEL, &ok_button, GTK_STOCK_OK, NULL, NULL); gtk_box_pack_end(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(dialog))), confirm_area, FALSE, FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(confirm_area), 5); gtk_widget_grab_default(ok_button); /* If no master passphrase is set, disable the "old passphrase" entry */ if (!master_passphrase_is_set()) gtk_widget_set_sensitive(entry_old, FALSE); g_signal_connect(G_OBJECT(entry_old), "activate", G_CALLBACK(entry_activated), entry_new1); g_signal_connect(G_OBJECT(entry_new1), "activate", G_CALLBACK(entry_activated), entry_new2); gtk_entry_set_activates_default(GTK_ENTRY(entry_new2), TRUE); ctx = g_new(struct _ctx, 1); ctx->done = FALSE; ctx->dialog = dialog; ctx->entry_old = entry_old; ctx->entry_new1 = entry_new1; ctx->entry_new2 = entry_new2; g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(ok_button_clicked), ctx); g_signal_connect(G_OBJECT(cancel_button), "clicked", G_CALLBACK(cancel_button_clicked), ctx); g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(dialog_destroy), ctx); gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG(dialog))); gtk_window_present(GTK_WINDOW(dialog)); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); manage_window_set_transient(GTK_WINDOW(dialog)); while (!ctx->done) gtk_main_iteration(); if (ctx->dialog != NULL) gtk_widget_destroy(ctx->dialog); GTK_EVENTS_FLUSH(); g_free(ctx); }
static void grouplist_dialog_set_list(const gchar *pattern, gboolean refresh) { static GdkCursor *watch_cursor = NULL; GSList *cur; GtkCMCTreeNode *node; GPatternSpec *pspec; GdkWindow *window; if (locked) return; locked = TRUE; if (!pattern || *pattern == '\0') pattern = "*"; if (!watch_cursor) watch_cursor = gdk_cursor_new(GDK_WATCH); window = gtk_widget_get_window(dialog); gdk_window_set_cursor(window, watch_cursor); main_window_cursor_wait(mainwindow_get_mainwindow()); GTK_EVENTS_FLUSH(); if (refresh) { ack = TRUE; grouplist_clear(); recv_set_ui_func(grouplist_recv_func, NULL); group_list = news_get_group_list(news_folder); group_list = g_slist_reverse(group_list); recv_set_ui_func(NULL, NULL); if (group_list == NULL && ack == TRUE) { alertpanel_error(_("Can't retrieve newsgroup list.")); locked = FALSE; gdk_window_set_cursor(window, NULL); main_window_cursor_normal(mainwindow_get_mainwindow()); return; } } else gtk_cmclist_clear(GTK_CMCLIST(ctree)); gtk_entry_set_text(GTK_ENTRY(entry), pattern); grouplist_hash_init(); gtk_cmclist_freeze(GTK_CMCLIST(ctree)); pspec = g_pattern_spec_new(pattern); for (cur = group_list; cur != NULL ; cur = cur->next) { NewsGroupInfo *ginfo = (NewsGroupInfo *)cur->data; if (g_pattern_match_string(pspec, ginfo->name)) { node = grouplist_create_branch(ginfo, pattern); if (g_slist_find_custom(subscribed, ginfo->name, (GCompareFunc)g_ascii_strcasecmp) != NULL) gtk_cmctree_select(GTK_CMCTREE(ctree), node); } } for (cur = subscribed; cur; cur = g_slist_next(cur)) grouplist_expand_upwards(GTK_CMCTREE(ctree), (gchar *)cur->data); g_pattern_spec_free(pspec); gtk_cmclist_thaw(GTK_CMCLIST(ctree)); grouplist_hash_done(); gtk_label_set_text(GTK_LABEL(status_label), _("Done.")); gdk_window_set_cursor(window, NULL); main_window_cursor_normal(mainwindow_get_mainwindow()); locked = FALSE; }
static void pgpview_show_mime_part(TextView *textview, MimeInfo *partinfo) { GtkTextView *text; GtkTextBuffer *buffer; GtkTextIter iter; gpgme_data_t sigdata = NULL; gpgme_verify_result_t sigstatus = NULL; gpgme_ctx_t ctx = NULL; gpgme_key_t key = NULL; gpgme_signature_t sig = NULL; gpgme_error_t err = 0; gboolean imported = FALSE; if (!partinfo) return; textview_set_font(textview, NULL); textview_clear(textview); text = GTK_TEXT_VIEW(textview->text); buffer = gtk_text_view_get_buffer(text); gtk_text_buffer_get_start_iter(buffer, &iter); err = gpgme_new (&ctx); if (err) { debug_print("err : %s\n", gpgme_strerror(err)); textview_show_mime_part(textview, partinfo); return; } sigdata = sgpgme_data_from_mimeinfo(partinfo); if (!sigdata) { g_warning("no sigdata"); textview_show_mime_part(textview, partinfo); return; } /* Here we do not care about what data we attempt to verify with the * signature, or about result of the verification - all we care about * is that we find out ID of the key used to make this signature. */ sigstatus = sgpgme_verify_signature(ctx, sigdata, NULL, sigdata); if (!sigstatus || sigstatus == GINT_TO_POINTER(-GPG_ERR_SYSTEM_ERROR)) { g_warning("no sigstatus"); textview_show_mime_part(textview, partinfo); return; } sig = sigstatus->signatures; if (!sig) { g_warning("no sig"); textview_show_mime_part(textview, partinfo); return; } gpgme_get_key(ctx, sig->fpr, &key, 0); if (!key) { gchar *gpgbin = get_gpg_executable_name(); gchar *cmd = g_strdup_printf("\"%s\" --batch --no-tty --recv-keys %s", (gpgbin ? gpgbin : "gpg"), sig->fpr); AlertValue val = G_ALERTDEFAULT; if (!prefs_common_get_prefs()->work_offline) { val = alertpanel(_("Key import"), _("This key is not in your keyring. Do you want " "Claws Mail to try and import it from a " "keyserver?"), GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND); GTK_EVENTS_FLUSH(); } if (val == G_ALERTDEFAULT) { TEXTVIEW_INSERT(_("\n Key ID ")); TEXTVIEW_INSERT(sig->fpr); TEXTVIEW_INSERT(":\n\n"); TEXTVIEW_INSERT(_(" This key is not in your keyring.\n")); TEXTVIEW_INSERT(_(" It should be possible to import it ")); if (prefs_common_get_prefs()->work_offline) TEXTVIEW_INSERT(_("when working online,\n or ")); TEXTVIEW_INSERT(_("with the following command: \n\n ")); TEXTVIEW_INSERT(cmd); } else { TEXTVIEW_INSERT(_("\n Importing key ID ")); TEXTVIEW_INSERT(sig->fpr); TEXTVIEW_INSERT(":\n\n"); main_window_cursor_wait(mainwindow_get_mainwindow()); textview_cursor_wait(textview); GTK_EVENTS_FLUSH(); #ifndef G_OS_WIN32 int res = 0; pid_t pid = 0; pid = fork(); if (pid == -1) { res = -1; } else if (pid == 0) { /* son */ gchar **argv; argv = strsplit_with_quote(cmd, " ", 0); res = execvp(argv[0], argv); perror("execvp"); exit(255); } else { int status = 0; time_t start_wait = time(NULL); res = -1; do { if (waitpid(pid, &status, WNOHANG) == 0 || !WIFEXITED(status)) { usleep(200000); } else { res = WEXITSTATUS(status); break; } if (time(NULL) - start_wait > 9) { debug_print("SIGTERM'ing gpg %d\n", pid); kill(pid, SIGTERM); } if (time(NULL) - start_wait > 10) { debug_print("SIGKILL'ing gpg %d\n", pid); kill(pid, SIGKILL); break; } } while(1); } debug_print("res %d\n", res); if (res == 0) imported = TRUE; #else /* We need to call gpg in a separate thread, so that waiting for * it to finish does not block the UI. */ pthread_t pt; struct _ImportCtx *ctx = malloc(sizeof(struct _ImportCtx)); ctx->done = FALSE; ctx->exitcode = STILL_ACTIVE; ctx->cmd = cmd; if (pthread_create(&pt, NULL, _import_threaded, (void *)ctx) != 0) { debug_print("Couldn't create thread, continuing unthreaded.\n"); _import_threaded(ctx); } else { debug_print("Thread created, waiting for it to finish...\n"); while (!ctx->done) claws_do_idle(); } debug_print("Thread finished.\n"); pthread_join(pt, NULL); if (ctx->exitcode == 0) { imported = TRUE; } g_free(ctx); #endif main_window_cursor_normal(mainwindow_get_mainwindow()); textview_cursor_normal(textview); if (imported) { TEXTVIEW_INSERT(_(" This key has been imported to your keyring.\n")); } else { TEXTVIEW_INSERT(_(" This key couldn't be imported to your keyring.\n")); TEXTVIEW_INSERT(_(" Key servers are sometimes slow.\n")); TEXTVIEW_INSERT(_(" You can try to import it manually with the command:\n\n ")); TEXTVIEW_INSERT(cmd); } } g_free(cmd); return; } else { TEXTVIEW_INSERT(_("\n Key ID ")); #if defined GPGME_VERSION_NUMBER && GPGME_VERSION_NUMBER >= 0x010700 TEXTVIEW_INSERT(key->fpr); #else TEXTVIEW_INSERT(sig->fpr); #endif TEXTVIEW_INSERT(":\n\n"); TEXTVIEW_INSERT(_(" This key is in your keyring.\n")); } gpgme_data_release(sigdata); gpgme_release(ctx); textview_show_icon(textview, GTK_STOCK_DIALOG_AUTHENTICATION); }