talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 39be80dde52ad1b5815fc14af5bec39068ee55d9
parent 22249a5bdbc5930c0a3069804ba9cdf35ec07dec
Author: Michael Rasmussen <mir@datanom.net>
Date:   Fri, 27 Oct 2017 16:45:01 +0200

Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws

Diffstat:
Msrc/common/utils.c | 2+-
Msrc/etpan/nntp-thread.c | 128++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/folder.c | 4++--
Msrc/imap.c | 6+++---
Msrc/inc.c | 6+++---
Msrc/mbox.c | 4++--
Msrc/messageview.c | 4++--
Msrc/news.c | 12+++++++++++-
Msrc/password.c | 4++--
Msrc/password.h | 4++--
Msrc/plugins/fancy/fancy_prefs.c | 8++++++++
Msrc/plugins/fancy/fancy_viewer.c | 22+++++++++++++++++++++-
Msrc/prefs_account.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/prefs_folder_item.c | 5+++--
Msrc/send_message.c | 6+++---
Msrc/statusbar.h | 3---
16 files changed, 226 insertions(+), 51 deletions(-)

diff --git a/src/common/utils.c b/src/common/utils.c @@ -4121,7 +4121,7 @@ gboolean get_uri_part(const gchar *start, const gchar *scanpos, * should pass some URI type to this function and decide on that whether * to perform punctuation stripping */ -#define IS_REAL_PUNCT(ch) (g_ascii_ispunct(ch) && !strchr("/?=-_)", ch)) +#define IS_REAL_PUNCT(ch) (g_ascii_ispunct(ch) && !strchr("/?=-_~)", ch)) for (; ep_ - 1 > scanpos + 1 && IS_REAL_PUNCT(*(ep_ - 1)); diff --git a/src/etpan/nntp-thread.c b/src/etpan/nntp-thread.c @@ -51,6 +51,8 @@ #define DISABLE_LOG_DURING_LOGIN +#define NNTP_BATCH_SIZE 4999 + static struct etpan_thread_manager * thread_manager = NULL; static chash * nntp_hash = NULL; static chash * session_hash = NULL; @@ -822,26 +824,64 @@ static void xover_run(struct etpan_thread_op * op) } result->error = r; - debug_print("nntp xover run - end %i\n", r); + debug_print("nntp xover run %d-%d - end %i\n", + param->beg, param->end, r); } int nntp_threaded_xover(Folder * folder, guint32 beg, guint32 end, struct newsnntp_xover_resp_item **single_result, clist **multiple_result) { struct xover_param param; struct xover_result result; - - debug_print("nntp xover - begin\n"); - - param.nntp = get_nntp(folder); - param.beg = beg; - param.end = end; - param.result = single_result; - param.msglist = multiple_result; - - threaded_run(folder, &param, &result, xover_run); + clist *l = NULL, *h = NULL; + guint32 cbeg = 0, cend = 0; + + debug_print("nntp xover - begin (%d-%d)\n", beg, end); + + h = clist_new(); + + /* Request the overview in batches of NNTP_BATCH_SIZE, to prevent + * long stalls or libetpan choking on too large server response, + * and to allow updating any progress indicators while we work. */ + cbeg = beg; + while (cbeg <= end && cend <= end) { + cend = cbeg + NNTP_BATCH_SIZE; + if (cend > end) + cend = end; + + param.nntp = get_nntp(folder); + param.beg = cbeg; + param.end = cend; + param.result = single_result; + param.msglist = &l; + + threaded_run(folder, &param, &result, xover_run); + + /* Handle errors */ + if (result.error != NEWSNNTP_NO_ERROR) { + log_warning(LOG_PROTOCOL, _("couldn't get xover range\n")); + debug_print("couldn't get xover for %d-%d\n", cbeg, cend); + if (l != NULL) + newsnntp_xover_resp_list_free(l); + newsnntp_xover_resp_list_free(h); + return result.error; + } + + /* Append the new data (l) to list of results (h). */ + if (l != NULL) { + debug_print("total items so far %d, items this batch %d\n", + clist_count(h), clist_count(l)); + clist_concat(h, l); + clist_free(l); + l = NULL; + } + + cbeg += NNTP_BATCH_SIZE + 1; + } debug_print("nntp xover - end\n"); - + + *multiple_result = h; + return result.error; } @@ -875,26 +915,66 @@ static void xhdr_run(struct etpan_thread_op * op) } result->error = r; - debug_print("nntp xhdr run - end %i\n", r); + debug_print("nntp xhdr '%s %d-%d' run - end %i\n", + param->header, param->beg, param->end, r); } int nntp_threaded_xhdr(Folder * folder, const char *header, guint32 beg, guint32 end, clist **hdrlist) { struct xhdr_param param; struct xhdr_result result; + clist *l = NULL; + clist *h = *hdrlist; + guint32 cbeg = 0, cend = 0; + + debug_print("nntp xhdr %s - begin (%d-%d)\n", header, beg, end); + + if (h == NULL) + h = clist_new(); + + /* Request the headers in batches of NNTP_BATCH_SIZE, to prevent + * long stalls or libetpan choking on too large server response, + * and to allow updating any progress indicators while we work. */ + cbeg = beg; + while (cbeg <= end && cend <= end) { + cend = cbeg + NNTP_BATCH_SIZE; + if (cend > end) + cend = end; + + param.nntp = get_nntp(folder); + param.header = header; + param.beg = cbeg; + param.end = cend; + param.hdrlist = &l; + + threaded_run(folder, &param, &result, xhdr_run); + + /* Handle errors */ + if (result.error != NEWSNNTP_NO_ERROR) { + log_warning(LOG_PROTOCOL, _("couldn't get xhdr range\n")); + debug_print("couldn't get xhdr %s %d-%d\n", header, cbeg, cend); + if (l != NULL) + newsnntp_xhdr_free(l); + newsnntp_xhdr_free(h); + return result.error; + } + + /* Append the new data (l) to list of results (h). */ + if (l != NULL) { + debug_print("total items so far %d, items this batch %d\n", + clist_count(h), clist_count(l)); + clist_concat(h, l); + clist_free(l); + l = NULL; + } + + cbeg += NNTP_BATCH_SIZE + 1; + } - debug_print("nntp xhdr - begin\n"); - - param.nntp = get_nntp(folder); - param.header = header; - param.beg = beg; - param.end = end; - param.hdrlist = hdrlist; + debug_print("nntp xhdr %s - end (%d-%d)\n", header, beg, end); + + *hdrlist = h; - threaded_run(folder, &param, &result, xhdr_run); - - debug_print("nntp xhdr - end\n"); - return result.error; } diff --git a/src/folder.c b/src/folder.c @@ -4566,13 +4566,13 @@ void folder_item_synchronise(FolderItem *item) if (!item) return; if (item->prefs->offlinesync && item->folder->klass->synchronise) { - statuswindow_print_all(_("Synchronising %s for offline use...\n"), item->path ? item->path : "(null)"); + statusbar_print_all(_("Synchronising %s for offline use...\n"), item->path ? item->path : "(null)"); item->folder->klass->synchronise(item, item->prefs->offlinesync_days); if (item->prefs->offlinesync_days > 0 && item->prefs->remove_old_bodies) folder_item_clean_local_files(item, item->prefs->offlinesync_days); - statuswindow_pop_all(); + statusbar_pop_all(); } } diff --git a/src/imap.c b/src/imap.c @@ -1165,7 +1165,7 @@ static IMAPSession *imap_session_new(Folder * folder, buf = g_strdup_printf(_("Account '%s': Connecting to IMAP server: %s:%d..."), folder->account->account_name, folder->account->recv_server, port); - statuswindow_print_all("%s", buf); + statusbar_print_all("%s", buf); log_message(LOG_PROTOCOL, "%s\n", buf); g_free(buf); @@ -1194,7 +1194,7 @@ static IMAPSession *imap_session_new(Folder * folder, } } - statuswindow_pop_all(); + statusbar_pop_all(); if (r == MAILIMAP_NO_ERROR_AUTHENTICATED) { authenticated = TRUE; } @@ -1332,7 +1332,7 @@ try_again: memset(acc_pass, 0, strlen(acc_pass)); g_free(acc_pass); } - statuswindow_pop_all(); + statusbar_pop_all(); session->authenticated = TRUE; return MAILIMAP_NO_ERROR; } diff --git a/src/inc.c b/src/inc.c @@ -824,7 +824,7 @@ static IncState inc_pop3_session_do(IncSession *session) buf = g_strdup_printf(_("Account '%s': Connecting to POP3 server: %s:%d..."), account_name, server, port); - statuswindow_print_all("%s", buf); + statusbar_print_all("%s", buf); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(inc_dialog->dialog, buf); @@ -848,7 +848,7 @@ static IncState inc_pop3_session_do(IncSession *session) server, port); } session->inc_state = INC_CONNECT_ERROR; - statuswindow_pop_all(); + statusbar_pop_all(); return INC_CONNECT_ERROR; } @@ -925,7 +925,7 @@ static void inc_progress_dialog_set_label(IncProgressDialog *inc_dialog, case POP3_GETAUTH_PASS: case POP3_GETAUTH_APOP: progress_dialog_set_label(dialog, _("Authenticating...")); - statuswindow_pop_all(); + statusbar_pop_all(); statusbar_print_all(_("Retrieving messages from %s (%s)..."), SESSION(session)->server, session->ac_prefs->account_name); diff --git a/src/mbox.c b/src/mbox.c @@ -565,7 +565,7 @@ gint export_list_to_mbox(GSList *mlist, const gchar *mbox) flockfile(mbox_fp); #endif - statuswindow_print_all(_("Exporting to mbox...")); + statusbar_print_all(_("Exporting to mbox...")); for (cur = mlist; cur != NULL; cur = cur->next) { int len; gchar buft[BUFFSIZE]; @@ -665,7 +665,7 @@ gint export_list_to_mbox(GSList *mlist, const gchar *mbox) out: statusbar_progress_all(0,0,0); - statuswindow_pop_all(); + statusbar_pop_all(); #ifdef HAVE_FGETS_UNLOCKED funlockfile(mbox_fp); diff --git a/src/messageview.c b/src/messageview.c @@ -1382,13 +1382,13 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo, messageview->updating = TRUE; if (msginfo->size > 1024*1024) - statuswindow_print_all(_("Fetching message (%s)..."), + statusbar_print_all(_("Fetching message (%s)..."), to_human_readable(msginfo->size)); file = procmsg_get_message_file_path(msginfo); if (msginfo->size > 1024*1024) - statuswindow_pop_all(); + statusbar_pop_all(); if (!file) { g_warning("can't get message file path."); diff --git a/src/news.c b/src/news.c @@ -1136,6 +1136,8 @@ static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); + if (hdrlist != NULL) + newsnntp_xhdr_free(hdrlist); return; } @@ -1149,6 +1151,7 @@ static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList } } newsnntp_xhdr_free(hdrlist); + hdrlist = NULL; /* To */ ok = nntp_threaded_xhdr(item->folder, "to", first, last, &hdrlist); @@ -1160,6 +1163,8 @@ static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); + if (hdrlist != NULL) + newsnntp_xhdr_free(hdrlist); return; } @@ -1173,6 +1178,7 @@ static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList } } newsnntp_xhdr_free(hdrlist); + hdrlist = NULL; /* Cc */ ok = nntp_threaded_xhdr(item->folder, "cc", first, last, &hdrlist); @@ -1184,6 +1190,8 @@ static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); + if (hdrlist != NULL) + newsnntp_xhdr_free(hdrlist); return; } @@ -1197,7 +1205,7 @@ static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList } } newsnntp_xhdr_free(hdrlist); - + hdrlist = NULL; g_hash_table_destroy(hash_table); news_folder_unlock(NEWS_FOLDER(item->folder)); @@ -1235,6 +1243,8 @@ static GSList *news_get_msginfos_for_range(NewsSession *session, FolderItem *ite REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); + if (msglist != NULL) + newsnntp_xover_resp_list_free(msglist); return NULL; } diff --git a/src/password.c b/src/password.c @@ -145,7 +145,7 @@ static const gchar *master_passphrase() return _master_passphrase; } -const gboolean master_passphrase_is_set() +gboolean master_passphrase_is_set() { if (prefs_common_get_prefs()->master_passphrase == NULL || strlen(prefs_common_get_prefs()->master_passphrase) == 0) @@ -154,7 +154,7 @@ const gboolean master_passphrase_is_set() return TRUE; } -const gboolean master_passphrase_is_correct(const gchar *input) +gboolean master_passphrase_is_correct(const gchar *input) { guchar *kd, *input_kd; gchar **tokens; diff --git a/src/password.h b/src/password.h @@ -28,10 +28,10 @@ #ifndef PASSWORD_CRYPTO_OLD /* Returns TRUE if there is a master passphrase set in preferences. */ -const gboolean master_passphrase_is_set(); +gboolean master_passphrase_is_set(); /* Returns TRUE if input contains correct master passphrase, as set * in preferences. */ -const gboolean master_passphrase_is_correct(const gchar *input); +gboolean master_passphrase_is_correct(const gchar *input); /* Returns TRUE if master passphrase is entered (unlocked). */ gboolean master_passphrase_is_entered(); /* Removes (locks) master passphrase, if it was entered previously diff --git a/src/plugins/fancy/fancy_prefs.c b/src/plugins/fancy/fancy_prefs.c @@ -442,7 +442,15 @@ static void save_fancy_prefs_page(PrefsPage *page) fancy_prefs.enable_proxy = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(prefs_page->proxy_checkbox)); fancy_prefs.proxy_str = pref_get_pref_from_entry(GTK_ENTRY(prefs_page->proxy_str)); +#ifdef G_OS_WIN32 + /* pref_get_pref_from_entry() escapes the backslashes in strings, + * we do not want that, since this entry contains a Windows path. + * Let's just strdup it. */ + fancy_prefs.stylesheet = g_strdup(gtk_entry_get_text( + GTK_ENTRY(prefs_page->stylesheet))); +#else fancy_prefs.stylesheet = pref_get_pref_from_entry(GTK_ENTRY(prefs_page->stylesheet)); +#endif save_fancy_prefs(page); } diff --git a/src/plugins/fancy/fancy_viewer.c b/src/plugins/fancy/fancy_viewer.c @@ -147,7 +147,27 @@ static void fancy_set_defaults(FancyViewer *viewer) viewer->override_prefs_scripts = fancy_prefs.enable_scripts; viewer->override_prefs_plugins = fancy_prefs.enable_plugins; viewer->override_prefs_java = fancy_prefs.enable_java; - viewer->override_stylesheet = g_strconcat("file://", fancy_prefs.stylesheet, NULL); + + gchar *tmp; +#ifdef G_OS_WIN32 + /* Replace backslashes with forward slashes, since we'll be + * using this string in an URI. */ + gchar *tmp2 = g_strdup(fancy_prefs.stylesheet); + subst_char(tmp2, '\\', '/'); + + /* Escape string for use in an URI, keeping dir separators + * and colon for Windows drive name ("C:") intact. */ + tmp = g_uri_escape_string(tmp2, "/:", TRUE); + g_free(tmp2); +#else + /* Escape string for use in an URI, keeping dir separators + * intact. */ + tmp = g_uri_escape_string(fancy_prefs.stylesheet, "/", TRUE); +#endif + viewer->override_stylesheet = g_strconcat("file://", tmp, NULL); + g_free(tmp); + debug_print("Passing '%s' as stylesheet URI to Webkit\n", + viewer->override_stylesheet); g_signal_handlers_block_by_func(G_OBJECT(viewer->enable_images), fancy_auto_load_images_activated, viewer); diff --git a/src/prefs_account.c b/src/prefs_account.c @@ -369,6 +369,8 @@ static void prefs_account_mailcmd_toggled(GtkToggleButton *button, gpointer user_data); static void prefs_account_showpwd_checkbtn_toggled(GtkToggleButton *button, gpointer user_data); +static void prefs_account_entry_changed_newline_check_cb(GtkWidget *entry, + gpointer user_data); static void prefs_account_filter_on_recv_toggled(GtkToggleButton *button, gpointer user_data); @@ -1220,9 +1222,17 @@ static void basic_create_widget_func(PrefsPage * _page, uid_entry = gtk_entry_new (); gtk_widget_show (uid_entry); gtk_widget_set_size_request (uid_entry, DEFAULT_ENTRY_WIDTH, -1); + g_signal_connect(G_OBJECT(uid_entry), "changed", + G_CALLBACK(prefs_account_entry_changed_newline_check_cb), + GINT_TO_POINTER(ac_prefs->protocol)); + pass_entry = gtk_entry_new (); gtk_widget_show (pass_entry); gtk_widget_set_size_request (pass_entry, DEFAULT_ENTRY_WIDTH, -1); + g_signal_connect(G_OBJECT(pass_entry), "changed", + G_CALLBACK(prefs_account_entry_changed_newline_check_cb), + GINT_TO_POINTER(ac_prefs->protocol)); + #ifndef GENERIC_UMPC gtk_table_attach (GTK_TABLE (serv_table), uid_entry, 1, 2, 7, 8, GTK_EXPAND | GTK_SHRINK | GTK_FILL, @@ -2949,6 +2959,7 @@ static gint prefs_basic_apply(void) alertpanel_error(_("Mail address is not entered.")); return -1; } + if (((protocol == A_POP3) || (protocol == A_LOCAL && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(basic_page.mailcmd_checkbtn))) || (protocol == A_NONE)) && @@ -3015,6 +3026,18 @@ static gint prefs_basic_apply(void) protocol == A_IMAP4 ? "imap":"news", tmp_ac_prefs.account_name ? tmp_ac_prefs.account_name : "(null)"); + if (protocol == A_POP3 && + strchr(gtk_entry_get_text(GTK_ENTRY(basic_page.uid_entry)), '\n') != NULL) { + alertpanel_error(_("User ID can not contain newline character.")); + return -1; + } + + if (protocol == A_POP3 && + strchr(gtk_entry_get_text(GTK_ENTRY(basic_page.pass_entry)), '\n') != NULL) { + alertpanel_error(_("Password can not contain newline character.")); + return -1; + } + prefs_set_data_from_dialog(basic_param); /* Passwords are stored outside of PrefParams. */ @@ -4932,6 +4955,42 @@ static void prefs_account_showpwd_checkbtn_toggled(GtkToggleButton *button, gtk_entry_set_visibility(GTK_ENTRY(entry), active); } +static void prefs_account_entry_changed_newline_check_cb(GtkWidget *entry, + gpointer user_data) +{ + RecvProtocol protocol = GPOINTER_TO_INT(user_data); +#if !GTK_CHECK_VERSION(3, 0, 0) + static GdkColor red; + static gboolean colors_initialised = FALSE; +#else + static GdkColor red = { (guint32)0, (guint16)0xff, (guint16)0x70, (guint16)0x70 }; +#endif + +#if !GTK_CHECK_VERSION(3, 0, 0) + if (protocol != A_POP3) + return; + + if (strchr(gtk_entry_get_text(GTK_ENTRY(entry)), '\n') != NULL) { + /* Entry contains a newline, light it up. */ + debug_print("found newline in string, painting entry red\n"); + if (!colors_initialised) { + if (!gdk_color_parse("#ff7070", &red)) { + g_warning("color parse failed: red"); + return; + } + colors_initialised = gdk_colormap_alloc_color( + gdk_colormap_get_system(), &red, FALSE, TRUE); + } + + if (colors_initialised) { + gtk_widget_modify_base(entry, GTK_STATE_NORMAL, &red); + } + } else { + gtk_widget_modify_base(entry, GTK_STATE_NORMAL, NULL); + } +#endif +} + static void prefs_account_filter_on_recv_toggled(GtkToggleButton *button, gpointer user_data) { diff --git a/src/prefs_folder_item.c b/src/prefs_folder_item.c @@ -1764,9 +1764,10 @@ static void folder_regexp_test_cb(GtkWidget *widget, gpointer data) if (!colors_initialised) { if (!gdk_color_parse("#ff7070", &red)) { g_warning("color parse failed: red"); - colors_initialised = gdk_colormap_alloc_color( - gdk_colormap_get_system(), &red, FALSE, TRUE); + return; } + colors_initialised = gdk_colormap_alloc_color( + gdk_colormap_get_system(), &red, FALSE, TRUE); } #endif diff --git a/src/send_message.c b/src/send_message.c @@ -460,7 +460,7 @@ gint send_message_smtp_full(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp, g ac_prefs->session = SMTP_SESSION(session); - statuswindow_pop_all(); + statusbar_pop_all(); statusbar_verbosity_set(FALSE); return ret; } @@ -485,12 +485,12 @@ static gint send_recv_message(Session *session, const gchar *msg, gpointer data) case SMTP_HELO: g_snprintf(buf, sizeof(buf), _("Sending HELO...")); state_str = _("Authenticating"); - statuswindow_print_all(_("Sending message...")); + statusbar_print_all(_("Sending message...")); break; case SMTP_EHLO: g_snprintf(buf, sizeof(buf), _("Sending EHLO...")); state_str = _("Authenticating"); - statuswindow_print_all(_("Sending message...")); + statusbar_print_all(_("Sending message...")); break; case SMTP_AUTH: g_snprintf(buf, sizeof(buf), _("Authenticating...")); diff --git a/src/statusbar.h b/src/statusbar.h @@ -34,9 +34,6 @@ void statusbar_print_all (const gchar *format, ...) G_GNUC_PRINTF(1, 2); void statusbar_pop_all (void); -#define statuswindow_print_all statusbar_print_all -#define statuswindow_pop_all statusbar_pop_all - void statusbar_verbosity_set (gboolean verbose); void statusbar_progress_all (gint done, gint total, gint step);