summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/network-openssl.c20
-rw-r--r--src/fe-common/core/chat-completion.c55
-rw-r--r--src/fe-common/core/themes.c2
-rw-r--r--src/fe-common/irc/fe-netjoin.c16
-rw-r--r--src/fe-common/irc/fe-netsplit.c15
-rw-r--r--src/fe-text/gui-readline.c3
-rw-r--r--src/fe-text/mainwindows.c91
7 files changed, 148 insertions, 54 deletions
diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c
index c7ce4b43..9fddf073 100644
--- a/src/core/network-openssl.c
+++ b/src/core/network-openssl.c
@@ -46,6 +46,7 @@
#endif
/* OpenSSL 1.1.0 also introduced some useful additions to the api */
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER)
static int X509_STORE_up_ref(X509_STORE *vfy)
{
@@ -57,6 +58,7 @@ static int X509_STORE_up_ref(X509_STORE *vfy)
return (n > 1) ? 1 : 0;
}
#endif
+#endif
/* ssl i/o channel object */
typedef struct
@@ -72,7 +74,10 @@ typedef struct
} GIOSSLChannel;
static int ssl_inited = FALSE;
+/* https://github.com/irssi/irssi/issues/820 */
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
static X509_STORE *store = NULL;
+#endif
static void irssi_ssl_free(GIOChannel *handle)
{
@@ -379,7 +384,9 @@ static GIOFuncs irssi_ssl_channel_funcs = {
gboolean irssi_ssl_init(void)
{
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
int success;
+#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
if (!OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL)) {
@@ -391,6 +398,8 @@ gboolean irssi_ssl_init(void)
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
store = X509_STORE_new();
if (store == NULL) {
g_error("Could not initialize OpenSSL: X509_STORE_new() failed");
@@ -404,6 +413,7 @@ gboolean irssi_ssl_init(void)
store = NULL;
/* Don't return an error; the user might have their own cafile/capath. */
}
+#endif
ssl_inited = TRUE;
@@ -522,13 +532,21 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_
g_free(scafile);
g_free(scapath);
verify = TRUE;
- } else if (store != NULL) {
+ }
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
+ else if (store != NULL) {
/* Make sure to increment the refcount every time the store is
* used, that's essential not to get it free'd by OpenSSL when
* the SSL_CTX is destroyed. */
X509_STORE_up_ref(store);
SSL_CTX_set_cert_store(ctx, store);
}
+#else
+ else {
+ if (!SSL_CTX_set_default_verify_paths(ctx))
+ g_warning("Could not load default certificates");
+ }
+#endif
if(!(ssl = SSL_new(ctx)))
{
diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c
index 97cd0565..7ecdd4a2 100644
--- a/src/fe-common/core/chat-completion.c
+++ b/src/fe-common/core/chat-completion.c
@@ -639,6 +639,59 @@ static void complete_window_nicks(GList **list, WINDOW_REC *window,
}
}
+/* Checks if a line is only nicks from autocompletion.
+ This lets us insert colons only at the beginning of a list
+ of nicks */
+static int only_nicks(const char *linestart)
+{
+ int i = 1;
+ char prev;
+
+ // at the beginning of the line
+ if (*linestart == '\0') {
+ return TRUE;
+ }
+
+ /* completion_char being a whole string introduces loads of edge cases
+ and can't be handled generally. Skip this case; we handled the
+ "beginning of line" case already */
+ if (completion_char[1] != '\0')
+ return FALSE;
+
+ /* This would make the completion char get inserted everywhere otherwise */
+ if (*completion_char == ' ')
+ return FALSE;
+
+ /* First ensure that the line is of the format "foo: bar: baz"
+ we check this by ensuring each space is preceded by a colon or
+ another space */
+ while (linestart[i] != '\0') {
+ if (linestart[i] == ' ') {
+ prev = linestart[i - 1];
+ if (prev != *completion_char && prev != ' ')
+ return FALSE;
+ }
+ i += 1;
+ }
+
+ /* There's an edge case here, if we're completing something
+ like `foo: bar ba<tab>`, then the `linestart` line will end
+ at "bar", and we'll miss the space. Ensure that the end
+ of the line is a colon followed by an optional series of spaces */
+ i -= 1;
+ while (i >= 0) {
+ if (linestart[i] == ' ') {
+ i--;
+ continue;
+ } else if (linestart[i] == *completion_char) {
+ return TRUE;
+ } else {
+ break;
+ }
+ }
+ return FALSE;
+}
+
static void sig_complete_word(GList **list, WINDOW_REC *window,
const char *word, const char *linestart,
int *want_space)
@@ -691,7 +744,7 @@ static void sig_complete_word(GList **list, WINDOW_REC *window,
} else if (channel != NULL) {
/* nick completion .. we could also be completing a nick
after /MSG from nicks in channel */
- const char *suffix = *linestart != '\0' ? NULL : completion_char;
+ const char *suffix = only_nicks(linestart) ? completion_char : NULL;
complete_window_nicks(list, window, word, suffix);
} else if (window->level & MSGLEVEL_MSGS) {
/* msgs window, complete /MSG nicks */
diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c
index cb1cce8f..6692985b 100644
--- a/src/fe-common/core/themes.c
+++ b/src/fe-common/core/themes.c
@@ -130,7 +130,7 @@ static char *theme_replace_expand(THEME_REC *theme, int index,
abstract = rec->data;
abstract = theme_format_expand_data(theme, (const char **) &abstract,
default_fg, default_bg,
- last_fg, last_bg, flags);
+ last_fg, last_bg, (flags | EXPAND_FLAG_IGNORE_REPLACES));
ret = parse_special_string(abstract, NULL, NULL, data, NULL,
PARSE_FLAG_ONLY_ARGS);
g_free(abstract);
diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c
index bc39b27c..a7a2e4fe 100644
--- a/src/fe-common/irc/fe-netjoin.c
+++ b/src/fe-common/irc/fe-netjoin.c
@@ -245,20 +245,18 @@ static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channe
message before it. */
static void sig_print_starting(TEXT_DEST_REC *dest)
{
- NETJOIN_SERVER_REC *rec;
+ GSList *tmp, *next;
if (printing_joins)
return;
- if (!IS_IRC_SERVER(dest->server))
- return;
-
- if (!server_ischannel(dest->server, dest->target))
- return;
+ for (tmp = joinservers; tmp != NULL; tmp = next) {
+ NETJOIN_SERVER_REC *server = tmp->data;
- rec = netjoin_find_server(IRC_SERVER(dest->server));
- if (rec != NULL && rec->netjoins != NULL)
- print_netjoins(rec, NULL);
+ next = tmp->next;
+ if (server->netjoins != NULL)
+ print_netjoins(server, NULL);
+ }
}
static int sig_check_netjoins(void)
diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c
index ac3330e5..edd3fc34 100644
--- a/src/fe-common/irc/fe-netsplit.c
+++ b/src/fe-common/irc/fe-netsplit.c
@@ -247,20 +247,17 @@ static int check_server_splits(IRC_SERVER_REC *server)
message before it. */
static void sig_print_starting(TEXT_DEST_REC *dest)
{
- IRC_SERVER_REC *rec;
+ GSList *tmp;
if (printing_splits)
return;
- if (!IS_IRC_SERVER(dest->server))
- return;
-
- if (!server_ischannel(dest->server, dest->target))
- return;
+ for (tmp = servers; tmp != NULL; tmp = tmp->next) {
+ IRC_SERVER_REC *rec = tmp->data;
- rec = IRC_SERVER(dest->server);
- if (rec->split_servers != NULL)
- print_splits(rec, NULL);
+ if (IS_IRC_SERVER(rec) && rec->split_servers != NULL)
+ print_splits(rec, NULL);
+ }
}
static int sig_check_splits(void)
diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c
index b3a78396..88e827a7 100644
--- a/src/fe-text/gui-readline.c
+++ b/src/fe-text/gui-readline.c
@@ -1174,6 +1174,7 @@ void gui_readline_init(void)
key_bind("key", NULL, "^H", "backspace", (SIGNAL_FUNC) key_combo);
key_bind("key", NULL, "^?", "backspace", (SIGNAL_FUNC) key_combo);
key_bind("key", NULL, "^I", "tab", (SIGNAL_FUNC) key_combo);
+ key_bind("key", NULL, "meta2-Z", "stab", (SIGNAL_FUNC) key_combo);
/* meta */
key_bind("key", NULL, "^[", "meta", (SIGNAL_FUNC) key_combo);
@@ -1278,7 +1279,7 @@ void gui_readline_init(void)
/* line transmitting */
key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line);
- key_bind("word_completion_backward", "", NULL, NULL, (SIGNAL_FUNC) key_word_completion_backward);
+ key_bind("word_completion_backward", "Choose previous completion suggestion", "stab", NULL, (SIGNAL_FUNC) key_word_completion_backward);
key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion);
key_bind("erase_completion", "Remove the completion added by word_completion", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion);
key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces);
diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c
index 5f24674f..83a3e0cc 100644
--- a/src/fe-text/mainwindows.c
+++ b/src/fe-text/mainwindows.c
@@ -915,6 +915,8 @@ static int try_shrink_lower(MAIN_WINDOW_REC *window, int count)
{
MAIN_WINDOW_REC *shrink_win;
+ g_return_val_if_fail(count >= 0, FALSE);
+
shrink_win = mainwindows_find_lower(window);
if (shrink_win != NULL) {
int ok;
@@ -959,6 +961,8 @@ static int try_shrink_upper(MAIN_WINDOW_REC *window, int count)
{
MAIN_WINDOW_REC *shrink_win;
+ g_return_val_if_fail(count >= 0, FALSE);
+
shrink_win = mainwindows_find_upper(window);
if (shrink_win != NULL) {
int ok;
@@ -1063,6 +1067,8 @@ static int try_grow_upper(MAIN_WINDOW_REC *window, int count)
static int mainwindow_shrink(MAIN_WINDOW_REC *window, int count, int resize_lower)
{
+ g_return_val_if_fail(count >= 0, FALSE);
+
if (MAIN_WINDOW_TEXT_HEIGHT(window)-count < WINDOW_MIN_SIZE)
return FALSE;
@@ -1091,6 +1097,8 @@ static int try_rshrink_right(MAIN_WINDOW_REC *window, int count)
{
MAIN_WINDOW_REC *shrink_win;
+ g_return_val_if_fail(count >= 0, FALSE);
+
shrink_win = mainwindows_find_right(window, FALSE);
if (shrink_win != NULL) {
if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) {
@@ -1111,6 +1119,8 @@ static int try_rshrink_left(MAIN_WINDOW_REC *window, int count)
{
MAIN_WINDOW_REC *shrink_win;
+ g_return_val_if_fail(count >= 0, FALSE);
+
shrink_win = mainwindows_find_left(window, FALSE);
if (shrink_win != NULL) {
if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) {
@@ -1168,6 +1178,8 @@ static int try_rgrow_left(MAIN_WINDOW_REC *window, int count)
static int mainwindow_rshrink(MAIN_WINDOW_REC *window, int count)
{
+ g_return_val_if_fail(count >= 0, FALSE);
+
if (MAIN_WINDOW_TEXT_WIDTH(window)-count < NEW_WINDOW_WIDTH)
return FALSE;
@@ -1220,19 +1232,29 @@ void mainwindows_redraw_dirty(void)
}
}
+static void mainwindow_grow_int(int count)
+{
+ if (count == 0) {
+ return;
+ } else if (count < 0) {
+ if (!mainwindow_shrink(WINDOW_MAIN(active_win), -count, FALSE)) {
+ printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL);
+ }
+ } else {
+ if (!mainwindow_grow(WINDOW_MAIN(active_win), count, FALSE)) {
+ printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL);
+ }
+ }
+}
+
/* SYNTAX: WINDOW GROW [<lines>] */
static void cmd_window_grow(const char *data)
{
- MAIN_WINDOW_REC *window;
int count;
count = *data == '\0' ? 1 : atoi(data);
- window = WINDOW_MAIN(active_win);
- if (!mainwindow_grow(window, count, FALSE)) {
- printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
- TXT_WINDOW_TOO_SMALL);
- }
+ mainwindow_grow_int(count);
}
/* SYNTAX: WINDOW SHRINK [<lines>] */
@@ -1241,16 +1263,14 @@ static void cmd_window_shrink(const char *data)
int count;
count = *data == '\0' ? 1 : atoi(data);
- if (!mainwindow_shrink(WINDOW_MAIN(active_win), count, FALSE)) {
- printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
- TXT_WINDOW_TOO_SMALL);
- }
+ if (count < -INT_MAX) count = -INT_MAX;
+
+ mainwindow_grow_int(-count);
}
/* SYNTAX: WINDOW SIZE <lines> */
static void cmd_window_size(const char *data)
{
- char sizestr[MAX_INT_STRLEN];
int size;
if (!is_numeric(data, 0)) return;
@@ -1258,13 +1278,9 @@ static void cmd_window_size(const char *data)
size -= WINDOW_MAIN(active_win)->height -
WINDOW_MAIN(active_win)->statusbar_lines;
- if (size == 0) return;
+ if (size < -INT_MAX) size = -INT_MAX;
- ltoa(sizestr, size < 0 ? -size : size);
- if (size < 0)
- cmd_window_shrink(sizestr);
- else
- cmd_window_grow(sizestr);
+ mainwindow_grow_int(size);
}
/* SYNTAX: WINDOW BALANCE */
@@ -1393,6 +1409,11 @@ static void _cmd_window_show_opt(const char *data, int right)
}
parent = mainwindow_create(right);
+ if (parent == NULL) {
+ printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_WINDOW_TOO_SMALL);
+ return;
+ }
+
parent->active = window;
gui_window_reparent(window, parent);
@@ -1415,16 +1436,29 @@ static void cmd_window_rshow(const char *data)
_cmd_window_show_opt(data, TRUE);
}
+static void window_rgrow_int(int count)
+{
+ if (count == 0) {
+ return;
+ } else if (count < 0) {
+ if (!mainwindow_rshrink(WINDOW_MAIN(active_win), -count)) {
+ printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL);
+ }
+ } else {
+ if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) {
+ printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL);
+ }
+ }
+}
+
/* SYNTAX: WINDOW RGROW [<columns>] */
static void cmd_window_rgrow(const char *data)
{
int count;
count = *data == '\0' ? 1 : atoi(data);
- if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) {
- printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
- TXT_WINDOW_TOO_SMALL);
- }
+
+ window_rgrow_int(count);
}
/* SYNTAX: WINDOW RSHRINK [<lines>] */
@@ -1433,29 +1467,22 @@ static void cmd_window_rshrink(const char *data)
int count;
count = *data == '\0' ? 1 : atoi(data);
- if (!mainwindow_rshrink(WINDOW_MAIN(active_win), count)) {
- printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
- TXT_WINDOW_TOO_SMALL);
- }
+ if (count < -INT_MAX) count = -INT_MAX;
+
+ window_rgrow_int(-count);
}
/* SYNTAX: WINDOW RSIZE <columns> */
static void cmd_window_rsize(const char *data)
{
- char rsizestr[MAX_INT_STRLEN];
int rsize;
if (!is_numeric(data, 0)) return;
rsize = atoi(data);
rsize -= MAIN_WINDOW_TEXT_WIDTH(WINDOW_MAIN(active_win));
- if (rsize == 0) return;
- ltoa(rsizestr, rsize < 0 ? -rsize : rsize);
- if (rsize < 0)
- cmd_window_rshrink(rsizestr);
- else
- cmd_window_rgrow(rsizestr);
+ window_rgrow_int(rsize);
}
/* SYNTAX: WINDOW RBALANCE */