From 0823289fd9c6a2eec7ff04581426856d1dbb15e5 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 21 Sep 2015 22:53:53 -0300 Subject: [PATCH 01/26] Limit recursion depth of key/combo expansion in key_states_scan() Fixes FS#817 - "SegFault when executing bind command", which provides the test case "/bind cleft key meta", which is stupid but now it doesn't break things. The limit of 100 is arbitrary, it means roughly 140 stack frames total. The flyspray ticket mentions it crashes at 512, in my system it goes all the way to 149677 stack frames. http://bugs.irssi.org/index.php?do=details&task_id=817 --- src/fe-common/core/keyboard.c | 37 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index f138d4e2..fed7f9cb 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -31,6 +31,8 @@ #include "fe-windows.h" #include "printtext.h" +#define MAX_EXPAND_RECURSION 100 + GSList *keyinfos; static GHashTable *keys, *default_keys; @@ -171,7 +173,7 @@ KEYINFO_REC *key_info_find(const char *id) return NULL; } -static int expand_key(const char *key, GSList **out); +static int expand_key(const char *key, GSList **out, int *limit); #define expand_out_char(out, c) \ { \ @@ -188,13 +190,17 @@ static int expand_key(const char *key, GSList **out); g_slist_free(out); out = NULL; \ } -static int expand_combo(const char *start, const char *end, GSList **out) +static int expand_combo(const char *start, const char *end, GSList **out, int *limit) { KEY_REC *rec; KEYINFO_REC *info; GSList *tmp, *tmp2, *list, *copy, *newout; char *str, *p; + if ((*limit)-- < 0) { + return FALSE; + } + if (start == end) { /* single key */ expand_out_char(*out, *start); @@ -229,7 +235,7 @@ static int expand_combo(const char *start, const char *end, GSList **out) /* only one way to generate the combo, good */ rec = list->data; g_slist_free(list); - return expand_key(rec->key, out); + return expand_key(rec->key, out, limit); } /* multiple ways to generate the combo - @@ -244,7 +250,11 @@ static int expand_combo(const char *start, const char *end, GSList **out) copy = g_slist_append(copy, g_string_new(str->str)); } - if (!expand_key(rec->key, ©)) { + if (!expand_key(rec->key, ©, limit)) { + if (*limit < 0) { + return FALSE; + } + /* illegal key combo, remove from list */ expand_out_free(copy); } else { @@ -254,7 +264,11 @@ static int expand_combo(const char *start, const char *end, GSList **out) rec = list->data; g_slist_free(list); - if (!expand_key(rec->key, out)) { + if (!expand_key(rec->key, out, limit)) { + if (*limit < 0) { + return FALSE; + } + /* illegal key combo, remove from list */ expand_out_free(*out); } @@ -264,12 +278,16 @@ static int expand_combo(const char *start, const char *end, GSList **out) } /* Expand key code - returns TRUE if successful. */ -static int expand_key(const char *key, GSList **out) +static int expand_key(const char *key, GSList **out, int *limit) { GSList *tmp; const char *start; int last_hyphen; + if ((*limit)-- < 0) { + return FALSE; + } + /* meta-^W^Gf -> ^[-^W-^G-f */ start = NULL; last_hyphen = TRUE; for (; *key != '\0'; key++) { @@ -279,7 +297,7 @@ static int expand_key(const char *key, GSList **out) continue; } - if (!expand_combo(start, key-1, out)) + if (!expand_combo(start, key-1, out, limit)) return FALSE; expand_out_char(*out, '-'); start = NULL; @@ -332,7 +350,7 @@ static int expand_key(const char *key, GSList **out) } if (start != NULL) - return expand_combo(start, key-1, out); + return expand_combo(start, key-1, out, limit); for (tmp = *out; tmp != NULL; tmp = tmp->next) { GString *str = tmp->data; @@ -346,12 +364,13 @@ static int expand_key(const char *key, GSList **out) static void key_states_scan_key(const char *key, KEY_REC *rec) { GSList *tmp, *out; + int limit = MAX_EXPAND_RECURSION; if (g_strcmp0(rec->info->id, "key") == 0) return; out = g_slist_append(NULL, g_string_new(NULL)); - if (expand_key(key, &out)) { + if (expand_key(key, &out, &limit)) { for (tmp = out; tmp != NULL; tmp = tmp->next) { GString *str = tmp->data; From 0f066aac11e9a56f394330a8d7dab3428594a623 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 28 Sep 2015 08:54:19 +0530 Subject: [PATCH 02/26] Remove Typo from FAQs --- docs/startup-HOWTO.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 30caf657..deff3116 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -391,7 +391,7 @@ messages window.

the connection into some window. IRSSI DOES NOT. There is no required relationship between window and server. You can connect to 10 servers and manage them all in just one window, or join channel in each one of -them to one sigle window if you really want to. That being said, here's +them to one single window if you really want to. That being said, here's how you do connect to new server without closing the old connection:


From cff536ab7091e79747352ff1f1d1d832870b2fb4 Mon Sep 17 00:00:00 2001
From: Jari Matilainen 
Date: Tue, 29 Sep 2015 10:39:49 +0200
Subject: [PATCH 03/26] Add sasl info to /network list output if available

---
 src/fe-common/irc/fe-ircnet.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c
index dab6f57f..c341081a 100644
--- a/src/fe-common/irc/fe-ircnet.c
+++ b/src/fe-common/irc/fe-ircnet.c
@@ -56,6 +56,11 @@ static void cmd_network_list(void)
 			g_string_append_printf(str, "autosendcmd: %s, ", rec->autosendcmd);
 		if (rec->usermode != NULL)
 			g_string_append_printf(str, "usermode: %s, ", rec->usermode);
+		if (rec->sasl_username != NULL) {
+			g_string_append_printf(str, "sasl_mechanism: %s, ", rec->sasl_mechanism);
+			g_string_append_printf(str, "sasl_username: %s, ", rec->sasl_username);
+			g_string_append_printf(str, "sasl_password: (pass), ");
+		}
 
 		if (rec->cmd_queue_speed > 0)
 			g_string_append_printf(str, "cmdspeed: %d, ", rec->cmd_queue_speed);

From b04b5f0f1d03be6282f7ba835b8a4f29b18b9c69 Mon Sep 17 00:00:00 2001
From: Jari Matilainen 
Date: Tue, 29 Sep 2015 11:44:11 +0200
Subject: [PATCH 04/26] Make sure sasl settings are defined before printing
 them out

---
 src/fe-common/irc/fe-ircnet.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c
index c341081a..bb0af313 100644
--- a/src/fe-common/irc/fe-ircnet.c
+++ b/src/fe-common/irc/fe-ircnet.c
@@ -56,12 +56,12 @@ static void cmd_network_list(void)
 			g_string_append_printf(str, "autosendcmd: %s, ", rec->autosendcmd);
 		if (rec->usermode != NULL)
 			g_string_append_printf(str, "usermode: %s, ", rec->usermode);
-		if (rec->sasl_username != NULL) {
+		if (rec->sasl_mechanism != NULL)
 			g_string_append_printf(str, "sasl_mechanism: %s, ", rec->sasl_mechanism);
+		if (rec->sasl_username != NULL)
 			g_string_append_printf(str, "sasl_username: %s, ", rec->sasl_username);
+		if (rec->sasl_password != NULL)
 			g_string_append_printf(str, "sasl_password: (pass), ");
-		}
-
 		if (rec->cmd_queue_speed > 0)
 			g_string_append_printf(str, "cmdspeed: %d, ", rec->cmd_queue_speed);
 		if (rec->max_cmds_at_once > 0)

From 00176dbff5af1a649a1f45972c45d661912aa8be Mon Sep 17 00:00:00 2001
From: Jellyfrog 
Date: Tue, 29 Sep 2015 17:34:35 +0200
Subject: [PATCH 05/26] Switch to modern Travis CI infrastructure

Fixes #310
---
 .travis.yml | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 35226645..aa807a7b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,4 @@
+sudo: false
 language: perl
 perl:
     - "5.20-shrplib"
@@ -7,19 +8,22 @@ env:
     - CC=clang
     - CC=gcc
 
+addons:
+    apt:
+        packages:
+            - libperl-dev
+            - elinks
+
 before_install:
-    - sudo apt-get update -qq
     - perl -V
-    - sudo apt-get build-dep -qq irssi
-    - sudo apt-get install -qq lynx
 
 install: true
 
 script:
-    - ./autogen.sh --with-proxy --with-bot --with-perl=module
+    - ./autogen.sh --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build --enable-silent-rules
     - cat config.log
     - make
-    - sudo make install
+    - make install
 
 notifications:
     irc:

From a475d57183bcbfd6e540dba5cd7894d8c38b53b7 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Thu, 1 Oct 2015 22:25:40 +0200
Subject: [PATCH 06/26] Save the sasl state in the session

This is seemingly required to have irssi re-authenticate after a
restart.
---
 src/irc/core/irc-session.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c
index ea65d8a5..18e8e5c7 100644
--- a/src/irc/core/irc-session.c
+++ b/src/irc/core/irc-session.c
@@ -28,6 +28,8 @@
 #include "irc-channels.h"
 #include "irc-nicklist.h"
 
+#include "sasl.h"
+
 struct _isupport_data { CONFIG_REC *config; CONFIG_NODE *node; };
 
 static void session_isupport_foreach(char *key, char *value, struct _isupport_data *data)
@@ -65,6 +67,10 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config,
 	config_node_set_str(config, node, "away_reason", server->away_reason);
 	config_node_set_bool(config, node, "emode_known", server->emode_known);
 
+	config_node_set_int(config, node, "sasl_mechanism", server->connrec->sasl_mechanism);
+	config_node_set_str(config, node, "sasl_username", server->connrec->sasl_username);
+	config_node_set_str(config, node, "sasl_password", server->connrec->sasl_password);
+
 	config_node_set_bool(config, node, "isupport_sent", server->isupport_sent);
 	isupport = config_node_section(config, node, "isupport", NODE_TYPE_BLOCK);
         isupport_data.config = config;
@@ -90,6 +96,15 @@ static void sig_session_restore_server(IRC_SERVER_REC *server,
 	server->emode_known = config_node_get_bool(node, "emode_known", FALSE);
 	server->isupport_sent = config_node_get_bool(node, "isupport_sent", FALSE);
 
+	server->connrec->sasl_mechanism = config_node_get_int(node, "sasl_mechanism", SASL_MECHANISM_NONE);
+	/* The fields below might have been filled when loading the chatnet
+	 * description from the config and we favor the content that's been saved
+	 * in the session file over that. */
+	g_free(server->connrec->sasl_username);
+	server->connrec->sasl_username = g_strdup(config_node_get_str(node, "sasl_username", NULL));
+	g_free(server->connrec->sasl_password);
+	server->connrec->sasl_password = g_strdup(config_node_get_str(node, "sasl_password", NULL));
+
 	if (server->isupport == NULL) {
 		server->isupport = g_hash_table_new((GHashFunc) g_istr_hash,
 						    (GCompareFunc) g_istr_equal);

From cfff402fe677316d286ce6663b8afeee4be95526 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 11:25:30 +0200
Subject: [PATCH 07/26] Don't set the usermode field if blank

Fixes FS#919
---
 src/irc/core/irc-chatnets.c      |  5 ++++-
 src/irc/core/irc-servers-setup.c | 12 +++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/irc/core/irc-chatnets.c b/src/irc/core/irc-chatnets.c
index d72f71dd..0796e0cb 100644
--- a/src/irc/core/irc-chatnets.c
+++ b/src/irc/core/irc-chatnets.c
@@ -35,10 +35,13 @@ void ircnet_create(IRC_CHATNET_REC *rec)
 
 static void sig_chatnet_read(IRC_CHATNET_REC *rec, CONFIG_NODE *node)
 {
+	char *value;
+
 	if (!IS_IRC_CHATNET(rec))
 		return;
 
-	rec->usermode = g_strdup(config_node_get_str(node, "usermode", NULL));
+	value = config_node_get_str(node, "usermode", NULL);
+	rec->usermode = (value != NULL && *value != '\0') ? g_strdup(value) : NULL;
 
 	rec->max_cmds_at_once = config_node_get_int(node, "cmdmax", 0);
 	rec->cmd_queue_speed = config_node_get_int(node, "cmdspeed", 0);
diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c
index bf1d2ddf..f425b587 100644
--- a/src/irc/core/irc-servers-setup.c
+++ b/src/irc/core/irc-servers-setup.c
@@ -48,12 +48,18 @@ static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn,
 
 static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn)
 {
+	const char *value;
+
 	if (!IS_IRC_SERVER_CONNECT(conn))
 		return;
 
-	conn->alternate_nick = *settings_get_str("alternate_nick") != '\0' ?
-		g_strdup(settings_get_str("alternate_nick")) : NULL;
-        conn->usermode = g_strdup(settings_get_str("usermode"));
+	value = settings_get_str("alternate_nick");
+	conn->alternate_nick = (value != NULL && *value != '\0') ?
+		g_strdup(value) : NULL;
+
+	value = settings_get_str("usermode");
+	conn->usermode = (value != NULL && *value != '\0') ?
+		g_strdup(value) : NULL;
 }
 
 static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn,

From b545bc96a9e1a875beb50d9202161864ca8164d8 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 12:39:08 +0200
Subject: [PATCH 08/26] Fix a memory leak.

g_get_current_dir() returns a heap-allocated string.
---
 src/core/core.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/core/core.c b/src/core/core.c
index b9debbb5..879d346f 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -156,11 +156,17 @@ static void sig_init_finished(void)
 static char *fix_path(const char *str)
 {
 	char *new_str = convert_home(str);
+
 	if (!g_path_is_absolute(new_str)) {
 		char *tmp_str = new_str;
-		new_str = g_strdup_printf("%s/%s", g_get_current_dir(), tmp_str);
+		char *current_dir = g_get_current_dir();
+
+		new_str = g_build_path(G_DIR_SEPARATOR_S, current_dir, tmp_str);
+
+		g_free(current_dir);
 		g_free(tmp_str);
 	}
+
 	return new_str;
 }
 

From 2e860abd2b8b3a30f74005450830c34a318b64a3 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 14:04:04 +0200
Subject: [PATCH 09/26] Fix the display of utf8 sequences in the gui

term_addstr() had a long-standing fixme that suggested it didn't
take into account the string encoding when calculating the string
length.
The BIG5 code path is untested.
---
 src/fe-common/core/utf8.h   |  2 ++
 src/fe-text/gui-printtext.c |  7 +++--
 src/fe-text/term-terminfo.c | 53 ++++++++++++++++++++++++++++++++++---
 src/fe-text/term.h          |  2 +-
 4 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/src/fe-common/core/utf8.h b/src/fe-common/core/utf8.h
index 3c15dc7d..70b44d7e 100644
--- a/src/fe-common/core/utf8.h
+++ b/src/fe-common/core/utf8.h
@@ -8,6 +8,8 @@
 #define is_big5_hi(hi)  (0x81 <= (hi) && (hi) <= 0xFE)
 #define is_big5(hi,lo) (is_big5_hi(hi) && is_big5_lo(lo))
 
+int strlen_big5(const unsigned char *str);
+
 /* Returns width for character (0-2). */
 int mk_wcwidth(unichar c);
 
diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c
index 547d39c9..d8272df5 100644
--- a/src/fe-text/gui-printtext.c
+++ b/src/fe-text/gui-printtext.c
@@ -220,16 +220,15 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
 	get_colors(flags, &fg, &bg, &attr);
 
 	if (window == NULL) {
-                g_return_if_fail(next_xpos != -1);
+		g_return_if_fail(next_xpos != -1);
 
 		term_set_color2(root_window, attr, fg, bg);
 
 		term_move(root_window, next_xpos, next_ypos);
 		if (flags & GUI_PRINT_FLAG_CLRTOEOL)
 			term_clrtoeol(root_window);
-		term_addstr(root_window, str);
-		next_xpos += strlen(str); /* FIXME utf8 or big5 */
-                return;
+		next_xpos += term_addstr(root_window, str);
+		return;
 	}
 
 	lineinfo.level = dest == NULL ? 0 : dest->level;
diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index ded79c28..8c95bc0d 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -522,15 +522,60 @@ void term_add_unichar(TERM_WINDOW *window, unichar chr)
 	}
 }
 
-void term_addstr(TERM_WINDOW *window, const char *str)
+int term_addstr(TERM_WINDOW *window, const char *str)
 {
-	int len;
+	int i, len, raw_len;
+	unichar *tmp;
+	const char *ptr;
 
 	if (vcmove) term_move_real();
-	len = strlen(str); /* FIXME utf8 or big5 */
+
+	raw_len = strlen(str);
+
+	/* The string length depends on the terminal encoding */
+	switch (term_type) {
+	case TERM_TYPE_BIG5:
+		len = strlen_big5((const unsigned char *)str);
+		break;
+	case TERM_TYPE_UTF8:
+		len = g_utf8_strlen(str, -1);
+		break;
+	default:
+		len = strlen(str);
+		break;
+	}
+
+	tmp = calloc(len, sizeof(unichar));
+	if (tmp == NULL)
+	    return 0;
+
+	switch (term_type) {
+	case TERM_TYPE_BIG5:
+	    big5_to_unichars(str, tmp);
+	    break;
+	case TERM_TYPE_UTF8:
+	    ptr = str;
+	    for (i = 0; i < len; i++) {
+		tmp[i] = g_utf8_get_char(ptr);
+		ptr = g_utf8_next_char(ptr);
+	    }
+	    break;
+	default:
+	    for (i = 0; i < len; i++)
+		tmp[i] = str[i];
+	}
+
+	for (len = i = 0; i < len; i++)
+	    len += unichar_isprint(tmp[i]) ? mk_wcwidth(tmp[i]) : 1;
+
+	free(tmp);
+
         term_printed_text(len);
 
-	fwrite(str, 1, len, window->term->out);
+	/* Use strlen() here since we need the number of raw bytes */
+	fwrite(str, 1, raw_len, window->term->out);
+
+	return len;
 }
 
 void term_clrtoeol(TERM_WINDOW *window)
diff --git a/src/fe-text/term.h b/src/fe-text/term.h
index cdcc787a..f0a76c42 100644
--- a/src/fe-text/term.h
+++ b/src/fe-text/term.h
@@ -83,7 +83,7 @@ void term_set_color(TERM_WINDOW *window, int col);
 void term_move(TERM_WINDOW *window, int x, int y);
 void term_addch(TERM_WINDOW *window, char chr);
 void term_add_unichar(TERM_WINDOW *window, unichar chr);
-void term_addstr(TERM_WINDOW *window, const char *str);
+int  term_addstr(TERM_WINDOW *window, const char *str);
 void term_clrtoeol(TERM_WINDOW *window);
 
 void term_move_cursor(int x, int y);

From c351c448b8dd2b9759e46c0c6e73ed5ead936ffc Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 15:02:43 +0200
Subject: [PATCH 10/26] Rework the logic to avoid allocating memory

---
 src/fe-text/term-terminfo.c | 52 ++++++++++++++-----------------------
 1 file changed, 19 insertions(+), 33 deletions(-)

diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index 8c95bc0d..2ee69a1c 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -524,52 +524,38 @@ void term_add_unichar(TERM_WINDOW *window, unichar chr)
 
 int term_addstr(TERM_WINDOW *window, const char *str)
 {
-	int i, len, raw_len;
-	unichar *tmp;
+	int len, raw_len;
+	unichar tmp;
 	const char *ptr;
 
 	if (vcmove) term_move_real();
 
+	len = 0;
 	raw_len = strlen(str);
 
 	/* The string length depends on the terminal encoding */
-	switch (term_type) {
-	case TERM_TYPE_BIG5:
-		len = strlen_big5((const unsigned char *)str);
-		break;
-	case TERM_TYPE_UTF8:
-		len = g_utf8_strlen(str, -1);
-		break;
-	default:
-		len = strlen(str);
-		break;
-	}
 
-	tmp = calloc(len, sizeof(unichar));
-	if (tmp == NULL)
-	    return 0;
+	ptr = str;
 
-	switch (term_type) {
-	case TERM_TYPE_BIG5:
-	    big5_to_unichars(str, tmp);
-	    break;
-	case TERM_TYPE_UTF8:
-	    ptr = str;
-	    for (i = 0; i < len; i++) {
-		tmp[i] = g_utf8_get_char(ptr);
+	if (term_type != TERM_TYPE_BIG5) {
+	    while (*ptr != '\0') {
+		tmp = g_utf8_get_char(ptr);
+		len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1;
 		ptr = g_utf8_next_char(ptr);
 	    }
-	    break;
-	default:
-	    for (i = 0; i < len; i++)
-		tmp[i] = str[i];
+	} else {
+	    while (*ptr != '\0') {
+		if (is_big5(ptr[0], ptr[1])) {
+		    tmp = ptr[0] << 8 | ptr[1];
+		    ptr += 2;
+		} else {
+		    tmp = *ptr;
+		    ptr += 1;
+		}
+		len += (tmp > 0xff) ? 2 : 1; 
+	    }
 	}
 
-	for (len = i = 0; i < len; i++)
-	    len += unichar_isprint(tmp[i]) ? mk_wcwidth(tmp[i]) : 1;
-
-	free(tmp);
-
         term_printed_text(len);
 
 	/* Use strlen() here since we need the number of raw bytes */

From c7646dc58d1e70abc8d2981e08baa83e459affdb Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 15:07:59 +0200
Subject: [PATCH 11/26] Even simpler logic

---
 src/fe-text/term-terminfo.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index 2ee69a1c..6d289cfc 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -543,18 +543,8 @@ int term_addstr(TERM_WINDOW *window, const char *str)
 		len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1;
 		ptr = g_utf8_next_char(ptr);
 	    }
-	} else {
-	    while (*ptr != '\0') {
-		if (is_big5(ptr[0], ptr[1])) {
-		    tmp = ptr[0] << 8 | ptr[1];
-		    ptr += 2;
-		} else {
-		    tmp = *ptr;
-		    ptr += 1;
-		}
-		len += (tmp > 0xff) ? 2 : 1; 
-	    }
-	}
+	} else
+	    len = raw_len;
 
         term_printed_text(len);
 

From 48ab298a67151e6fce33c1d7b34f4f83796b8d9a Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 15:08:48 +0200
Subject: [PATCH 12/26] Kill an unneeded declaration

---
 src/fe-common/core/utf8.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/fe-common/core/utf8.h b/src/fe-common/core/utf8.h
index 70b44d7e..3c15dc7d 100644
--- a/src/fe-common/core/utf8.h
+++ b/src/fe-common/core/utf8.h
@@ -8,8 +8,6 @@
 #define is_big5_hi(hi)  (0x81 <= (hi) && (hi) <= 0xFE)
 #define is_big5(hi,lo) (is_big5_hi(hi) && is_big5_lo(lo))
 
-int strlen_big5(const unsigned char *str);
-
 /* Returns width for character (0-2). */
 int mk_wcwidth(unichar c);
 

From db5ae4adce6ad82150a4fef01c8b141631f89d96 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Fri, 2 Oct 2015 17:13:49 +0200
Subject: [PATCH 13/26] Flush the dirty buffer to disk

Given a big enough write_buffer_size and a long enough
write_buffer_timeout it might be possible to show the user an incomplete
or empty awaylog.

Patch by: Petteri Aimonen
---
 src/core/log-away.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/core/log-away.c b/src/core/log-away.c
index 681edcbf..c6de721c 100644
--- a/src/core/log-away.c
+++ b/src/core/log-away.c
@@ -62,6 +62,9 @@ static void awaylog_open(void)
 		return;
 	}
 
+	/* Flush the dirty buffers to disk before acquiring the file position */
+	write_buffer_flush();
+
 	awaylog = log;
 	away_filepos = lseek(log->handle, 0, SEEK_CUR);
 	away_msgs = 0;
@@ -83,6 +86,9 @@ static void awaylog_close(void)
 
 	if (awaylog == log) awaylog = NULL;
 
+	/* Flush the dirty buffers to disk before showing the away log */
+	write_buffer_flush();
+
 	signal_emit("awaylog show", 3, log, GINT_TO_POINTER(away_msgs),
 		    GINT_TO_POINTER(away_filepos));
 	log_close(log);

From ef55e0f6534a5b790131c320fd0490a5beb21a68 Mon Sep 17 00:00:00 2001
From: dequis 
Date: Fri, 2 Oct 2015 13:48:23 -0300
Subject: [PATCH 14/26] Add missing null terminator to the g_build_path()
 varargs

Lemon broke it a few commits ago.
---
 src/core/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/core.c b/src/core/core.c
index 879d346f..bbeec6f4 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -161,7 +161,7 @@ static char *fix_path(const char *str)
 		char *tmp_str = new_str;
 		char *current_dir = g_get_current_dir();
 
-		new_str = g_build_path(G_DIR_SEPARATOR_S, current_dir, tmp_str);
+		new_str = g_build_path(G_DIR_SEPARATOR_S, current_dir, tmp_str, NULL);
 
 		g_free(current_dir);
 		g_free(tmp_str);

From a66bb95d0e3d76dfb6abda88d6f128540279b461 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= 
Date: Fri, 2 Oct 2015 18:57:06 +0200
Subject: [PATCH 15/26] Use silent rules.

---
 .travis.yml  | 2 +-
 configure.ac | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index aa807a7b..f066c17b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,7 +20,7 @@ before_install:
 install: true
 
 script:
-    - ./autogen.sh --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build --enable-silent-rules
+    - ./autogen.sh --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build
     - cat config.log
     - make
     - make install
diff --git a/configure.ac b/configure.ac
index 7bcd3fe7..325b5e5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,6 +7,8 @@ AC_CONFIG_HEADERS([irssi-config.h])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([1.9 no-define foreign])
 
+AM_SILENT_RULES([yes])
+
 AM_MAINTAINER_MODE
 
 AC_PROG_CC

From da3f2f0d0174675faa1a092722e8298460254112 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= 
Date: Fri, 2 Oct 2015 19:51:54 +0200
Subject: [PATCH 16/26] Set HOST_NAME_MAX to 255, if it's undefined.

Thanks to Jilles and dx.

Fixes #309
---
 src/irc/core/irc-expandos.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/irc/core/irc-expandos.c b/src/irc/core/irc-expandos.c
index 5d8150f0..62ef577a 100644
--- a/src/irc/core/irc-expandos.c
+++ b/src/irc/core/irc-expandos.c
@@ -27,6 +27,10 @@
 #include "irc-channels.h"
 #include "nicklist.h"
 
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif
+
 static char *last_join;
 
 /* last person to join a channel you are on */
@@ -56,7 +60,7 @@ static char *expando_userhost(SERVER_REC *server, void *item, int *free_ret)
 {
 	IRC_SERVER_REC *ircserver;
 	const char *username;
-	char hostname[HOST_NAME_MAX];
+	char hostname[HOST_NAME_MAX + 1];
 
 	ircserver = IRC_SERVER(server);
 
@@ -80,7 +84,7 @@ static char *expando_userhost(SERVER_REC *server, void *item, int *free_ret)
 static char *expando_hostname(SERVER_REC *server, void *item, int *free_ret)
 {
 	IRC_SERVER_REC *ircserver;
-	char hostname[HOST_NAME_MAX];
+	char hostname[HOST_NAME_MAX + 1];
 	char **list;
 	char *hostname_split;
 

From b68a30cdfe43bec9cdb0e7c822b66d90ccf8982d Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Sat, 3 Oct 2015 14:32:38 +0200
Subject: [PATCH 17/26] Include write-buffer.h in log-away.c

Silence a warning and make the world a better place.
---
 src/core/log-away.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/log-away.c b/src/core/log-away.c
index c6de721c..e2a0120b 100644
--- a/src/core/log-away.c
+++ b/src/core/log-away.c
@@ -24,6 +24,7 @@
 #include "log.h"
 #include "servers.h"
 #include "settings.h"
+#include "write-buffer.h"
 
 static LOG_REC *awaylog;
 static int away_filepos;

From 48375c3f900f56434441caa0161c0531fd0ce435 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= 
Date: Sat, 3 Oct 2015 18:50:23 +0200
Subject: [PATCH 18/26] Simplify Travis config.

---
 .travis.yml | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index f066c17b..c8bbb6d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,15 +24,3 @@ script:
     - cat config.log
     - make
     - make install
-
-notifications:
-    irc:
-        channels:
-            - "irc.freenode.net#irssi"
-        template:
-            - "%{repository} (%{commit}: %{author}): %{message}"
-            - "Build details : %{build_url}"
-        on_success: always
-        on_failure: always
-        use_notice: true
-        skip_join: true

From 685d8fe5b033ffce40b02aaf4ec3341f5cf3350c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= 
Date: Fri, 2 Oct 2015 20:25:14 +0200
Subject: [PATCH 19/26] Add SETTING_TYPE_ANY and replace -1 with it.

---
 src/core/settings.c              |  9 +++++----
 src/core/settings.h              |  3 ++-
 src/fe-common/core/completion.c  |  5 ++---
 src/fe-common/core/fe-settings.c | 31 +++++++++++++++----------------
 4 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/core/settings.c b/src/core/settings.c
index b34a5766..8e493124 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -59,7 +59,7 @@ static SETTINGS_REC *settings_get(const char *key, SettingType type)
 		g_warning("settings_get(%s) : not found", key);
 		return NULL;
 	}
-	if (type != -1 && rec->type != type) {
+	if (type != SETTING_TYPE_ANY && rec->type != type) {
 		g_warning("settings_get(%s) : invalid type", key);
 		return NULL;
 	}
@@ -85,7 +85,7 @@ settings_get_str_type(const char *key, SettingType type)
 
 const char *settings_get_str(const char *key)
 {
-	return settings_get_str_type(key, -1);
+	return settings_get_str_type(key, SETTING_TYPE_ANY);
 }
 
 int settings_get_int(const char *key)
@@ -163,6 +163,7 @@ char *settings_get_print(SETTINGS_REC *rec)
 	case SETTING_TYPE_TIME:
 	case SETTING_TYPE_LEVEL:
 	case SETTING_TYPE_SIZE:
+	case SETTING_TYPE_ANY:
 		value = g_strdup(settings_get_str(rec->key));
 		break;
 	}
@@ -380,10 +381,10 @@ SettingType settings_get_type(const char *key)
 {
 	SETTINGS_REC *rec;
 
-	g_return_val_if_fail(key != NULL, -1);
+	g_return_val_if_fail(key != NULL, SETTING_TYPE_ANY);
 
 	rec = g_hash_table_lookup(settings, key);
-	return rec == NULL ? -1 : rec->type;
+	return rec == NULL ? SETTING_TYPE_ANY : rec->type;
 }
 
 /* Get the record of the setting */
diff --git a/src/core/settings.h b/src/core/settings.h
index af00cc80..6f2cf129 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -7,7 +7,8 @@ typedef enum {
 	SETTING_TYPE_BOOLEAN,
 	SETTING_TYPE_TIME,
 	SETTING_TYPE_LEVEL,
-	SETTING_TYPE_SIZE
+	SETTING_TYPE_SIZE,
+	SETTING_TYPE_ANY
 } SettingType;
 
 typedef struct {
diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c
index 312e417c..4461de92 100644
--- a/src/fe-common/core/completion.c
+++ b/src/fe-common/core/completion.c
@@ -362,8 +362,7 @@ static GList *completion_get_settings(const char *key, SettingType type)
 	for (tmp = sets; tmp != NULL; tmp = tmp->next) {
 		SETTINGS_REC *rec = tmp->data;
 
-		if ((type == -1 || rec->type == type) &&
-		    g_ascii_strncasecmp(rec->key, key, len) == 0)
+		if ((type == SETTING_TYPE_ANY || rec->type == type) && g_ascii_strncasecmp(rec->key, key, len) == 0)
 			complist = g_list_insert_sorted(complist, g_strdup(rec->key), (GCompareFunc) g_istr_cmp);
 	}
 	g_slist_free(sets);
@@ -682,7 +681,7 @@ static void sig_complete_set(GList **list, WINDOW_REC *window,
 
 	if (*line == '\0' ||
 	    !g_strcmp0("-clear", line) || !g_strcmp0("-default", line))
-		*list = completion_get_settings(word, -1);
+		*list = completion_get_settings(word, SETTING_TYPE_ANY);
 	else if (*line != '\0' && *word == '\0') {
 		SETTINGS_REC *rec = settings_get_record(line);
 		if (rec != NULL) {
diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c
index 9c370838..2627989d 100644
--- a/src/fe-common/core/fe-settings.c
+++ b/src/fe-common/core/fe-settings.c
@@ -126,7 +126,7 @@ static void cmd_set(char *data)
 			/* change the setting */
 			switch (rec->type) {
 			case SETTING_TYPE_BOOLEAN:
-                                if (clear)
+				if (clear)
 					settings_set_bool(key, FALSE);
 				else if (set_default)
 					settings_set_bool(key, rec->default_value.v_bool);
@@ -149,32 +149,30 @@ static void cmd_set(char *data)
 			case SETTING_TYPE_TIME:
 				if (!settings_set_time(key, clear ? "0" :
 						       set_default ? rec->default_value.v_string : value))
-					printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-						    TXT_INVALID_TIME);
+					printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_INVALID_TIME);
 				break;
 			case SETTING_TYPE_LEVEL:
 				if (!settings_set_level(key, clear ? "" :
 							set_default ? rec->default_value.v_string : value))
-					printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-						    TXT_INVALID_LEVEL);
+					printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_INVALID_LEVEL);
 				break;
 			case SETTING_TYPE_SIZE:
 				if (!settings_set_size(key, clear ? "0" :
 						       set_default ? rec->default_value.v_string : value))
-					printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-						    TXT_INVALID_SIZE);
+					printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_INVALID_SIZE);
+				break;
+			case SETTING_TYPE_ANY:
+				/* Unpossible! */
 				break;
 			}
 			signal_emit("setup changed", 0);
-			printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
-				    TXT_SET_TITLE, rec->section);
+			printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_SET_TITLE, rec->section);
 			set_print(rec);
 		} else
-			printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-				    TXT_SET_UNKNOWN, key);
+			printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SET_UNKNOWN, key);
 	}
 
-        cmd_params_free(free_arg);
+	cmd_params_free(free_arg);
 }
 
 /* SYNTAX: TOGGLE  [on|off|toggle] */
@@ -187,20 +185,21 @@ static void cmd_toggle(const char *data)
 	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &key, &value))
 		return;
 
-        if (*key == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+	if (*key == '\0')
+		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
 
 	type = settings_get_type(key);
-        if (type == -1)
+	if (type == SETTING_TYPE_ANY)
 		printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SET_UNKNOWN, key);
 	else if (type != SETTING_TYPE_BOOLEAN)
 		printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SET_NOT_BOOLEAN, key);
 	else {
 		set_boolean(key, *value != '\0' ? value : "TOGGLE");
-                set_print(settings_get_record(key));
+		set_print(settings_get_record(key));
 		signal_emit("setup changed", 0);
 	}
 
-        cmd_params_free(free_arg);
+	cmd_params_free(free_arg);
 }
 
 static int config_key_compare(CONFIG_NODE *node1, CONFIG_NODE *node2)

From 5f35fbc57a18eabc68723f1b82aacbfd84f637d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= 
Date: Fri, 2 Oct 2015 20:29:19 +0200
Subject: [PATCH 20/26] Remove check for >= 0 for unsigned unichar.

---
 src/fe-text/gui-entry.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c
index 17a7c507..c7d06404 100644
--- a/src/fe-text/gui-entry.c
+++ b/src/fe-text/gui-entry.c
@@ -35,21 +35,21 @@ static unichar i_toupper(unichar c)
 {
 	if (term_type == TERM_TYPE_UTF8)
 		return g_unichar_toupper(c);
-	return (c >= 0 && c <= 255) ? toupper(c) : c;
+	return c <= 255 ? toupper(c) : c;
 }
 
 static unichar i_tolower(unichar c)
 {
 	if (term_type == TERM_TYPE_UTF8)
 		return g_unichar_tolower(c);
-	return (c >= 0 && c <= 255) ? tolower(c) : c;
+	return c <= 255 ? tolower(c) : c;
 }
 
 static int i_isalnum(unichar c)
 {
 	if (term_type == TERM_TYPE_UTF8)
 		return (g_unichar_isalnum(c) || mk_wcwidth(c) == 0);
-	return (c >= 0 && c <= 255) ? isalnum(c) : 0;
+	return c <= 255 ? isalnum(c) : 0;
 }
 
 GUI_ENTRY_REC *active_entry;

From 2127fd362e240a9fed09dff9044fe5c477fc2bf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= 
Date: Sat, 3 Oct 2015 19:07:08 +0200
Subject: [PATCH 21/26] Add -Wall and -Werror as CFLAGS to make.

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index c8bbb6d8..46f58766 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,5 +22,5 @@ install: true
 script:
     - ./autogen.sh --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build
     - cat config.log
-    - make
+    - make CFLAGS="-Wall -Werror"
     - make install

From 0140e7c6b23ff1490965b080a7882b2508677d55 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Sun, 4 Oct 2015 11:56:54 +0200
Subject: [PATCH 22/26] Fix the indentation.

---
 src/fe-text/term-terminfo.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index 6d289cfc..27be904e 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -537,14 +537,14 @@ int term_addstr(TERM_WINDOW *window, const char *str)
 
 	ptr = str;
 
-	if (term_type != TERM_TYPE_BIG5) {
-	    while (*ptr != '\0') {
-		tmp = g_utf8_get_char(ptr);
-		len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1;
-		ptr = g_utf8_next_char(ptr);
-	    }
+	if (term_type == TERM_TYPE_UTF8) {
+		while (*ptr != '\0') {
+			tmp = g_utf8_get_char(ptr);
+			len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1;
+			ptr = g_utf8_next_char(ptr);
+		}
 	} else
-	    len = raw_len;
+		len = raw_len;
 
         term_printed_text(len);
 

From 58a166484ad7eab33c1ad72b64016e5aacebfaf5 Mon Sep 17 00:00:00 2001
From: dequis 
Date: Tue, 6 Oct 2015 04:51:16 -0300
Subject: [PATCH 23/26] Add xterm's keypad enter, meta-O-M to "key return"
 bindings

From the 'kent' terminfo entry. Also applies to putty.

Fixes #327
---
 src/fe-text/gui-readline.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c
index ec61e317..dc7185e7 100644
--- a/src/fe-text/gui-readline.c
+++ b/src/fe-text/gui-readline.c
@@ -1020,6 +1020,8 @@ void gui_readline_init(void)
 	key_bind("key", NULL, "meta2-5F", "cend", (SIGNAL_FUNC) key_combo);
 	key_bind("key", NULL, "meta2-1;5F", "cend", (SIGNAL_FUNC) key_combo);
 
+	key_bind("key", NULL, "meta-O-M", "return", (SIGNAL_FUNC) key_combo);
+
 	/* cursor movement */
 	key_bind("backward_character", "Move the cursor a character backward", "left", NULL, (SIGNAL_FUNC) key_backward_character);
 	key_bind("forward_character", "Move the cursor a character forward", "right", NULL, (SIGNAL_FUNC) key_forward_character);

From f540ec9de1bb35b226e3c97e763238072fe295dd Mon Sep 17 00:00:00 2001
From: dequis 
Date: Thu, 8 Oct 2015 00:06:17 -0300
Subject: [PATCH 24/26] Fix /reconnect RECON-1 saying "Reconnection tag 1 not
 found"

Turns out it was fixing the wrong string, and trying to do
atoi("RECON-1") instead of atoi("1").

"/reconnect 1" worked, but "/reconnect RECON-1" gave that confusing
error message.
---
 src/core/servers-reconnect.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c
index ae97ecd2..f419035b 100644
--- a/src/core/servers-reconnect.c
+++ b/src/core/servers-reconnect.c
@@ -420,8 +420,8 @@ static void cmd_reconnect(const char *data, SERVER_REC *server)
 			cmd_param_error(CMDERR_NOT_CONNECTED);
                 rec = reconnects->data;
 	} else {
-		if (g_ascii_strncasecmp(data, "RECON-", 6) == 0)
-			data += 6;
+		if (g_ascii_strncasecmp(tag, "RECON-", 6) == 0)
+			tag += 6;
 
 		tagnum = atoi(tag);
 		rec = tagnum <= 0 ? NULL : reconnect_find_tag(tagnum);

From 06bf25bfbaaf33772e36317dba28ce5b6a301616 Mon Sep 17 00:00:00 2001
From: Rodrigo Rebello 
Date: Wed, 28 Oct 2015 13:38:21 -0200
Subject: [PATCH 25/26] Fix quote around macro argument

In m4/curses.m4, line 134, the 5th argument passed to AC_NCURSES was
surrounded by '"' instead of '[' and ']'. Because of that, the expansion
of AC_NCURSES in that case would produce the following line inside the
configure script (note the repeated double quotes):

  screen_manager=""ncurses on $withval/include""

That would cause the following error when configure was executed with
the "--with-ncurses=dir" argument:

  ./configure: line 13468: on: command not found

Although in the case above the error doesn't actually influence the
build process ('screen_manager' isn't used anywhere in the script),
trying to execute 'on' might be harmful if it corresponded to an
existing command in the user's environment.
---
 m4/curses.m4 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/m4/curses.m4 b/m4/curses.m4
index 82b110fe..41c0e6c8 100644
--- a/m4/curses.m4
+++ b/m4/curses.m4
@@ -131,7 +131,7 @@ AC_DEFUN([AC_CHECK_CURSES],[
 	  if test x$withval = xno ; then
 		search_ncurses=false
 	  elif test x$withval != xyes ; then
-		AC_NCURSES($withval/include, ncurses.h, -L$withval/lib -lncurses, -I$withval/include, "ncurses on $withval/include")
+		AC_NCURSES($withval/include, ncurses.h, -L$withval/lib -lncurses, -I$withval/include, [ncurses on $withval/include])
 	  fi
 	)
 

From 8094e87cdf78bd864ffb37351ff4853cb127d8d1 Mon Sep 17 00:00:00 2001
From: LemonBoy 
Date: Wed, 28 Oct 2015 21:56:35 +0100
Subject: [PATCH 26/26] Preserve the sasl_ options across reconnects.

---
 src/irc/core/irc-servers-reconnect.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c
index b0aad26f..ca61492d 100644
--- a/src/irc/core/irc-servers-reconnect.c
+++ b/src/irc/core/irc-servers-reconnect.c
@@ -48,6 +48,9 @@ static void sig_server_connect_copy(SERVER_CONNECT_REC **dest,
 	rec->max_whois = src->max_whois;
 	rec->usermode = g_strdup(src->usermode);
 	rec->alternate_nick = g_strdup(src->alternate_nick);
+	rec->sasl_mechanism = src->sasl_mechanism;
+	rec->sasl_username = src->sasl_username;
+	rec->sasl_password = src->sasl_password;
 	*dest = (SERVER_CONNECT_REC *) rec;
 }