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:
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, ¶m, &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, ¶m, &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, ¶m, &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, ¶m, &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);