From ccc64c0050478dc0567ce9bb22dc75d541f8477e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 26 Jun 2014 10:26:59 +0200 Subject: [PATCH 0001/1495] forward alternate_nick to Irc::Server attributes add the missing alternate_nick in Irc::Server by making an additional call to the Irc::Connect filler. this is not quite ideal but might need bigger refactoring otherwise. --- src/perl/irc/Irc.xs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 22a87384..601ba852 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -11,6 +11,7 @@ static void perl_irc_connect_fill_hash(HV *hv, IRC_SERVER_CONNECT_REC *conn) static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server) { + perl_irc_connect_fill_hash(hv, server->connrec); perl_server_fill_hash(hv, (SERVER_REC *) server); hv_store(hv, "real_address", 12, new_pv(server->real_address), 0); From 98435fb4649367c182e35aea8c89ce7a4cf8d4d3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 11 Sep 2014 18:15:06 +0200 Subject: [PATCH 0002/1495] support storing and replaying the monospace attribute in textbuffer --- src/fe-text/textbuffer-view.c | 3 +++ src/fe-text/textbuffer.c | 8 ++++++++ src/fe-text/textbuffer.h | 1 + 3 files changed, 12 insertions(+) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 3099ee3e..ad4c00b8 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -146,6 +146,9 @@ static void update_cmd_color(unsigned char cmd, int *color) case LINE_CMD_ITALIC: *color ^= ATTR_ITALIC; break; + case LINE_CMD_MONOSPACE: + /* ignored */ + break; case LINE_CMD_COLOR0: *color &= BGATTR; *color &= ~ATTR_FGCOLOR24; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 24ee62bc..561fdabd 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -326,6 +326,10 @@ void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, data[pos++] = 0; data[pos++] = LINE_CMD_ITALIC; } + if ((flags & GUI_PRINT_FLAG_MONOSPACE) != (buffer->last_flags & GUI_PRINT_FLAG_MONOSPACE)) { + data[pos++] = 0; + data[pos++] = LINE_CMD_MONOSPACE; + } if (flags & GUI_PRINT_FLAG_INDENT) { data[pos++] = 0; data[pos++] = LINE_CMD_INDENT; @@ -509,6 +513,10 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) g_string_append_printf(str, "\004%c", FORMAT_STYLE_ITALIC); break; + case LINE_CMD_MONOSPACE: + g_string_append_printf(str, "\004%c", + FORMAT_STYLE_MONOSPACE); + break; case LINE_CMD_COLOR0: g_string_append_printf(str, "\004%c%c", '0', FORMAT_COLOR_NOCHANGE); diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index eacfd447..303789a3 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -18,6 +18,7 @@ enum { LINE_CMD_BLINK, /* enable/disable blink */ LINE_CMD_BOLD, /* enable/disable bold */ LINE_CMD_ITALIC, /* enable/disable italic */ + LINE_CMD_MONOSPACE, /* enable/disable monospace (gui only) */ LINE_COLOR_EXT, /* extended color */ LINE_COLOR_EXT_BG, /* extended bg */ #ifdef TERM_TRUECOLOR From b03805eeb916712815971ac6bcfffe10cc16711f Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 4 Nov 2014 12:08:27 +0100 Subject: [PATCH 0003/1495] reimplement format and length logic for the entry prompt --- src/fe-common/core/printtext.c | 12 ++++++++++++ src/fe-common/core/printtext.h | 1 + src/fe-text/gui-entry.c | 32 ++++++++++++++++++++++++++++++-- src/fe-text/gui-printtext.c | 10 ++++++++++ src/fe-text/gui-printtext.h | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 466a2825..ba6f3242 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -413,6 +413,18 @@ void printtext_gui(const char *text) g_free(str); } +/* Like printtext_gui(), but don't expand % codes. */ +void printtext_gui_internal(const char *str) +{ + TEXT_DEST_REC dest; + + g_return_if_fail(str != NULL); + + memset(&dest, 0, sizeof(dest)); + + format_send_to_gui(&dest, str); +} + static void msg_beep_check(TEXT_DEST_REC *dest) { if (dest->level != 0 && (dest->level & MSGLEVEL_NO_ACT) == 0 && diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index 66ba28f4..ab8dfac1 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -23,6 +23,7 @@ void printtext_dest(TEXT_DEST_REC *dest, const char *text, ...); /* only GUI should call these - used for printing text to somewhere else than windows */ void printtext_gui(const char *text); +void printtext_gui_internal(const char *str); void printformat_module_gui(const char *module, int formatnum, ...); void printformat_module_gui_args(const char *module, int formatnum, va_list va); diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 17a7c507..309f3a68 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -26,6 +26,7 @@ #include "gui-entry.h" #include "gui-printtext.h" #include "term.h" +#include "recode.h" #undef i_toupper #undef i_tolower @@ -345,6 +346,33 @@ void gui_entry_set_active(GUI_ENTRY_REC *entry) } } +/* Return screen length of plain string */ +static int scrlen_str(const char *str) +{ + int len = 0; + char *stripped; + g_return_val_if_fail(str != NULL, 0); + + str = stripped = strip_codes(str); + if (is_utf8() && g_utf8_validate(str, -1, NULL)) { + + while (*str != '\0') { + gunichar c; + + c = g_utf8_get_char(str); + str = g_utf8_next_char(str); + + len += unichar_isprint(c) ? mk_wcwidth(c) : 1; + } + + } else { + len = strlen(str); + } + + g_free(stripped); + return len; +} + void gui_entry_set_prompt(GUI_ENTRY_REC *entry, const char *str) { int oldlen; @@ -355,11 +383,11 @@ void gui_entry_set_prompt(GUI_ENTRY_REC *entry, const char *str) if (str != NULL) { g_free_not_null(entry->prompt); entry->prompt = g_strdup(str); - entry->promptlen = format_get_length(str); + entry->promptlen = scrlen_str(str); } if (entry->prompt != NULL) - gui_printtext(entry->xpos, entry->ypos, entry->prompt); + gui_printtext_internal(entry->xpos, entry->ypos, entry->prompt); if (entry->promptlen != oldlen) { gui_entry_fix_cursor(entry); diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 547d39c9..83b26e82 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -109,6 +109,16 @@ void gui_printtext(int xpos, int ypos, const char *str) next_xpos = next_ypos = -1; } +void gui_printtext_internal(int xpos, int ypos, const char *str) +{ + next_xpos = xpos; + next_ypos = ypos; + + printtext_gui_internal(str); + + next_xpos = next_ypos = -1; +} + void gui_printtext_after_time(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str, time_t time) { GUI_WINDOW_REC *gui; diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index 33b7ce6f..d2671497 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -17,6 +17,7 @@ void gui_set_default_indent(const char *name); INDENT_FUNC get_default_indent_func(void); void gui_printtext(int xpos, int ypos, const char *str); +void gui_printtext_internal(int xpos, int ypos, const char *str); void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str); void gui_printtext_after_time(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str, time_t time); From dee7825f05e0e558020fabe2e536e2b5d4df8050 Mon Sep 17 00:00:00 2001 From: Alexandre Morignot Date: Tue, 10 Feb 2015 16:37:41 +0100 Subject: [PATCH 0004/1495] handle an already used nick different from the one we send --- src/irc/core/irc-nicklist.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 5438509e..a006a3cb 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -343,7 +343,7 @@ static void event_nick_invalid(IRC_SERVER_REC *server, const char *data) static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) { - char *str, *cmd; + char *str, *cmd, *params, *nick; int n; g_return_if_fail(data != NULL); @@ -353,6 +353,14 @@ static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) return; } + params = event_get_params(data, 2, NULL, &nick); + if (g_ascii_strcasecmp(server->nick, nick) != 0) { + /* the server uses a nick different from the one we send */ + g_free(server->nick); + server->nick = g_strdup(nick); + } + g_free(params); + /* nick already in use - need to change it .. */ if (g_ascii_strcasecmp(server->nick, server->connrec->nick) == 0 && server->connrec->alternate_nick != NULL && From deb6ca1b1a676fae094253fc55519e2a60c206d1 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 24 Sep 2015 13:03:02 +0200 Subject: [PATCH 0005/1495] Applied patch from fs#275 to make /hilight -mask -line work properly --- src/fe-common/core/fe-messages.c | 16 ++++++++++------ src/fe-common/core/formats.c | 2 ++ src/fe-common/core/formats.h | 6 ++++++ src/fe-common/core/hilight-text.c | 9 ++++----- src/fe-common/core/hilight-text.h | 2 +- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index d09c1b0b..e06a4571 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -175,6 +175,7 @@ static void sig_message_public(SERVER_REC *server, const char *msg, int for_me, print_channel, level; char *nickmode, *color, *freemsg = NULL; HILIGHT_REC *hilight; + int match_beg = 0, match_end = 0; /* NOTE: this may return NULL if some channel is just closed with /WINDOW CLOSE and server still sends the few last messages */ @@ -187,8 +188,8 @@ static void sig_message_public(SERVER_REC *server, const char *msg, nick_match_msg(chanrec, msg, server->nick) : nick_match_msg_everywhere(chanrec, msg, server->nick); hilight = for_me ? NULL : - hilight_match_nick(server, target, nick, address, MSGLEVEL_PUBLIC, msg); - color = (hilight == NULL) ? NULL : hilight_get_color(hilight); + hilight_match(server, target, nick, address, MSGLEVEL_PUBLIC, msg, &match_beg, &match_end); + color = (hilight == NULL || !hilight->nick) ? NULL : hilight_get_color(hilight); print_channel = chanrec == NULL || !window_item_is_active((WI_ITEM_REC *) chanrec); @@ -214,10 +215,13 @@ static void sig_message_public(SERVER_REC *server, const char *msg, if (printnick == NULL) printnick = nick; + TEXT_DEST_REC dest; + format_create_dest(&dest, server, target, level, NULL); + dest.hilight = hilight; + dest.match_beg = match_beg; + dest.match_end = match_end; if (color != NULL) { /* highlighted nick */ - TEXT_DEST_REC dest; - format_create_dest(&dest, server, target, level, NULL); hilight_update_text_dest(&dest,hilight); if (!print_channel) /* message to active channel in window */ printformat_dest(&dest, TXT_PUBMSG_HILIGHT, color, @@ -228,11 +232,11 @@ static void sig_message_public(SERVER_REC *server, const char *msg, nickmode); } else { if (!print_channel) - printformat(server, target, level, + printformat_dest(&dest, for_me ? TXT_PUBMSG_ME : TXT_PUBMSG, printnick, msg, nickmode); else - printformat(server, target, level, + printformat_dest(&dest, for_me ? TXT_PUBMSG_ME_CHANNEL : TXT_PUBMSG_CHANNEL, printnick, target, msg, nickmode); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index ccf48394..b95b3966 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -416,6 +416,8 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, dest->server_tag = server != NULL ? SERVER(server)->tag : server_tag; dest->target = target; dest->level = level; + dest->match_beg = 0; + dest->match_end = 0; dest->window = window != NULL ? window : window_find_closest(server, target, level); } diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 07e1832c..484105f9 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -45,6 +45,9 @@ struct _FORMAT_REC { #define PRINT_FLAG_SET_SERVERTAG 0x0010 #define PRINT_FLAG_UNSET_SERVERTAG 0x0020 +// FIXME: sould use better +typedef struct _HILIGHT_REC HILIGHT_REC; + typedef struct _TEXT_DEST_REC { WINDOW_REC *window; SERVER_REC *server; @@ -52,6 +55,9 @@ typedef struct _TEXT_DEST_REC { const char *target; int level; + HILIGHT_REC *hilight; + int match_beg; + int match_end; int hilight_priority; char *hilight_color; int flags; diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 87c5d467..c6017d2a 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -325,11 +325,10 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, if (dest->level & MSGLEVEL_NOHILIGHT) return; - hilight_start = hilight_end = 0; - hilight = hilight_match(dest->server, dest->target, - NULL, NULL, dest->level, stripped, - &hilight_start, - &hilight_end); + hilight_start = dest->match_beg; + hilight_end = dest->match_end; + hilight = dest->hilight; + if (hilight == NULL) return; diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 1692b8ab..fa083882 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -7,7 +7,7 @@ #include "formats.h" -typedef struct _HILIGHT_REC HILIGHT_REC; +//typedef struct _HILIGHT_REC HILIGHT_REC; struct _HILIGHT_REC { char *text; From 72ac27e5a030b7c9207ecd00b8c2d092d28da644 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 8 Sep 2015 00:40:25 +0200 Subject: [PATCH 0006/1495] Implement the bracketed paste mode As an alternative method of paste detection, more reliable but might not be supported by all the VTs. --- src/fe-text/gui-readline.c | 42 +++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index ec61e317..b8f3c1c7 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -37,6 +37,7 @@ #include "gui-windows.h" #include "utf8.h" +#include #include typedef void (*ENTRY_REDIRECT_KEY_FUNC) (int key, void *data, SERVER_REC *server, WI_ITEM_REC *item); @@ -65,6 +66,13 @@ static char *paste_old_prompt; static int paste_prompt, paste_line_count; static int paste_join_multiline; static int paste_timeout_id; +static int paste_bracketed_mode; + +/* Terminal sequences that surround the input when the terminal has the + * bracketed paste mode active. Fror more details see + * https://cirw.in/blog/bracketed-paste */ +static const unichar bp_start[] = { 0x1b, '[', '2', '0', '0', '~' }; +static const unichar bp_end[] = { 0x1b, '[', '2', '0', '1', '~' }; static void sig_input(void); @@ -647,12 +655,43 @@ static void sig_input(void) unichar key; term_gets(buffer, &line_count); key = g_array_index(buffer, unichar, 0); + /* Either Ctrl-k or Ctrl-c is pressed */ if (key == 11 || key == 3) paste_flush(key == 11); g_array_free(buffer, TRUE); } else { term_gets(paste_buffer, &paste_line_count); - if (paste_detect_time > 0 && paste_buffer->len >= 3) { + + /* use the bracketed paste mode to detect when the user has + * pasted some text into the field. */ + if (paste_buffer->len > 12) { + /* try to find the start/end sequence */ + int seq_start = memmem(paste_buffer->data, + paste_buffer->len * g_array_get_element_size(paste_buffer), + bp_start, sizeof(bp_start)) != NULL, + seq_end = memmem(paste_buffer->data, + paste_buffer->len * g_array_get_element_size(paste_buffer), + bp_end, sizeof(bp_end)) != NULL; + + g_warning("found sequences : start %d end %d", seq_start, seq_end); + + if (seq_start) { + paste_bracketed_mode = TRUE; + /* remove the leading sequence chars */ + memmove(paste_buffer->data, paste_buffer->data + sizeof(bp_start), + paste_buffer->len * g_array_get_element_size(paste_buffer) - sizeof(bp_start)); + g_array_set_size(paste_buffer, paste_buffer->len - 6); + } + + if (seq_end) { + paste_bracketed_mode = FALSE; + /* remove the trailing sequence chars */ + g_array_set_size(paste_buffer, paste_buffer->len - 6); + /* decide what to do with the buffer */ + paste_timeout(NULL); + } + } + else if (paste_detect_time > 0 && paste_buffer->len >= 3) { if (paste_timeout_id != -1) g_source_remove(paste_timeout_id); paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL); @@ -945,6 +984,7 @@ void gui_readline_init(void) paste_buffer = g_array_new(FALSE, FALSE, sizeof(unichar)); paste_old_prompt = NULL; paste_timeout_id = -1; + paste_bracketed_mode = FALSE; g_get_current_time(&last_keypress); input_listen_init(STDIN_FILENO); From f1eead7b4a7cdcae6d71dba6e97d38e9d34fcf95 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 8 Sep 2015 00:48:13 +0200 Subject: [PATCH 0007/1495] Toggles --- src/fe-text/gui-readline.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index b8f3c1c7..90399711 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -66,6 +66,7 @@ static char *paste_old_prompt; static int paste_prompt, paste_line_count; static int paste_join_multiline; static int paste_timeout_id; +static int paste_use_bracketed_mode; static int paste_bracketed_mode; /* Terminal sequences that surround the input when the terminal has the @@ -662,11 +663,11 @@ static void sig_input(void) } else { term_gets(paste_buffer, &paste_line_count); - /* use the bracketed paste mode to detect when the user has - * pasted some text into the field. */ - if (paste_buffer->len > 12) { + /* use the bracketed paste mode to detect when the user pastes + * some text into the entry */ + if (paste_use_bracketed_mode != FALSE && paste_buffer->len > 12) { /* try to find the start/end sequence */ - int seq_start = memmem(paste_buffer->data, + int seq_start = memmem(paste_buffer->data, paste_buffer->len * g_array_get_element_size(paste_buffer), bp_start, sizeof(bp_start)) != NULL, seq_end = memmem(paste_buffer->data, @@ -678,7 +679,7 @@ static void sig_input(void) if (seq_start) { paste_bracketed_mode = TRUE; /* remove the leading sequence chars */ - memmove(paste_buffer->data, paste_buffer->data + sizeof(bp_start), + memmove(paste_buffer->data, paste_buffer->data + sizeof(bp_start), paste_buffer->len * g_array_get_element_size(paste_buffer) - sizeof(bp_start)); g_array_set_size(paste_buffer, paste_buffer->len - 6); } @@ -969,6 +970,7 @@ static void setup_changed(void) paste_verify_line_count = settings_get_int("paste_verify_line_count"); paste_join_multiline = settings_get_bool("paste_join_multiline"); + paste_use_bracketed_mode = settings_get_bool("paste_use_bracketed_mode"); } void gui_readline_init(void) @@ -990,6 +992,7 @@ void gui_readline_init(void) settings_add_str("history", "scroll_page_count", "/2"); settings_add_time("misc", "paste_detect_time", "5msecs"); + settings_add_bool("misc", "paste_use_bracketed_mode", FALSE); /* NOTE: function keys can generate at least 5 characters long keycodes. this must be larger to allow them to work. */ settings_add_int("misc", "paste_verify_line_count", 5); From 15dad291c7829c4ae7855880654b94d6edb4f17f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 8 Sep 2015 00:55:34 +0200 Subject: [PATCH 0008/1495] Replace some hairy logic with g_array_remove_range In the hope it'll do the same under the hood. --- src/fe-text/gui-readline.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 90399711..c4c0064e 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -679,9 +679,7 @@ static void sig_input(void) if (seq_start) { paste_bracketed_mode = TRUE; /* remove the leading sequence chars */ - memmove(paste_buffer->data, paste_buffer->data + sizeof(bp_start), - paste_buffer->len * g_array_get_element_size(paste_buffer) - sizeof(bp_start)); - g_array_set_size(paste_buffer, paste_buffer->len - 6); + g_array_remove_range(paste_buffer, 0, 6); } if (seq_end) { From 4764b102ff274f4a8695ced2ff2ebb39bf8d7bc2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 9 Sep 2015 22:35:11 +0200 Subject: [PATCH 0009/1495] Enable the bracketed paste mode on demand --- src/fe-text/gui-readline.c | 3 +++ src/fe-text/term-terminfo.c | 8 ++++++++ src/fe-text/term.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index c4c0064e..91dec4ea 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -969,6 +969,9 @@ static void setup_changed(void) paste_verify_line_count = settings_get_int("paste_verify_line_count"); paste_join_multiline = settings_get_bool("paste_join_multiline"); paste_use_bracketed_mode = settings_get_bool("paste_use_bracketed_mode"); + + /* Enable the bracketed paste mode on demand */ + term_set_bracketed_paste_mode(paste_use_bracketed_mode); } void gui_readline_init(void) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index ded79c28..9376bda8 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -689,3 +689,11 @@ void term_gets(GArray *buffer, int *line_count) } } } + +void term_set_bracketed_paste_mode(int enable) +{ + if (enable) + tputs("\e[?2004h", 0, term_putchar); + else + tputs("\e[?2004l", 0, term_putchar); +} diff --git a/src/fe-text/term.h b/src/fe-text/term.h index cdcc787a..692ce9c5 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -94,6 +94,8 @@ void term_refresh(TERM_WINDOW *window); void term_stop(void); +void term_set_bracketed_paste_mode(int enable); + /* keyboard input handling */ void term_set_input_type(int type); void term_gets(GArray *buffer, int *line_count); From 6888fc5fc74936af74fd30042e45652951648ea4 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 9 Sep 2015 22:41:17 +0200 Subject: [PATCH 0010/1495] Get rid of the non-portable memmem The sequences we're after are found at the beginning or at the end of the buffer, there's no need to scan the whole thing. --- src/fe-text/gui-readline.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 91dec4ea..87c824cf 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -666,15 +666,11 @@ static void sig_input(void) /* use the bracketed paste mode to detect when the user pastes * some text into the entry */ if (paste_use_bracketed_mode != FALSE && paste_buffer->len > 12) { - /* try to find the start/end sequence */ - int seq_start = memmem(paste_buffer->data, - paste_buffer->len * g_array_get_element_size(paste_buffer), - bp_start, sizeof(bp_start)) != NULL, - seq_end = memmem(paste_buffer->data, - paste_buffer->len * g_array_get_element_size(paste_buffer), - bp_end, sizeof(bp_end)) != NULL; - - g_warning("found sequences : start %d end %d", seq_start, seq_end); + /* try to find the start/end sequence, we know that we + * either find those at the start/end of the buffer or + * we don't find those at all. */ + int seq_start = !memcmp(paste_buffer->data, bp_start, sizeof(bp_start)), + seq_end = !memcmp(paste_buffer->data + paste_buffer->len * g_array_get_element_size(paste_buffer) - sizeof(bp_end), bp_end, sizeof(bp_end)); if (seq_start) { paste_bracketed_mode = TRUE; From 9a6b2dedcce165211892b39cf7455314dfde57fb Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 17 Sep 2015 00:52:55 -0300 Subject: [PATCH 0011/1495] Improve bracketed paste start/end detection - Use a keybinding to detect the start of a bracketed paste - Iterate over the paste buffer looking for the end marker --- src/fe-text/gui-readline.c | 50 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 87c824cf..51b9f758 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -665,37 +665,44 @@ static void sig_input(void) /* use the bracketed paste mode to detect when the user pastes * some text into the entry */ - if (paste_use_bracketed_mode != FALSE && paste_buffer->len > 12) { - /* try to find the start/end sequence, we know that we - * either find those at the start/end of the buffer or - * we don't find those at all. */ - int seq_start = !memcmp(paste_buffer->data, bp_start, sizeof(bp_start)), - seq_end = !memcmp(paste_buffer->data + paste_buffer->len * g_array_get_element_size(paste_buffer) - sizeof(bp_end), bp_end, sizeof(bp_end)); + if (paste_bracketed_mode) { + int i; + int len = paste_buffer->len - G_N_ELEMENTS(bp_end); + unichar *ptr = (unichar *) paste_buffer->data; - if (seq_start) { - paste_bracketed_mode = TRUE; - /* remove the leading sequence chars */ - g_array_remove_range(paste_buffer, 0, 6); + if (len <= 0) { + return; } - if (seq_end) { - paste_bracketed_mode = FALSE; - /* remove the trailing sequence chars */ - g_array_set_size(paste_buffer, paste_buffer->len - 6); - /* decide what to do with the buffer */ - paste_timeout(NULL); + for (i = 0; i <= len; i++, ptr++) { + if (ptr[0] == bp_end[0] && !memcmp(ptr, bp_end, sizeof(bp_end))) { + /* remove the trailing sequence chars */ + g_array_set_size(paste_buffer, i); + + /* decide what to do with the buffer */ + paste_timeout(NULL); + + paste_bracketed_mode = FALSE; + break; + } } } else if (paste_detect_time > 0 && paste_buffer->len >= 3) { if (paste_timeout_id != -1) g_source_remove(paste_timeout_id); paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL); - } else { + } else if (!paste_bracketed_mode) { int i; for (i = 0; i < paste_buffer->len; i++) { unichar key = g_array_index(paste_buffer, unichar, i); signal_emit("gui key pressed", 1, GINT_TO_POINTER(key)); + + if (paste_bracketed_mode) { + /* just enabled by the signal, remove what was processed so far */ + g_array_remove_range(paste_buffer, 0, i + 1); + return; + } } g_array_set_size(paste_buffer, 0); paste_line_count = 0; @@ -703,6 +710,11 @@ static void sig_input(void) } } +static void key_paste_start(void) +{ + paste_bracketed_mode = TRUE; +} + time_t get_idle_time(void) { return last_keypress.tv_sec; @@ -1060,6 +1072,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("paste_start", "Bracketed paste start", "meta2-200~", "paste_start", (SIGNAL_FUNC) key_paste_start); + /* 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); @@ -1155,6 +1169,8 @@ void gui_readline_deinit(void) key_configure_freeze(); + key_unbind("paste_start", (SIGNAL_FUNC) key_paste_start); + key_unbind("backward_character", (SIGNAL_FUNC) key_backward_character); key_unbind("forward_character", (SIGNAL_FUNC) key_forward_character); key_unbind("backward_word", (SIGNAL_FUNC) key_backward_word); From 52729ca3da6ca594d710f58f252ac6cd6952fab0 Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 17 Sep 2015 00:54:13 -0300 Subject: [PATCH 0012/1495] Save the part of the paste buffer after the bp_end marker for later Also move relevant code to a paste_bracketed_end() function --- src/fe-text/gui-readline.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 51b9f758..61cdad1a 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -61,6 +61,7 @@ static int paste_detect_time, paste_verify_line_count; static char *paste_entry; static int paste_entry_pos; static GArray *paste_buffer; +static GArray *paste_buffer_rest; static char *paste_old_prompt; static int paste_prompt, paste_line_count; @@ -331,6 +332,12 @@ static void paste_flush(int send) paste_send(); g_array_set_size(paste_buffer, 0); + /* re-add anything that may have been after the bracketed paste end */ + if (paste_buffer_rest->len) { + g_array_append_vals(paste_buffer, paste_buffer_rest->data, paste_buffer_rest->len); + g_array_set_size(paste_buffer_rest, 0); + } + gui_entry_set_prompt(active_entry, paste_old_prompt == NULL ? "" : paste_old_prompt); g_free(paste_old_prompt); paste_old_prompt = NULL; @@ -643,6 +650,26 @@ static gboolean paste_timeout(gpointer data) return FALSE; } +static void paste_bracketed_end(int i, gboolean rest) +{ + /* if there's stuff after the end bracket, save it for later */ + if (rest) { + unichar *start = ((unichar *) paste_buffer->data) + i + G_N_ELEMENTS(bp_end); + int len = paste_buffer->len - G_N_ELEMENTS(bp_end); + + g_array_set_size(paste_buffer_rest, 0); + g_array_append_vals(paste_buffer_rest, start, len); + } + + /* remove the rest, including the trailing sequence chars */ + g_array_set_size(paste_buffer, i); + + /* decide what to do with the buffer */ + paste_timeout(NULL); + + paste_bracketed_mode = FALSE; +} + static void sig_input(void) { if (!active_entry) { @@ -676,13 +703,7 @@ static void sig_input(void) for (i = 0; i <= len; i++, ptr++) { if (ptr[0] == bp_end[0] && !memcmp(ptr, bp_end, sizeof(bp_end))) { - /* remove the trailing sequence chars */ - g_array_set_size(paste_buffer, i); - - /* decide what to do with the buffer */ - paste_timeout(NULL); - - paste_bracketed_mode = FALSE; + paste_bracketed_end(i, i != len); break; } } @@ -993,6 +1014,7 @@ void gui_readline_init(void) paste_entry = NULL; paste_entry_pos = 0; paste_buffer = g_array_new(FALSE, FALSE, sizeof(unichar)); + paste_buffer_rest = g_array_new(FALSE, FALSE, sizeof(unichar)); paste_old_prompt = NULL; paste_timeout_id = -1; paste_bracketed_mode = FALSE; @@ -1228,6 +1250,7 @@ void gui_readline_deinit(void) key_unbind("stop_irc", (SIGNAL_FUNC) key_sig_stop); keyboard_destroy(keyboard); g_array_free(paste_buffer, TRUE); + g_array_free(paste_buffer_rest, TRUE); key_configure_thaw(); From 3b01198f0306676425f2bf90db2ca9c7179b014e Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 25 Sep 2015 01:37:06 -0300 Subject: [PATCH 0013/1495] paste_bracketed_end: Fix rest length calculation --- src/fe-text/gui-readline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 61cdad1a..8d571041 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -655,7 +655,7 @@ static void paste_bracketed_end(int i, gboolean rest) /* if there's stuff after the end bracket, save it for later */ if (rest) { unichar *start = ((unichar *) paste_buffer->data) + i + G_N_ELEMENTS(bp_end); - int len = paste_buffer->len - G_N_ELEMENTS(bp_end); + int len = paste_buffer->len - i - G_N_ELEMENTS(bp_end); g_array_set_size(paste_buffer_rest, 0); g_array_append_vals(paste_buffer_rest, start, len); From 79987d87f37f37ce07171ad4c6b94ffbab77b36d Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 25 Sep 2015 02:21:27 -0300 Subject: [PATCH 0014/1495] Send last line of bracketed paste together with the rest --- src/fe-text/gui-readline.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 8d571041..7f1ed9ca 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -69,6 +69,7 @@ static int paste_join_multiline; static int paste_timeout_id; static int paste_use_bracketed_mode; static int paste_bracketed_mode; +static int paste_was_bracketed_mode; /* Terminal sequences that surround the input when the terminal has the * bracketed paste mode active. Fror more details see @@ -258,9 +259,16 @@ static void paste_buffer_join_lines(GArray *buf) g_array_set_size(buf, dest - arr); } +static void paste_send_line(char *text) +{ + /* we need to get the current history every time because it might change between calls */ + command_history_add(command_history_current(active_win), text); + + signal_emit("send command", 3, text, active_win->active_server, active_win->active); +} + static void paste_send(void) { - HISTORY_REC *history; unichar *arr; GString *str; char out[10], *text; @@ -285,11 +293,7 @@ static void paste_send(void) } text = gui_entry_get_text(active_entry); - history = command_history_current(active_win); - command_history_add(history, text); - - signal_emit("send command", 3, text, - active_win->active_server, active_win->active); + paste_send_line(text); g_free(text); } @@ -297,12 +301,7 @@ static void paste_send(void) str = g_string_new(NULL); for (; i < paste_buffer->len; i++) { if (arr[i] == '\r' || arr[i] == '\n') { - history = command_history_current(active_win); - command_history_add(history, str->str); - - signal_emit("send command", 3, str->str, - active_win->active_server, - active_win->active); + paste_send_line(str->str); g_string_truncate(str, 0); } else if (active_entry->utf8) { out[g_unichar_to_utf8(arr[i], out)] = '\0'; @@ -316,7 +315,14 @@ static void paste_send(void) } } - gui_entry_set_text(active_entry, str->str); + if (paste_was_bracketed_mode) { + /* the text before the bracket end should be sent along with the rest */ + paste_send_line(str->str); + gui_entry_set_text(active_entry, ""); + } else { + gui_entry_set_text(active_entry, str->str); + } + g_string_free(str, TRUE); } @@ -632,6 +638,8 @@ static void key_delete_to_next_space(void) static gboolean paste_timeout(gpointer data) { + paste_was_bracketed_mode = paste_bracketed_mode; + if (paste_line_count == 0) { int i; From 83f9772e213b6b1e181338738c2997150162c871 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 25 Sep 2015 02:23:38 -0300 Subject: [PATCH 0015/1495] Fix some minor style issues --- src/fe-text/gui-readline.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 7f1ed9ca..9b635139 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -710,13 +710,12 @@ static void sig_input(void) } for (i = 0; i <= len; i++, ptr++) { - if (ptr[0] == bp_end[0] && !memcmp(ptr, bp_end, sizeof(bp_end))) { + if (ptr[0] == bp_end[0] && memcmp(ptr, bp_end, sizeof(bp_end)) == 0) { paste_bracketed_end(i, i != len); break; } } - } - else if (paste_detect_time > 0 && paste_buffer->len >= 3) { + } else if (paste_detect_time > 0 && paste_buffer->len >= 3) { if (paste_timeout_id != -1) g_source_remove(paste_timeout_id); paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL); From 7d062a313add81584608f2b0abf086f2b73e8098 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 25 Sep 2015 02:27:59 -0300 Subject: [PATCH 0016/1495] Create paste_bracketed_middle() function to handle small pastes "Small" as in ending in the same sig_input() call where they started --- src/fe-text/gui-readline.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 9b635139..5d859ede 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -678,6 +678,24 @@ static void paste_bracketed_end(int i, gboolean rest) paste_bracketed_mode = FALSE; } +static void paste_bracketed_middle() +{ + int i; + int len = paste_buffer->len - G_N_ELEMENTS(bp_end); + unichar *ptr = (unichar *) paste_buffer->data; + + if (len <= 0) { + return; + } + + for (i = 0; i <= len; i++, ptr++) { + if (ptr[0] == bp_end[0] && memcmp(ptr, bp_end, sizeof(bp_end)) == 0) { + paste_bracketed_end(i, i != len); + break; + } + } +} + static void sig_input(void) { if (!active_entry) { @@ -701,20 +719,8 @@ static void sig_input(void) /* use the bracketed paste mode to detect when the user pastes * some text into the entry */ if (paste_bracketed_mode) { - int i; - int len = paste_buffer->len - G_N_ELEMENTS(bp_end); - unichar *ptr = (unichar *) paste_buffer->data; + paste_bracketed_middle(); - if (len <= 0) { - return; - } - - for (i = 0; i <= len; i++, ptr++) { - if (ptr[0] == bp_end[0] && memcmp(ptr, bp_end, sizeof(bp_end)) == 0) { - paste_bracketed_end(i, i != len); - break; - } - } } else if (paste_detect_time > 0 && paste_buffer->len >= 3) { if (paste_timeout_id != -1) g_source_remove(paste_timeout_id); @@ -729,6 +735,9 @@ static void sig_input(void) if (paste_bracketed_mode) { /* just enabled by the signal, remove what was processed so far */ g_array_remove_range(paste_buffer, 0, i + 1); + + /* handle single-line / small pastes here */ + paste_bracketed_middle(); return; } } From c721d57688e8f5413df7c179eac54c315343fbb0 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 25 Sep 2015 03:09:14 -0300 Subject: [PATCH 0017/1495] Handle a paste start marker right after an end one (ignore both) This actually workarounds a bug with the "st" terminal, for which i've already submitted a patch, but irssi needs to be able to handle it decently too. --- src/fe-text/gui-readline.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 5d859ede..4616e919 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -681,7 +681,8 @@ static void paste_bracketed_end(int i, gboolean rest) static void paste_bracketed_middle() { int i; - int len = paste_buffer->len - G_N_ELEMENTS(bp_end); + int marklen = G_N_ELEMENTS(bp_end); + int len = paste_buffer->len - marklen; unichar *ptr = (unichar *) paste_buffer->data; if (len <= 0) { @@ -690,6 +691,23 @@ static void paste_bracketed_middle() for (i = 0; i <= len; i++, ptr++) { if (ptr[0] == bp_end[0] && memcmp(ptr, bp_end, sizeof(bp_end)) == 0) { + + /* if there are at least 6 bytes after the end, + * check for another start marker right afterwards */ + if (i <= (len - marklen) && + memcmp(ptr + marklen, bp_start, sizeof(bp_start)) == 0) { + + /* remove both markers*/ + g_array_remove_range(paste_buffer, i, marklen * 2); + len -= marklen * 2; + + /* go one step back */ + if (i > 0) { + i--; + ptr--; + } + continue; + } paste_bracketed_end(i, i != len); break; } From 7866d2bcd6797b8279238ffb2f710bd9ea599cc8 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 25 Sep 2015 03:22:02 -0300 Subject: [PATCH 0018/1495] Handle empty bracketed pastes (or sequences of those) Both cases were off-by-one mistakes erring on the side of being too conservative. This fixes these two harmless issues: - For a single empty paste, it required another keystroke before processing it - For a sequence of themcase, a single '~' was left in the input --- src/fe-text/gui-readline.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 4616e919..6e169b93 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -685,7 +685,7 @@ static void paste_bracketed_middle() int len = paste_buffer->len - marklen; unichar *ptr = (unichar *) paste_buffer->data; - if (len <= 0) { + if (len < 0) { return; } @@ -702,10 +702,8 @@ static void paste_bracketed_middle() len -= marklen * 2; /* go one step back */ - if (i > 0) { - i--; - ptr--; - } + i--; + ptr--; continue; } paste_bracketed_end(i, i != len); From 2ad6bb12955b3e9bfa43628e6dbfc984537f8b26 Mon Sep 17 00:00:00 2001 From: isundil Date: Thu, 1 Oct 2015 21:14:30 +0200 Subject: [PATCH 0019/1495] Fix #45 Make it easy to delete default channels, servers and networks Removing network will now also remove all attached servers --- src/core/servers-setup.c | 18 ++++++++++++++++++ src/core/servers-setup.h | 4 ++++ src/fe-common/irc/fe-ircnet.c | 6 ++++++ 3 files changed, 28 insertions(+) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 90a447d4..74b818e7 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -333,6 +333,24 @@ server_create_conn(int chat_type, const char *dest, int port, chatnet, password, nick); } +GSList *server_setup_find_chatnet(const char *chatnet) +{ + GSList *servers; + GSList *tmp; + + g_return_val_if_fail(chatnet != NULL, NULL); + + servers = NULL; + for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { + SERVER_SETUP_REC *rec = tmp->data; + + if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0) + servers = g_slist_append(servers, rec); + } + + return servers; +} + /* Find matching server from setup. Try to find record with a same port, but fallback to any server with the same address. */ SERVER_SETUP_REC *server_setup_find(const char *address, int port, diff --git a/src/core/servers-setup.h b/src/core/servers-setup.h index f7601a68..dffaec02 100644 --- a/src/core/servers-setup.h +++ b/src/core/servers-setup.h @@ -36,6 +36,10 @@ server_create_conn(int chat_type, const char *dest, int port, SERVER_SETUP_REC *server_setup_find(const char *address, int port, const char *chatnet); +/* Find all servers matching chatnet. + Return a list of SERVER_SETUP_REC */ +GSList *server_setup_find_chatnet(const char *chatnet); + void server_setup_add(SERVER_SETUP_REC *rec); void server_setup_remove(SERVER_SETUP_REC *rec); diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c index bb0af313..1760b966 100644 --- a/src/fe-common/irc/fe-ircnet.c +++ b/src/fe-common/irc/fe-ircnet.c @@ -176,6 +176,8 @@ static void cmd_network_add(const char *data) static void cmd_network_remove(const char *data) { IRC_CHATNET_REC *rec; + GSList *servers; + GSList *tmp; if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -183,6 +185,10 @@ static void cmd_network_remove(const char *data) if (rec == NULL) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_NOT_FOUND, data); else { + servers = server_setup_find_chatnet(data); + + for (tmp = servers; tmp != NULL; tmp = tmp->next) + server_setup_remove((SERVER_SETUP_REC *) tmp->data); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_REMOVED, data); chatnet_remove(CHATNET(rec)); } From 6ca7dc68478772258dea114d29625dc2c87999f9 Mon Sep 17 00:00:00 2001 From: isundil Date: Thu, 1 Oct 2015 22:36:02 +0200 Subject: [PATCH 0020/1495] Updated server removal Removing network will also remove attached channels --- src/core/channels-setup.c | 15 +++++++++++++++ src/core/channels-setup.h | 3 +++ src/core/servers-setup.c | 33 +++++++++++++++------------------ src/core/servers-setup.h | 7 +++---- src/fe-common/irc/fe-ircnet.c | 10 ++++------ 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index b2d971dd..2902ef8e 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -86,6 +86,21 @@ static void channel_setup_destroy(CHANNEL_SETUP_REC *channel) g_free(channel); } +void channel_setup_remove_chatnet(const char *chatnet) +{ + GSList *tmp, *next; + + g_return_if_fail(chatnet != NULL); + + for (tmp = setupchannels; tmp != NULL; tmp = next) { + CHANNEL_SETUP_REC *rec = tmp->data; + + next = tmp->next; + if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0) + channel_setup_remove(rec); + } +} + void channel_setup_remove(CHANNEL_SETUP_REC *channel) { channel_config_remove(channel); diff --git a/src/core/channels-setup.h b/src/core/channels-setup.h index 61b828b2..3bb7da7f 100644 --- a/src/core/channels-setup.h +++ b/src/core/channels-setup.h @@ -21,6 +21,9 @@ void channels_setup_deinit(void); void channel_setup_create(CHANNEL_SETUP_REC *channel); void channel_setup_remove(CHANNEL_SETUP_REC *channel); +/* Remove channels attached to chatnet */ +void channel_setup_remove_chatnet(const char *chatnet); + CHANNEL_SETUP_REC *channel_setup_find(const char *channel, const char *chatnet); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 74b818e7..cd5fe406 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -333,24 +333,6 @@ server_create_conn(int chat_type, const char *dest, int port, chatnet, password, nick); } -GSList *server_setup_find_chatnet(const char *chatnet) -{ - GSList *servers; - GSList *tmp; - - g_return_val_if_fail(chatnet != NULL, NULL); - - servers = NULL; - for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { - SERVER_SETUP_REC *rec = tmp->data; - - if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0) - servers = g_slist_append(servers, rec); - } - - return servers; -} - /* Find matching server from setup. Try to find record with a same port, but fallback to any server with the same address. */ SERVER_SETUP_REC *server_setup_find(const char *address, int port, @@ -523,6 +505,21 @@ void server_setup_add(SERVER_SETUP_REC *rec) signal_emit("server setup updated", 1, rec); } +void server_setup_remove_chatnet(const char *chatnet) +{ + GSList *tmp, *next; + + g_return_val_if_fail(chatnet != NULL, NULL); + + for (tmp = setupservers; tmp != NULL; tmp = next) { + SERVER_SETUP_REC *rec = tmp->data; + + next = tmp->next; + if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0) + server_setup_remove(rec); + } +} + void server_setup_remove(SERVER_SETUP_REC *rec) { server_setup_remove_config(rec); diff --git a/src/core/servers-setup.h b/src/core/servers-setup.h index dffaec02..e7ff7abf 100644 --- a/src/core/servers-setup.h +++ b/src/core/servers-setup.h @@ -36,13 +36,12 @@ server_create_conn(int chat_type, const char *dest, int port, SERVER_SETUP_REC *server_setup_find(const char *address, int port, const char *chatnet); -/* Find all servers matching chatnet. - Return a list of SERVER_SETUP_REC */ -GSList *server_setup_find_chatnet(const char *chatnet); - void server_setup_add(SERVER_SETUP_REC *rec); void server_setup_remove(SERVER_SETUP_REC *rec); +/* Remove servers attached to chatne */ +void server_setup_remove_chatnet(const char *chatnet); + void servers_setup_init(void); void servers_setup_deinit(void); diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c index 1760b966..4d7037d5 100644 --- a/src/fe-common/irc/fe-ircnet.c +++ b/src/fe-common/irc/fe-ircnet.c @@ -29,6 +29,8 @@ #include "irc-servers.h" #include "irc-chatnets.h" #include "printtext.h" +#include "servers-setup.h" +#include "channels-setup.h" static void cmd_network_list(void) { @@ -176,8 +178,6 @@ static void cmd_network_add(const char *data) static void cmd_network_remove(const char *data) { IRC_CHATNET_REC *rec; - GSList *servers; - GSList *tmp; if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -185,10 +185,8 @@ static void cmd_network_remove(const char *data) if (rec == NULL) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_NOT_FOUND, data); else { - servers = server_setup_find_chatnet(data); - - for (tmp = servers; tmp != NULL; tmp = tmp->next) - server_setup_remove((SERVER_SETUP_REC *) tmp->data); + server_setup_remove_chatnet(data); + channel_setup_remove_chatnet(data); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_REMOVED, data); chatnet_remove(CHATNET(rec)); } From ef1a09b87d5df7fcaeced70e09312c225d99c4b6 Mon Sep 17 00:00:00 2001 From: isundil Date: Thu, 1 Oct 2015 22:53:34 +0200 Subject: [PATCH 0021/1495] Fix return value of server_setup_remove_chatnet --- src/core/servers-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index cd5fe406..771e3999 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -509,7 +509,7 @@ void server_setup_remove_chatnet(const char *chatnet) { GSList *tmp, *next; - g_return_val_if_fail(chatnet != NULL, NULL); + g_return_if_fail(chatnet != NULL); for (tmp = setupservers; tmp != NULL; tmp = next) { SERVER_SETUP_REC *rec = tmp->data; From a475d57183bcbfd6e540dba5cd7894d8c38b53b7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 1 Oct 2015 22:25:40 +0200 Subject: [PATCH 0022/1495] 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 2e860abd2b8b3a30f74005450830c34a318b64a3 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 2 Oct 2015 14:04:04 +0200 Subject: [PATCH 0023/1495] 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 0024/1495] 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 0025/1495] 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 0026/1495] 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 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 0027/1495] 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 0028/1495] 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 0029/1495] 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 0030/1495] 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 0031/1495] 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 3c351ba018703de0639d64030c07aeba02962799 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 27 Jun 2015 11:33:55 -0300 Subject: [PATCH 0032/1495] Initial irssiproxy SSL support Patch by "Christian Sachs" from FS#645, rebased to current head. http://bugs.irssi.org/index.php?do=details&task_id=645 --- src/irc/proxy/dump.c | 40 +++++++++++++++- src/irc/proxy/listen.c | 101 ++++++++++++++++++++++++++++++++++++++--- src/irc/proxy/module.h | 3 ++ src/irc/proxy/proxy.c | 16 ++++++- src/irc/proxy/proxy.h | 17 +++++++ 5 files changed, 167 insertions(+), 10 deletions(-) diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c index e39c21a6..0ca9ebb4 100644 --- a/src/irc/proxy/dump.c +++ b/src/irc/proxy/dump.c @@ -29,6 +29,42 @@ #include "irc-channels.h" #include "irc-nicklist.h" #include "modes.h" +#include "line-split.h" + +void proxy_send(CLIENT_REC *client, char *d, int l) +{ +#ifdef HAVE_OPENSSL + if(client->listen->use_ssl) { + SSL_write(client->ssl, d, l); + } else +#endif + net_sendbuffer_send(client->handle, d, l); +} + +int proxy_readline(CLIENT_REC *client, char **str) +{ +#ifdef HAVE_OPENSSL + if(client->listen->use_ssl) { + char tmpbuf[2048]; + int recvlen = 0; + + recvlen = SSL_read(client->ssl, tmpbuf, sizeof(tmpbuf)); + if(recvlen > 0) { + return line_split(tmpbuf, recvlen, str, &client->handle->readbuffer); + } else { + int err; + err = SSL_get_error(client->ssl, recvlen); + /* READ/WRITE are not really errors, they just indicate that atm + OpenSSL is waiting for more data */ + if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { + return line_split(tmpbuf, 0, str, &client->handle->readbuffer); + } + return recvlen; /* if any other error occurs, this will quit the connection */ + } + } else +#endif + return net_sendbuffer_receive_line(client->handle, str, 1); +} void proxy_outdata(CLIENT_REC *client, const char *data, ...) { @@ -41,7 +77,7 @@ void proxy_outdata(CLIENT_REC *client, const char *data, ...) va_start(args, data); str = g_strdup_vprintf(data, args); - net_sendbuffer_send(client->handle, str, strlen(str)); + proxy_send(client, str, strlen(str)); g_free(str); va_end(args); @@ -65,7 +101,7 @@ void proxy_outdata_all(IRC_SERVER_REC *server, const char *data, ...) CLIENT_REC *rec = tmp->data; if (rec->connected && rec->server == server) - net_sendbuffer_send(rec->handle, str, len); + proxy_send(rec, str, len); } g_free(str); diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index dcc94e6b..55d66efb 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -50,6 +50,11 @@ static void remove_client(CLIENT_REC *rec) printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE, "Proxy: Client %s:%d disconnected", rec->host, rec->port); +#ifdef HAVE_OPENSSL + if(rec->listen->use_ssl) { + SSL_free(rec->ssl); + } +#endif g_free(rec->proxy_address); net_sendbuffer_destroy(rec->handle, TRUE); g_source_remove(rec->recv_tag); @@ -133,6 +138,13 @@ static void handle_client_connect_cmd(CLIENT_REC *client, "Proxy: Client %s:%d connected", client->host, client->port); client->connected = TRUE; +#ifdef HAVE_OPENSSL + if(client->listen->use_ssl) { + printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + "Proxy: Client connected from %s using encryption %s and logged in!", client->host, SSL_get_cipher(client->ssl)); + } +#endif + proxy_dump_data(client); } } @@ -310,7 +322,7 @@ static void sig_listen_client(CLIENT_REC *client) g_return_if_fail(client != NULL); while (g_slist_find(proxy_clients, client) != NULL) { - ret = net_sendbuffer_receive_line(client->handle, &str, 1); + ret = proxy_readline(client, &str); if (ret == -1) { /* connection lost */ remove_client(client); @@ -350,6 +362,26 @@ static void sig_listen(LISTEN_REC *listen) net_ip2host(&ip, host); sendbuf = net_sendbuffer_create(handle, 0); rec = g_new0(CLIENT_REC, 1); + +#ifdef HAVE_OPENSSL + if(listen->use_ssl) { + rec->ssl = SSL_new(listen->ssl_ctx); + SSL_set_fd(rec->ssl, g_io_channel_unix_get_fd(handle)); + int sslerror = SSL_accept(rec->ssl); /* handle error! */ + if(sslerror <= 0) { + /* The Handshake might take longer and the client might not be ready yet + so if such an error occurs, we just ignore it, SSL_read and SSL_write + should continue with the handshake. */ + if(SSL_get_error(rec->ssl, sslerror) != SSL_ERROR_WANT_READ) { + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, + "Proxy: An error occured while accepting SSL connection!"); + g_free(rec); + return; + } + } + } +#endif + rec->listen = listen; rec->handle = sendbuf; rec->host = g_strdup(host); @@ -416,7 +448,7 @@ static void sig_server_event(IRC_SERVER_REC *server, const char *line, if (sscanf(signal+6, "%p", &client) == 1) { /* send it to specific client only */ if (g_slist_find(proxy_clients, client) != NULL) - net_sendbuffer_send(((CLIENT_REC *) client)->handle, next_line->str, next_line->len); + proxy_send((CLIENT_REC *) client, next_line->str, next_line->len); g_free(event); signal_stop(); return; @@ -433,7 +465,7 @@ static void sig_server_event(IRC_SERVER_REC *server, const char *line, if (rec->want_ctcp == 1) { /* only CTCP for the chatnet where client is connected to will be forwarded */ if (strstr(rec->proxy_address, server->connrec->chatnet) != NULL) { - net_sendbuffer_send(rec->handle, + proxy_send(rec, next_line->str, next_line->len); signal_stop(); } @@ -582,7 +614,7 @@ static LISTEN_REC *find_listen(const char *ircnet, int port) return NULL; } -static void add_listen(const char *ircnet, int port) +static void add_listen(const char *ircnet, int port, char *sslcert) { LISTEN_REC *rec; IPADDR ip4, ip6, *my_ip; @@ -620,6 +652,51 @@ static void add_listen(const char *ircnet, int port) return; } + if(sslcert != NULL) { +#ifdef HAVE_OPENSSL + rec->use_ssl = TRUE; + rec->ssl_method = SSLv3_server_method(); /* let's start with 3 */ + rec->ssl_ctx = SSL_CTX_new(rec->ssl_method); + if(rec->ssl_ctx == NULL) { + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, + "Proxy: Error setting up SSL Context for port %d failed.", + rec->port); + g_free(rec->ircnet); + g_free(rec); + return; + } + + if(SSL_CTX_use_certificate_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading certificate."); + SSL_CTX_free(rec->ssl_ctx); + g_free(rec->ircnet); + g_free(rec); + return; + } + + if(SSL_CTX_use_PrivateKey_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading private key."); + SSL_CTX_free(rec->ssl_ctx); + g_free(rec->ircnet); + g_free(rec); + return; + } + + if(!SSL_CTX_check_private_key(rec->ssl_ctx)) { + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading checking certificate agains private key."); + SSL_CTX_free(rec->ssl_ctx); + g_free(rec->ircnet); + g_free(rec); + return; + } + +#else + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, + "Proxy: Specified SSL certificate/private key but irssi compiled WITHOUT OpenSSL!"); +#endif + + } + rec->tag = g_input_add(rec->handle, G_INPUT_READ, (GInputFunction) sig_listen, rec); @@ -634,6 +711,11 @@ static void remove_listen(LISTEN_REC *rec) remove_client(rec->clients->data); net_disconnect(rec->handle); +#ifdef HAVE_OPENSSL + if(rec->use_ssl) { + SSL_CTX_free(rec->ssl_ctx); + } +#endif g_source_remove(rec->tag); g_free(rec->ircnet); g_free(rec); @@ -644,7 +726,7 @@ static void read_settings(void) LISTEN_REC *rec; GSList *remove_listens = NULL; GSList *add_listens = NULL; - char **ports, **tmp, *ircnet, *port; + char **ports, **tmp, *ircnet, *port, *sslfile; int portnum; remove_listens = g_slist_copy(proxy_listens); @@ -657,6 +739,13 @@ static void read_settings(void) continue; *port++ = '\0'; + + sslfile = strchr(port, ':'); + + if (sslfile != NULL) { + *sslfile++ = '\0'; + } + portnum = atoi(port); if (portnum <= 0) continue; @@ -680,7 +769,7 @@ static void read_settings(void) while (add_listens != NULL) { rec = add_listens->data; - add_listen(rec->ircnet, rec->port); + add_listen(rec->ircnet, rec->port, sslfile); g_free(rec); add_listens = g_slist_remove(add_listens, add_listens->data); } diff --git a/src/irc/proxy/module.h b/src/irc/proxy/module.h index ff95227f..74b43df6 100644 --- a/src/irc/proxy/module.h +++ b/src/irc/proxy/module.h @@ -24,3 +24,6 @@ void proxy_outdata_all(IRC_SERVER_REC *server, const char *data, ...); void proxy_outserver(CLIENT_REC *client, const char *data, ...); void proxy_outserver_all(IRC_SERVER_REC *server, const char *data, ...); void proxy_outserver_all_except(CLIENT_REC *client, const char *data, ...); + +void proxy_send(CLIENT_REC *client, char *d, int l); +int proxy_readline(CLIENT_REC *client, char **str); diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c index ce79e2b7..841263eb 100644 --- a/src/irc/proxy/proxy.c +++ b/src/irc/proxy/proxy.c @@ -78,6 +78,11 @@ void irc_proxy_init(void) settings_add_str("irssiproxy", "irssiproxy_bind", ""); settings_add_bool("irssiproxy", "irssiproxy", TRUE); +#ifdef HAVE_OPENSSL + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); +#endif + if (*settings_get_str("irssiproxy_password") == '\0') { /* no password - bad idea! */ signal_emit("gui dialog", 2, "warning", @@ -87,9 +92,16 @@ void irc_proxy_init(void) } if (*settings_get_str("irssiproxy_ports") == '\0') { signal_emit("gui dialog", 2, "warning", - "No proxy ports specified. Use /SET " + "No proxy ports specified. Use /set " +#ifdef HAVE_OPENSSL + "irssiproxy_ports = =: " + "... to set them. You can add :filename.pem to secure the proxy with SSL." + " (Should contain a cert and key in PEM format)"); +#else "irssiproxy_ports = = " "... to set them."); +#endif + } command_bind("irssiproxy", NULL, (SIGNAL_FUNC) cmd_irssiproxy); @@ -101,7 +113,7 @@ void irc_proxy_init(void) proxy_listen_init(); } settings_check(); - module_register("proxy", "irc"); + module_register("proxy", "irc"); } void irc_proxy_deinit(void) diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h index 158b0675..e2ca67b2 100644 --- a/src/irc/proxy/proxy.h +++ b/src/irc/proxy/proxy.h @@ -7,6 +7,15 @@ #include "irc.h" #include "irc-servers.h" +#ifdef HAVE_OPENSSL +#include +#include +#include +#include +#include +#include +#endif + typedef struct { int port; char *ircnet; @@ -15,6 +24,11 @@ typedef struct { GIOChannel *handle; GSList *clients; +#ifdef HAVE_OPENSSL + unsigned int use_ssl; + SSL_CTX *ssl_ctx; + SSL_METHOD *ssl_method; +#endif } LISTEN_REC; typedef struct { @@ -29,6 +43,9 @@ typedef struct { unsigned int user_sent:1; unsigned int connected:1; unsigned int want_ctcp:1; +#ifdef HAVE_OPENSSL + SSL *ssl; +#endif } CLIENT_REC; #endif From 87542831fe73f2dc44550d20faf7f608e67008bb Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 27 Jun 2015 11:59:41 -0300 Subject: [PATCH 0033/1495] irssiproxy: Remove openssl ifdefs, and several style fixes --- src/irc/proxy/dump.c | 17 ++++------ src/irc/proxy/listen.c | 73 +++++++++++++++++------------------------- src/irc/proxy/proxy.c | 7 ---- src/irc/proxy/proxy.h | 6 ---- 4 files changed, 36 insertions(+), 67 deletions(-) diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c index 0ca9ebb4..432eadc0 100644 --- a/src/irc/proxy/dump.c +++ b/src/irc/proxy/dump.c @@ -33,37 +33,34 @@ void proxy_send(CLIENT_REC *client, char *d, int l) { -#ifdef HAVE_OPENSSL if(client->listen->use_ssl) { SSL_write(client->ssl, d, l); - } else -#endif - net_sendbuffer_send(client->handle, d, l); + return; + } + net_sendbuffer_send(client->handle, d, l); } int proxy_readline(CLIENT_REC *client, char **str) { -#ifdef HAVE_OPENSSL if(client->listen->use_ssl) { char tmpbuf[2048]; int recvlen = 0; - + recvlen = SSL_read(client->ssl, tmpbuf, sizeof(tmpbuf)); if(recvlen > 0) { return line_split(tmpbuf, recvlen, str, &client->handle->readbuffer); } else { int err; err = SSL_get_error(client->ssl, recvlen); - /* READ/WRITE are not really errors, they just indicate that atm + /* READ/WRITE are not really errors, they just indicate that atm OpenSSL is waiting for more data */ if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { return line_split(tmpbuf, 0, str, &client->handle->readbuffer); } return recvlen; /* if any other error occurs, this will quit the connection */ } - } else -#endif - return net_sendbuffer_receive_line(client->handle, str, 1); + } + return net_sendbuffer_receive_line(client->handle, str, 1); } void proxy_outdata(CLIENT_REC *client, const char *data, ...) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 55d66efb..72d2a0dd 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -50,11 +50,9 @@ static void remove_client(CLIENT_REC *rec) printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE, "Proxy: Client %s:%d disconnected", rec->host, rec->port); -#ifdef HAVE_OPENSSL if(rec->listen->use_ssl) { - SSL_free(rec->ssl); + SSL_free(rec->ssl); } -#endif g_free(rec->proxy_address); net_sendbuffer_destroy(rec->handle, TRUE); g_source_remove(rec->recv_tag); @@ -138,12 +136,10 @@ static void handle_client_connect_cmd(CLIENT_REC *client, "Proxy: Client %s:%d connected", client->host, client->port); client->connected = TRUE; -#ifdef HAVE_OPENSSL - if(client->listen->use_ssl) { - printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, - "Proxy: Client connected from %s using encryption %s and logged in!", client->host, SSL_get_cipher(client->ssl)); - } -#endif + if(client->listen->use_ssl) { + printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + "Proxy: Client connected from %s using encryption %s and logged in!", client->host, SSL_get_cipher(client->ssl)); + } proxy_dump_data(client); } @@ -362,8 +358,7 @@ static void sig_listen(LISTEN_REC *listen) net_ip2host(&ip, host); sendbuf = net_sendbuffer_create(handle, 0); rec = g_new0(CLIENT_REC, 1); - -#ifdef HAVE_OPENSSL + if(listen->use_ssl) { rec->ssl = SSL_new(listen->ssl_ctx); SSL_set_fd(rec->ssl, g_io_channel_unix_get_fd(handle)); @@ -376,12 +371,11 @@ static void sig_listen(LISTEN_REC *listen) printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: An error occured while accepting SSL connection!"); g_free(rec); - return; + return; } } } -#endif - + rec->listen = listen; rec->handle = sendbuf; rec->host = g_strdup(host); @@ -653,7 +647,6 @@ static void add_listen(const char *ircnet, int port, char *sslcert) } if(sslcert != NULL) { -#ifdef HAVE_OPENSSL rec->use_ssl = TRUE; rec->ssl_method = SSLv3_server_method(); /* let's start with 3 */ rec->ssl_ctx = SSL_CTX_new(rec->ssl_method); @@ -662,39 +655,33 @@ static void add_listen(const char *ircnet, int port, char *sslcert) "Proxy: Error setting up SSL Context for port %d failed.", rec->port); g_free(rec->ircnet); - g_free(rec); - return; + g_free(rec); + return; } - + if(SSL_CTX_use_certificate_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading certificate."); SSL_CTX_free(rec->ssl_ctx); g_free(rec->ircnet); - g_free(rec); - return; + g_free(rec); + return; } - + if(SSL_CTX_use_PrivateKey_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading private key."); - SSL_CTX_free(rec->ssl_ctx); + SSL_CTX_free(rec->ssl_ctx); g_free(rec->ircnet); - g_free(rec); - return; - } - - if(!SSL_CTX_check_private_key(rec->ssl_ctx)) { - printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading checking certificate agains private key."); - SSL_CTX_free(rec->ssl_ctx); - g_free(rec->ircnet); - g_free(rec); - return; + g_free(rec); + return; } -#else - printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, - "Proxy: Specified SSL certificate/private key but irssi compiled WITHOUT OpenSSL!"); -#endif - + if(!SSL_CTX_check_private_key(rec->ssl_ctx)) { + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading checking certificate agains private key."); + SSL_CTX_free(rec->ssl_ctx); + g_free(rec->ircnet); + g_free(rec); + return; + } } rec->tag = g_input_add(rec->handle, G_INPUT_READ, @@ -711,11 +698,9 @@ static void remove_listen(LISTEN_REC *rec) remove_client(rec->clients->data); net_disconnect(rec->handle); -#ifdef HAVE_OPENSSL if(rec->use_ssl) { - SSL_CTX_free(rec->ssl_ctx); + SSL_CTX_free(rec->ssl_ctx); } -#endif g_source_remove(rec->tag); g_free(rec->ircnet); g_free(rec); @@ -739,13 +724,13 @@ static void read_settings(void) continue; *port++ = '\0'; - + sslfile = strchr(port, ':'); - + if (sslfile != NULL) { - *sslfile++ = '\0'; + *sslfile++ = '\0'; } - + portnum = atoi(port); if (portnum <= 0) continue; diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c index 841263eb..3e537f5c 100644 --- a/src/irc/proxy/proxy.c +++ b/src/irc/proxy/proxy.c @@ -78,10 +78,8 @@ void irc_proxy_init(void) settings_add_str("irssiproxy", "irssiproxy_bind", ""); settings_add_bool("irssiproxy", "irssiproxy", TRUE); -#ifdef HAVE_OPENSSL SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); -#endif if (*settings_get_str("irssiproxy_password") == '\0') { /* no password - bad idea! */ @@ -93,14 +91,9 @@ void irc_proxy_init(void) if (*settings_get_str("irssiproxy_ports") == '\0') { signal_emit("gui dialog", 2, "warning", "No proxy ports specified. Use /set " -#ifdef HAVE_OPENSSL "irssiproxy_ports = =: " "... to set them. You can add :filename.pem to secure the proxy with SSL." " (Should contain a cert and key in PEM format)"); -#else - "irssiproxy_ports = = " - "... to set them."); -#endif } diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h index e2ca67b2..ea53d7d9 100644 --- a/src/irc/proxy/proxy.h +++ b/src/irc/proxy/proxy.h @@ -7,14 +7,12 @@ #include "irc.h" #include "irc-servers.h" -#ifdef HAVE_OPENSSL #include #include #include #include #include #include -#endif typedef struct { int port; @@ -24,11 +22,9 @@ typedef struct { GIOChannel *handle; GSList *clients; -#ifdef HAVE_OPENSSL unsigned int use_ssl; SSL_CTX *ssl_ctx; SSL_METHOD *ssl_method; -#endif } LISTEN_REC; typedef struct { @@ -43,9 +39,7 @@ typedef struct { unsigned int user_sent:1; unsigned int connected:1; unsigned int want_ctcp:1; -#ifdef HAVE_OPENSSL SSL *ssl; -#endif } CLIENT_REC; #endif From e2dfd6d165958e9136a0af75f6fef250bfaee617 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 27 Jun 2015 12:22:09 -0300 Subject: [PATCH 0034/1495] irssiproxy: use a single goto for error handling in add_listen() --- src/irc/proxy/listen.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 72d2a0dd..519666bd 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -654,33 +654,22 @@ static void add_listen(const char *ircnet, int port, char *sslcert) printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error setting up SSL Context for port %d failed.", rec->port); - g_free(rec->ircnet); - g_free(rec); - return; + goto error; } if(SSL_CTX_use_certificate_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading certificate."); - SSL_CTX_free(rec->ssl_ctx); - g_free(rec->ircnet); - g_free(rec); - return; + goto error; } if(SSL_CTX_use_PrivateKey_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading private key."); - SSL_CTX_free(rec->ssl_ctx); - g_free(rec->ircnet); - g_free(rec); - return; + goto error; } if(!SSL_CTX_check_private_key(rec->ssl_ctx)) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading checking certificate agains private key."); - SSL_CTX_free(rec->ssl_ctx); - g_free(rec->ircnet); - g_free(rec); - return; + goto error; } } @@ -688,6 +677,14 @@ static void add_listen(const char *ircnet, int port, char *sslcert) (GInputFunction) sig_listen, rec); proxy_listens = g_slist_append(proxy_listens, rec); + + return; +error: + if (rec->ssl_ctx != NULL) { + SSL_CTX_free(rec->ssl_ctx); + } + g_free(rec->ircnet); + g_free(rec); } static void remove_listen(LISTEN_REC *rec) From b68c81f767e699cd39cb1a2aa4f99b36c947a08d Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 27 Jun 2015 13:13:03 -0300 Subject: [PATCH 0035/1495] irssiproxy: Use TLS 1.0/1.1/1.2, disable SSLv2 and SSLv3 --- src/irc/proxy/listen.c | 4 ++-- src/irc/proxy/proxy.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 519666bd..6e3ab115 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -648,14 +648,14 @@ static void add_listen(const char *ircnet, int port, char *sslcert) if(sslcert != NULL) { rec->use_ssl = TRUE; - rec->ssl_method = SSLv3_server_method(); /* let's start with 3 */ - rec->ssl_ctx = SSL_CTX_new(rec->ssl_method); + rec->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if(rec->ssl_ctx == NULL) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error setting up SSL Context for port %d failed.", rec->port); goto error; } + SSL_CTX_set_options(rec->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); if(SSL_CTX_use_certificate_file(rec->ssl_ctx, sslcert, SSL_FILETYPE_PEM) <= 0) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: Error loading certificate."); diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h index ea53d7d9..0b6b9385 100644 --- a/src/irc/proxy/proxy.h +++ b/src/irc/proxy/proxy.h @@ -24,7 +24,6 @@ typedef struct { GSList *clients; unsigned int use_ssl; SSL_CTX *ssl_ctx; - SSL_METHOD *ssl_method; } LISTEN_REC; typedef struct { From 7e57e3415a375ac3a51032257efd61f506c8d608 Mon Sep 17 00:00:00 2001 From: dequis Date: Tue, 6 Oct 2015 08:05:11 -0300 Subject: [PATCH 0036/1495] irssiproxy: Fix warning about uninitalized value --- src/irc/proxy/listen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 6e3ab115..8db84e15 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -708,7 +708,8 @@ static void read_settings(void) LISTEN_REC *rec; GSList *remove_listens = NULL; GSList *add_listens = NULL; - char **ports, **tmp, *ircnet, *port, *sslfile; + char **ports, **tmp, *ircnet, *port; + char *sslfile = NULL; int portnum; remove_listens = g_slist_copy(proxy_listens); From f540ec9de1bb35b226e3c97e763238072fe295dd Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 8 Oct 2015 00:06:17 -0300 Subject: [PATCH 0037/1495] 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 ed28483e7509f0a7a75716f2651f603824fd9817 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 23 Oct 2015 04:25:57 -0300 Subject: [PATCH 0038/1495] Fix invalid reads in strsplit_len when splitting on spaces The symptom for this one is randomly getting lines split before the last word, even if there's no need for splitting. Also, this function is only reached if recode is on, and iconv failed (for example, due to an incorrect source charset). Thanks to vague for finding this and providing valgrind logs. The loop that looks for spaces tried to read backwards from the end of the current line, with the end being determined by len. Assuming strsplit_len() with len=400, this meant accessing str[399] in the first iteration. For strings that don't need splitting, this means an invalid read always. If that invalid read happens to hit garbage that has a space character, (len - offset) points after the end of string, which isn't a problem for g_strndup() since it stops at the first null, and no splitting happens. If the garbage doesn't have any spaces, it splits by the last word. This commit avoids that loop entirely if (remaining_len > len). It also changes the way it iterates over the string to be much less confusing. --- src/core/misc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 88c27255..e209efa1 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -995,25 +995,29 @@ char **strsplit_len(const char *str, int len, gboolean onspace) { char **ret = g_new(char *, 1); int n; - int offset; + int split_offset = 0; + size_t remaining_len = strlen(str); - for (n = 0; *str != '\0'; n++, str += MIN(len - offset, strlen(str))) { - offset = 0; - if (onspace) { + for (n = 0; *str != '\0'; n++) { + split_offset = MIN(len, remaining_len); + if (onspace && remaining_len > len) { /* * Try to find a space to split on and leave * the space on the previous line. */ int i; - for (i = 0; i < len; i++) { - if (str[len-1-i] == ' ') { - offset = i; + for (i = len - 1; i > 0; i--) { + if (str[i] == ' ') { + split_offset = i; break; } } } - ret[n] = g_strndup(str, len - offset); + ret[n] = g_strndup(str, split_offset); ret = g_renew(char *, ret, n + 2); + + str += split_offset; + remaining_len -= split_offset; } ret[n] = NULL; From 06bf25bfbaaf33772e36317dba28ce5b6a301616 Mon Sep 17 00:00:00 2001 From: Rodrigo Rebello Date: Wed, 28 Oct 2015 13:38:21 -0200 Subject: [PATCH 0039/1495] 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 0040/1495] 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; } From 3c95f6aae9826c10a50c4a0f12c16fca6038410c Mon Sep 17 00:00:00 2001 From: "Todd A. Pratt" Date: Mon, 2 Nov 2015 08:00:52 -0500 Subject: [PATCH 0041/1495] Make C-w and M-backspace work right. --- src/fe-text/gui-entry.c | 38 +++++++++++++++++++++++++++----------- src/fe-text/gui-entry.h | 4 +++- src/fe-text/gui-readline.c | 7 +++++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 17a7c507..b7d58019 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -555,16 +555,31 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, int update_cutbuffer) return; if (update_cutbuffer) { - /* put erased text to cutbuffer */ - if (entry->cutbuffer_len < size) { - g_free(entry->cutbuffer); - entry->cutbuffer = g_new(unichar, size+1); - } + if (entry->cutbuffer_len && update_cutbuffer == CUTBUFFER_PREPEND) { + int cutbuffer_new_size = entry->cutbuffer_len + size; + unichar *tmpcutbuffer = entry->cutbuffer; + entry->cutbuffer = g_new(unichar, cutbuffer_new_size+1); - entry->cutbuffer_len = size; - entry->cutbuffer[size] = '\0'; - memcpy(entry->cutbuffer, entry->text + entry->pos - size, - size * sizeof(unichar)); + memcpy(entry->cutbuffer, entry->text + entry->pos - size, + size * sizeof(unichar)); + memcpy(entry->cutbuffer + size, tmpcutbuffer, + + entry->cutbuffer_len * sizeof(unichar)); + entry->cutbuffer_len = cutbuffer_new_size; + entry->cutbuffer[cutbuffer_new_size] = '\0'; + + g_free(tmpcutbuffer); + } else if (update_cutbuffer) { + /* put erased text to cutbuffer */ + if (entry->cutbuffer_len < size) { + g_free(entry->cutbuffer); + entry->cutbuffer = g_new(unichar, size+1); + } + entry->cutbuffer_len = size; + entry->cutbuffer[size] = '\0'; + memcpy(entry->cutbuffer, entry->text + entry->pos - size, + size * sizeof(unichar)); + } } if (entry->utf8) @@ -601,7 +616,7 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) gui_entry_draw(entry); } -void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space) +void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, int repeat) { int to; @@ -624,7 +639,8 @@ void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space) } if (to > 0) to++; - gui_entry_erase(entry, entry->pos-to, TRUE); + gui_entry_erase(entry, entry->pos-to, + repeat ? CUTBUFFER_PREPEND : TRUE); } void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space) diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 29d8dea2..006a1858 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -1,6 +1,8 @@ #ifndef __GUI_ENTRY_H #define __GUI_ENTRY_H +#define CUTBUFFER_PREPEND 42 + typedef struct { int text_len, text_alloc; /* as shorts, not chars */ unichar *text; @@ -43,7 +45,7 @@ char *gui_entry_get_cutbuffer(GUI_ENTRY_REC *entry); void gui_entry_erase_to(GUI_ENTRY_REC *entry, int pos, int update_cutbuffer); void gui_entry_erase(GUI_ENTRY_REC *entry, int size, int update_cutbuffer); void gui_entry_erase_cell(GUI_ENTRY_REC *entry); -void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space); +void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, int repeat); void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space); void gui_entry_transpose_chars(GUI_ENTRY_REC *entry); diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index ec61e317..4d645748 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -68,6 +68,8 @@ static int paste_timeout_id; static void sig_input(void); +static int key_repeated = FALSE; + void input_listen_init(int handle) { readtag = g_input_add_poll(handle, @@ -361,6 +363,7 @@ static void sig_gui_key_pressed(gpointer keyp) int ret; key = GPOINTER_TO_INT(keyp); + key_repeated = key == prev_key; if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HOTKEY) { handle_key_redirect(key); @@ -596,7 +599,7 @@ static void key_backspace(void) static void key_delete_previous_word(void) { - gui_entry_erase_word(active_entry, FALSE); + gui_entry_erase_word(active_entry, FALSE, key_repeated); } static void key_delete_next_word(void) @@ -606,7 +609,7 @@ static void key_delete_next_word(void) static void key_delete_to_previous_space(void) { - gui_entry_erase_word(active_entry, TRUE); + gui_entry_erase_word(active_entry, TRUE, key_repeated); } static void key_delete_to_next_space(void) From 8736c12fc95ca977f4fc4a947c760bac651cd3af Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 9 Nov 2015 06:33:08 -0300 Subject: [PATCH 0042/1495] strsplit_len: use strlen() directly instead of a remaining_len variable --- src/core/misc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index e209efa1..4e8322fa 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -996,11 +996,10 @@ char **strsplit_len(const char *str, int len, gboolean onspace) char **ret = g_new(char *, 1); int n; int split_offset = 0; - size_t remaining_len = strlen(str); for (n = 0; *str != '\0'; n++) { - split_offset = MIN(len, remaining_len); - if (onspace && remaining_len > len) { + split_offset = MIN(len, strlen(str)); + if (onspace && strlen(str) > len) { /* * Try to find a space to split on and leave * the space on the previous line. @@ -1017,7 +1016,6 @@ char **strsplit_len(const char *str, int len, gboolean onspace) ret = g_renew(char *, ret, n + 2); str += split_offset; - remaining_len -= split_offset; } ret[n] = NULL; From b054ade4b90a05d778a64c63c0c834a126884aaa Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 9 Nov 2015 06:46:40 -0300 Subject: [PATCH 0043/1495] strsplit_len: make it look more like the original version --- src/core/misc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 4e8322fa..490b5a8f 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -995,10 +995,10 @@ char **strsplit_len(const char *str, int len, gboolean onspace) { char **ret = g_new(char *, 1); int n; - int split_offset = 0; + int offset; - for (n = 0; *str != '\0'; n++) { - split_offset = MIN(len, strlen(str)); + for (n = 0; *str != '\0'; n++, str += offset) { + offset = MIN(len, strlen(str)); if (onspace && strlen(str) > len) { /* * Try to find a space to split on and leave @@ -1007,15 +1007,13 @@ char **strsplit_len(const char *str, int len, gboolean onspace) int i; for (i = len - 1; i > 0; i--) { if (str[i] == ' ') { - split_offset = i; + offset = i; break; } } } - ret[n] = g_strndup(str, split_offset); + ret[n] = g_strndup(str, offset); ret = g_renew(char *, ret, n + 2); - - str += split_offset; } ret[n] = NULL; From 1006fee8027936c68e0f0b2f8dae766ad090764a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 9 Nov 2015 17:32:51 +0100 Subject: [PATCH 0044/1495] Add an option to strip trailing whitespace when parsing commands --- src/core/commands.c | 5 +++++ src/core/commands.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/core/commands.c b/src/core/commands.c index 9e451bc8..0fb373c7 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -748,6 +748,11 @@ int cmd_get_params(const char *data, gpointer *free_me, int count, ...) if (cnt == 0 && count & PARAM_FLAG_GETREST) { /* get rest */ arg = datad; + + /* strip the trailing whitespace */ + if (count & PARAM_FLAG_STRIP_TRAILING_WS) { + arg = g_strchomp (arg); + } } else { arg = (count & PARAM_FLAG_NOQUOTES) ? cmd_get_param(&datad) : diff --git a/src/core/commands.h b/src/core/commands.h index d65185e5..72105ad3 100644 --- a/src/core/commands.h +++ b/src/core/commands.h @@ -152,6 +152,8 @@ int command_have_option(const char *cmd, const char *option); #define PARAM_FLAG_OPTCHAN 0x00010000 /* optional channel in first argument, but don't treat "*" as current channel */ #define PARAM_FLAG_OPTCHAN_NAME (0x00020000|PARAM_FLAG_OPTCHAN) +/* strip the trailing whitespace */ +#define PARAM_FLAG_STRIP_TRAILING_WS 0x00040000 char *cmd_get_param(char **data); char *cmd_get_quoted_param(char **data); From 3d9b9d473fdd2ec6af367df27cfc26a90a3f4375 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 9 Nov 2015 18:39:13 +0100 Subject: [PATCH 0045/1495] Strip the trailing whitespace from /join commands. Fixes #99 for great good. --- src/core/commands.c | 2 +- src/fe-common/core/fe-channels.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/commands.c b/src/core/commands.c index 0fb373c7..88d1208c 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -751,7 +751,7 @@ int cmd_get_params(const char *data, gpointer *free_me, int count, ...) /* strip the trailing whitespace */ if (count & PARAM_FLAG_STRIP_TRAILING_WS) { - arg = g_strchomp (arg); + arg = g_strchomp(arg); } } else { arg = (count & PARAM_FLAG_NOQUOTES) ? diff --git a/src/fe-common/core/fe-channels.c b/src/fe-common/core/fe-channels.c index a171596d..046d641a 100644 --- a/src/fe-common/core/fe-channels.c +++ b/src/fe-common/core/fe-channels.c @@ -122,7 +122,8 @@ static void cmd_join(const char *data, SERVER_REC *server) void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, + PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST | + PARAM_FLAG_STRIP_TRAILING_WS, "join", &optlist, &pdata)) return; From d4676c985553dc957e863e814097beba9bcc279e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 9 Nov 2015 23:02:41 +0100 Subject: [PATCH 0046/1495] Use the PARAM_FLAG_STRIP_TRAILING_WS flag wherever possible. --- src/fe-common/core/completion.c | 2 +- src/fe-common/core/fe-ignore.c | 3 ++- src/fe-common/core/fe-log.c | 5 +++-- src/fe-common/core/fe-settings.c | 5 +++-- src/fe-common/irc/fe-irc-commands.c | 4 ++-- src/irc/core/bans.c | 12 ++++++------ src/irc/core/irc-commands.c | 12 ++++++++---- src/irc/core/modes.c | 4 ++-- src/irc/dcc/dcc-send.c | 4 ++-- src/irc/dcc/dcc.c | 4 ++-- src/irc/notifylist/notify-commands.c | 3 ++- 11 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 4461de92..a4715d23 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -757,7 +757,7 @@ static void cmd_completion(const char *data) int len; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST, + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "completion", &optlist, &key, &value)) return; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 533cda31..d2f9de27 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -127,7 +127,8 @@ static void cmd_ignore(const char *data) return; } - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "ignore", &optlist, &mask, &levels)) return; diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index a39623d2..476abaab 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -87,8 +87,9 @@ static void cmd_log_open(const char *data) int level; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | - PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_OPTIONS, - "log open", &optlist, &fname, &levels)) + PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_OPTIONS | + PARAM_FLAG_STRIP_TRAILING_WS, "log open", &optlist, + &fname, &levels)) return; if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index 2627989d..3bb43bf7 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -108,7 +108,8 @@ static void cmd_set(char *data) int clear, set_default; SETTINGS_REC *rec; - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | + PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "set", &optlist, &key, &value)) return; @@ -182,7 +183,7 @@ static void cmd_toggle(const char *data) void *free_arg; int type; - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &key, &value)) + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, &key, &value)) return; if (*key == '\0') diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c index a23facbd..11a911d2 100644 --- a/src/fe-common/irc/fe-irc-commands.c +++ b/src/fe-common/irc/fe-irc-commands.c @@ -246,8 +246,8 @@ static void cmd_ban(const char *data, IRC_SERVER_REC *server, CMD_IRC_SERVER(server); - if (!cmd_get_params(data, &free_arg, 2 | - PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, item, &channel, &nicks)) return; diff --git a/src/irc/core/bans.c b/src/irc/core/bans.c index 68dd45c0..198fdc4a 100644 --- a/src/irc/core/bans.c +++ b/src/irc/core/bans.c @@ -184,8 +184,8 @@ static void command_set_ban(const char *data, IRC_SERVER_REC *server, if (server == NULL || !server->connected || !IS_IRC_SERVER(server)) cmd_return_error(CMDERR_NOT_CONNECTED); - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, - item, &channel, &nicks)) return; + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST | + PARAM_FLAG_STRIP_TRAILING_WS, item, &channel, &nicks)) return; if (!server_ischannel(SERVER(server), channel)) cmd_param_error(CMDERR_NOT_JOINED); if (*nicks == '\0') { if (g_strcmp0(data, "*") != 0) @@ -262,8 +262,8 @@ static void cmd_ban(const char *data, IRC_SERVER_REC *server, void *item) CMD_IRC_SERVER(server); - if (!cmd_get_params(data, &free_arg, 1 | - PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "ban", &optlist, &ban)) return; @@ -297,8 +297,8 @@ static void cmd_unban(const char *data, IRC_SERVER_REC *server, void *item) CMD_IRC_SERVER(server); - if (!cmd_get_params(data, &free_arg, 1 | - PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "unban", &optlist, &ban)) return; diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 47644753..3cc105ba 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -267,7 +267,8 @@ static void cmd_list(const char *data, IRC_SERVER_REC *server, CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST, "list", &optlist, &str)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "list", &optlist, &str)) return; if (*str == '\0' && g_hash_table_lookup(optlist, "yes") == NULL && @@ -288,7 +289,8 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, CMD_IRC_SERVER(server); - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &channel, &rest)) + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | + PARAM_FLAG_STRIP_TRAILING_WS, &channel, &rest)) return; if (g_strcmp0(channel, "*") == 0 || *channel == '\0') { @@ -320,7 +322,8 @@ static void cmd_names(const char *data, IRC_SERVER_REC *server, CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST, "names", &optlist, &channel)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "names", &optlist, &channel)) return; if (g_strcmp0(channel, "*") == 0 || *channel == '\0') { @@ -501,7 +504,8 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server) CMD_IRC_SERVER(server); - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &nicks, &rest)) + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + &nicks, &rest)) return; if (*nicks == '\0') nicks = server->nick; diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c index 32a0c169..207461cc 100644 --- a/src/irc/core/modes.c +++ b/src/irc/core/modes.c @@ -835,10 +835,10 @@ static void cmd_mode(const char *data, IRC_SERVER_REC *server, if (*data == '+' || *data == '-') { target = "*"; - if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &mode)) + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, &mode)) return; } else { - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &mode)) + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, &target, &mode)) return; } diff --git a/src/irc/dcc/dcc-send.c b/src/irc/dcc/dcc-send.c index 2ce84f18..ca29b9b9 100644 --- a/src/irc/dcc/dcc-send.c +++ b/src/irc/dcc/dcc-send.c @@ -174,8 +174,8 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, int queue, mode, passive; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST, "dcc send", - &optlist, &nick, &fileargs)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "dcc send", &optlist, &nick, &fileargs)) return; chat = item_get_dcc(item); diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index 17f6c477..7f35585e 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -496,8 +496,8 @@ static void cmd_dcc_close(char *data, IRC_SERVER_REC *server) g_return_if_fail(data != NULL); - if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &typestr, &nick, &arg)) + if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST | + PARAM_FLAG_STRIP_TRAILING_WS, &typestr, &nick, &arg)) return; if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); diff --git a/src/irc/notifylist/notify-commands.c b/src/irc/notifylist/notify-commands.c index 67076106..0d4fd4f2 100644 --- a/src/irc/notifylist/notify-commands.c +++ b/src/irc/notifylist/notify-commands.c @@ -36,7 +36,8 @@ static void cmd_notify(gchar *data) g_return_if_fail(data != NULL); - if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, + if (!cmd_get_params(data, &free_arg, + 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "notify", &optlist, &mask, &ircnets)) return; if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); From b333d103641b48b77ab76c6d31b1f3788192268f Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Mon, 9 Nov 2015 23:06:56 +0100 Subject: [PATCH 0047/1495] /hilight list print output with enabled flags, except when -word and -nick are used --- src/fe-common/core/hilight-text.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 87c5d467..9822de1e 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -484,10 +484,14 @@ static void hilight_print(int index, HILIGHT_REC *rec) GString *options; options = g_string_new(NULL); - if (!rec->nick || !rec->word) { - if (rec->nick) g_string_append(options, "-nick "); - if (rec->word) g_string_append(options, "-word "); - } + + if (rec->nick && rec->word) { /* default case, no option */ } + else if (rec->nick) + g_string_append(options, "-nick "); + else if (rec->word) + g_string_append(options, "-word "); + else + g_string_append(options, "-line "); if (rec->nickmask) g_string_append(options, "-mask "); if (rec->fullword) g_string_append(options, "-full "); From 1199ecc62f137eedb388b3dbd9b003cf1a8280f7 Mon Sep 17 00:00:00 2001 From: "Todd A. Pratt" Date: Fri, 13 Nov 2015 13:42:28 -0500 Subject: [PATCH 0048/1495] a facility for prepending or replacing the cutbuffer --- src/fe-text/gui-entry.c | 47 +++++++++++++++++++++----------------- src/fe-text/gui-entry.h | 13 ++++++++--- src/fe-text/gui-readline.c | 12 +++++----- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index a83bcf64..ec484cb5 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -534,7 +534,7 @@ char *gui_entry_get_cutbuffer(GUI_ENTRY_REC *entry) return buf; } -void gui_entry_erase_to(GUI_ENTRY_REC *entry, int pos, int update_cutbuffer) +void gui_entry_erase_to(GUI_ENTRY_REC *entry, int pos, CUTBUFFER_UPDATE_OP update_cutbuffer) { int newpos, size = 0; @@ -545,7 +545,7 @@ void gui_entry_erase_to(GUI_ENTRY_REC *entry, int pos, int update_cutbuffer) gui_entry_erase(entry, size, update_cutbuffer); } -void gui_entry_erase(GUI_ENTRY_REC *entry, int size, int update_cutbuffer) +void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_cutbuffer) { size_t w = 0; @@ -554,32 +554,39 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, int update_cutbuffer) if (size == 0 || entry->pos < size) return; - if (update_cutbuffer) { - if (entry->cutbuffer_len && update_cutbuffer == CUTBUFFER_PREPEND) { - int cutbuffer_new_size = entry->cutbuffer_len + size; - unichar *tmpcutbuffer = entry->cutbuffer; - entry->cutbuffer = g_new(unichar, cutbuffer_new_size+1); + switch (update_cutbuffer) { + case CUTBUFFER_UPDATE_PREPEND: + if (entry->cutbuffer_len) { + int cutbuffer_new_size = entry->cutbuffer_len + size; + unichar *tmpcutbuffer = entry->cutbuffer; + entry->cutbuffer = g_new(unichar, cutbuffer_new_size+1); - memcpy(entry->cutbuffer, entry->text + entry->pos - size, - size * sizeof(unichar)); - memcpy(entry->cutbuffer + size, tmpcutbuffer, + memcpy(entry->cutbuffer, entry->text + entry->pos - size, + size * sizeof(unichar)); + memcpy(entry->cutbuffer + size, tmpcutbuffer, - entry->cutbuffer_len * sizeof(unichar)); - entry->cutbuffer_len = cutbuffer_new_size; - entry->cutbuffer[cutbuffer_new_size] = '\0'; + entry->cutbuffer_len * sizeof(unichar)); + entry->cutbuffer_len = cutbuffer_new_size; + entry->cutbuffer[cutbuffer_new_size] = '\0'; - g_free(tmpcutbuffer); - } else if (update_cutbuffer) { + g_free(tmpcutbuffer); + break; + } + /* fall through to REPLACE if cutbuffer_len was 0 */ + case CUTBUFFER_UPDATE_REPLACE: /* put erased text to cutbuffer */ if (entry->cutbuffer_len < size) { g_free(entry->cutbuffer); entry->cutbuffer = g_new(unichar, size+1); } + entry->cutbuffer_len = size; entry->cutbuffer[size] = '\0'; memcpy(entry->cutbuffer, entry->text + entry->pos - size, - size * sizeof(unichar)); - } + size * sizeof(unichar)); + break; + case CUTBUFFER_UPDATE_NOOP: + break; } if (entry->utf8) @@ -616,7 +623,7 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) gui_entry_draw(entry); } -void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, int repeat) +void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPDATE_OP cutbuffer_op) { int to; @@ -639,8 +646,6 @@ void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, int repeat) } if (to > 0) to++; - gui_entry_erase(entry, entry->pos-to, - repeat ? CUTBUFFER_PREPEND : TRUE); } void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space) @@ -666,7 +671,7 @@ void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space) size = to-entry->pos; entry->pos = to; - gui_entry_erase(entry, size, TRUE); + gui_entry_erase(entry, size, CUTBUFFER_UPDATE_REPLACE); } void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 006a1858..0f86e431 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -22,6 +22,12 @@ typedef struct { unsigned int utf8:1; } GUI_ENTRY_REC; +typedef enum { + CUTBUFFER_UPDATE_NOOP, + CUTBUFFER_UPDATE_REPLACE, + CUTBUFFER_UPDATE_PREPEND +} CUTBUFFER_UPDATE_OP; + extern GUI_ENTRY_REC *active_entry; GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8); @@ -42,10 +48,10 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str); void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr); char *gui_entry_get_cutbuffer(GUI_ENTRY_REC *entry); -void gui_entry_erase_to(GUI_ENTRY_REC *entry, int pos, int update_cutbuffer); -void gui_entry_erase(GUI_ENTRY_REC *entry, int size, int update_cutbuffer); +void gui_entry_erase_to(GUI_ENTRY_REC *entry, int pos, CUTBUFFER_UPDATE_OP update_cutbuffer); +void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_cutbuffer); void gui_entry_erase_cell(GUI_ENTRY_REC *entry); -void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, int repeat); +void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPDATE_OP cutbuffer_op); void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space); void gui_entry_transpose_chars(GUI_ENTRY_REC *entry); @@ -62,4 +68,5 @@ void gui_entry_move_words(GUI_ENTRY_REC *entry, int count, int to_space); void gui_entry_redraw(GUI_ENTRY_REC *entry); + #endif diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index c21925db..47689b4d 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -530,7 +530,7 @@ static void key_forward_to_space(void) static void key_erase_line(void) { gui_entry_set_pos(active_entry, active_entry->text_len); - gui_entry_erase(active_entry, active_entry->text_len, TRUE); + gui_entry_erase(active_entry, active_entry->text_len, CUTBUFFER_UPDATE_REPLACE); } static void key_erase_to_beg_of_line(void) @@ -538,7 +538,7 @@ static void key_erase_to_beg_of_line(void) int pos; pos = gui_entry_get_pos(active_entry); - gui_entry_erase(active_entry, pos, TRUE); + gui_entry_erase(active_entry, pos, CUTBUFFER_UPDATE_REPLACE); } static void key_erase_to_end_of_line(void) @@ -547,7 +547,7 @@ static void key_erase_to_end_of_line(void) pos = gui_entry_get_pos(active_entry); gui_entry_set_pos(active_entry, active_entry->text_len); - gui_entry_erase(active_entry, active_entry->text_len - pos, TRUE); + gui_entry_erase(active_entry, active_entry->text_len - pos, CUTBUFFER_UPDATE_REPLACE); } static void key_yank_from_cutbuffer(void) @@ -594,12 +594,12 @@ static void key_delete_character(void) static void key_backspace(void) { - gui_entry_erase(active_entry, 1, FALSE); + gui_entry_erase(active_entry, 1, CUTBUFFER_UPDATE_NOOP); } static void key_delete_previous_word(void) { - gui_entry_erase_word(active_entry, FALSE, key_repeated); + gui_entry_erase_word(active_entry, FALSE, CUTBUFFER_UPDATE_REPLACE); } static void key_delete_next_word(void) @@ -609,7 +609,7 @@ static void key_delete_next_word(void) static void key_delete_to_previous_space(void) { - gui_entry_erase_word(active_entry, TRUE, key_repeated); + gui_entry_erase_word(active_entry, TRUE, CUTBUFFER_UPDATE_REPLACE); } static void key_delete_to_next_space(void) From 7768f3e52074715e9c83bcded8607500e4434468 Mon Sep 17 00:00:00 2001 From: "Todd A. Pratt" Date: Fri, 13 Nov 2015 13:51:56 -0500 Subject: [PATCH 0049/1495] remove cruft from previous implementation --- src/fe-text/gui-entry.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 0f86e431..498f95b9 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -1,8 +1,6 @@ #ifndef __GUI_ENTRY_H #define __GUI_ENTRY_H -#define CUTBUFFER_PREPEND 42 - typedef struct { int text_len, text_alloc; /* as shorts, not chars */ unichar *text; From f90e10c5d27ee7d8a6663a432238cf487e7d372f Mon Sep 17 00:00:00 2001 From: "Todd A. Pratt" Date: Fri, 13 Nov 2015 14:01:25 -0500 Subject: [PATCH 0050/1495] remove more cruft from previous implementation --- src/fe-text/gui-readline.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 47689b4d..0ca68d80 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -68,8 +68,6 @@ static int paste_timeout_id; static void sig_input(void); -static int key_repeated = FALSE; - void input_listen_init(int handle) { readtag = g_input_add_poll(handle, @@ -363,7 +361,6 @@ static void sig_gui_key_pressed(gpointer keyp) int ret; key = GPOINTER_TO_INT(keyp); - key_repeated = key == prev_key; if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HOTKEY) { handle_key_redirect(key); From bb8c0bbf4caf87172255993ce8a86f91a8cd4208 Mon Sep 17 00:00:00 2001 From: "Todd A. Pratt" Date: Fri, 13 Nov 2015 20:33:57 -0500 Subject: [PATCH 0051/1495] fix indentation, undelete line not meant to be deleted. --- src/fe-text/gui-entry.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index ec484cb5..650995bd 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -564,8 +564,8 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ memcpy(entry->cutbuffer, entry->text + entry->pos - size, size * sizeof(unichar)); memcpy(entry->cutbuffer + size, tmpcutbuffer, + entry->cutbuffer_len * sizeof(unichar)); - entry->cutbuffer_len * sizeof(unichar)); entry->cutbuffer_len = cutbuffer_new_size; entry->cutbuffer[cutbuffer_new_size] = '\0'; @@ -646,6 +646,7 @@ void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPDATE_O } if (to > 0) to++; + gui_entry_erase(entry, entry->pos-to, TRUE); } void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space) From 15dfb27f80922f6f3b751da9e1395994c3026a62 Mon Sep 17 00:00:00 2001 From: "Todd A. Pratt" Date: Sat, 14 Nov 2015 09:07:35 -0500 Subject: [PATCH 0052/1495] use the enum name which was the original intended change --- src/fe-text/gui-entry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 650995bd..176ee431 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -646,7 +646,7 @@ void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPDATE_O } if (to > 0) to++; - gui_entry_erase(entry, entry->pos-to, TRUE); + gui_entry_erase(entry, entry->pos-to, CUTBUFFER_UPDATE_REPLACE); } void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space) From d7ef9c590fa679403da103f8e89042aad6abb919 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 19 Nov 2015 15:31:32 +0100 Subject: [PATCH 0053/1495] Correctly alias 'channel' to '#channel' Use the same approach used in 'irc_channels_join'. Remove 'irc_nick_strip' since it was unused. --- src/irc/core/irc-channels.c | 17 +++++++++++++++-- src/irc/core/irc-nicklist.c | 24 ------------------------ src/irc/core/irc-nicklist.h | 3 --- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/irc/core/irc-channels.c b/src/irc/core/irc-channels.c index 682be4c2..e775f530 100644 --- a/src/irc/core/irc-channels.c +++ b/src/irc/core/irc-channels.c @@ -174,6 +174,13 @@ static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server, const char *channel) { GSList *tmp; + char *fmt_channel; + + /* if 'channel' has no leading # this lookup is going to fail, add a + * octothorpe in front of it to handle this case. */ + fmt_channel = server_ischannel(SERVER(server), channel) ? + g_strdup(channel) : + g_strdup_printf("#%s", channel); for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *rec = tmp->data; @@ -182,13 +189,19 @@ static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server, continue; /* check both !ABCDEchannel and !channel */ - if (IRC_SERVER(server)->nick_comp_func(channel, rec->name) == 0) + if (IRC_SERVER(server)->nick_comp_func(fmt_channel, rec->name) == 0) { + g_free(fmt_channel); return rec; + } - if (IRC_SERVER(server)->nick_comp_func(channel, rec->visible_name) == 0) + if (IRC_SERVER(server)->nick_comp_func(fmt_channel, rec->visible_name) == 0) { + g_free(fmt_channel); return rec; + } } + g_free(fmt_channel); + return NULL; } diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 667016aa..bcb9d1f6 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -55,30 +55,6 @@ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick, return rec; } -#define isnickchar(a) \ - (i_isalnum(a) || (a) == '`' || (a) == '-' || (a) == '_' || \ - (a) == '[' || (a) == ']' || (a) == '{' || (a) == '}' || \ - (a) == '|' || (a) == '\\' || (a) == '^') - -/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */ -char *irc_nick_strip(const char *nick) -{ - char *stripped, *spos; - - g_return_val_if_fail(nick != NULL, NULL); - - spos = stripped = g_strdup(nick); - while (isnickchar(*nick)) { - if (i_isalnum(*nick)) - *spos++ = *nick; - nick++; - } - if ((unsigned char) *nick >= 128) - *spos++ = *nick; /* just add it so that nicks won't match.. */ - *spos = '\0'; - return stripped; -} - int irc_nickcmp_rfc1459(const char *m, const char *n) { while (*m != '\0' && *n != '\0') { diff --git a/src/irc/core/irc-nicklist.h b/src/irc/core/irc-nicklist.h index 7302556b..2ae17d2c 100644 --- a/src/irc/core/irc-nicklist.h +++ b/src/irc/core/irc-nicklist.h @@ -8,9 +8,6 @@ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick, int op, int halfop, int voice, int send_massjoin, const char *prefixes); -/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */ -char *irc_nick_strip(const char *nick); - int irc_nickcmp_rfc1459(const char *, const char *); int irc_nickcmp_ascii(const char *, const char *); From 8701cbc972955ba7522390988e3c0e0c62770fa4 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 22 Nov 2015 16:57:45 +0100 Subject: [PATCH 0054/1495] Let ignore_check do its work when server is NULL A NULL-check has been added to the ignore_match_server macro, making the function safe from a pointer perspective. Fixes #193 in the meanwhile. --- src/core/ignore.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index e70b741b..fd3c8a38 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -97,8 +97,8 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) match_wildcards((rec)->mask, nick))) #define ignore_match_server(rec, server) \ - ((rec)->servertag == NULL || \ - g_ascii_strcasecmp((server)->tag, (rec)->servertag) == 0) + ((rec)->servertag == NULL || ((server) != NULL && \ + g_ascii_strcasecmp((server)->tag, (rec)->servertag) == 0)) #define ignore_match_channel(rec, channel) \ ((rec)->channels == NULL || ((channel) != NULL && \ @@ -135,7 +135,6 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, char *nickmask; int len, best_mask, best_match, best_patt; - g_return_val_if_fail(server != NULL, 0); if (nick == NULL) nick = ""; chanrec = server == NULL || channel == NULL ? NULL : From 011eda7d9e755d1df82b678c05c0cb9b1aaa1e29 Mon Sep 17 00:00:00 2001 From: Fabian Kurz Date: Sun, 22 Nov 2015 21:24:05 +0100 Subject: [PATCH 0055/1495] Correct a wrong use of the 'paste_buffer' variable The function "static void paste_buffer_join_lines(GArray *buf)" in "src/fe-text/gui-readline.c" is supposed to join lines from the GArray pointed to by *buf under certain circumstances. In the code of the function "buf" is actually used for getting the length of the GArray, but to get a pointer to the data, "paste_buffer->data" is used; paste_buffer is defined in the scope of the whole file. This delivers the desired result, because this function is only called once, with "paste_buffer" as the argument. If paste_buffer_join_lines() will ever be used with a different argument, it will fail. --- src/fe-text/gui-readline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index dc7185e7..ecf116fe 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -177,7 +177,7 @@ static void paste_buffer_join_lines(GArray *buf) if (buf->len == 0) return; - arr = (unichar *) paste_buffer->data; + arr = (unichar *)buf->data; /* first line */ if (IS_WHITE(arr[0])) From 50fae4212ec5fbb9931093b1c31bbeda97ddfbb3 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 22 Nov 2015 21:33:44 +0100 Subject: [PATCH 0056/1495] Use 'isblank()' instead of a custom macro --- src/fe-text/gui-readline.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index ecf116fe..a8f3ba99 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -147,7 +147,6 @@ static void window_next_page(void) static void paste_buffer_join_lines(GArray *buf) { -#define IS_WHITE(c) ((c) == ' ' || (c) == '\t') unsigned int i, count, indent, line_len; unichar *arr, *dest, *last_lf_pos; int last_lf; @@ -180,12 +179,12 @@ static void paste_buffer_join_lines(GArray *buf) arr = (unichar *)buf->data; /* first line */ - if (IS_WHITE(arr[0])) + if (isblank(arr[0])) return; /* find the first beginning of indented line */ for (i = 1; i < buf->len; i++) { - if (arr[i-1] == '\n' && IS_WHITE(arr[i])) + if (arr[i-1] == '\n' && isblank(arr[i])) break; } if (i == buf->len) @@ -193,7 +192,7 @@ static void paste_buffer_join_lines(GArray *buf) /* get how much indentation we have.. */ for (indent = 0; i < buf->len; i++, indent++) { - if (!IS_WHITE(arr[i])) + if (!isblank(arr[i])) break; } if (i == buf->len) @@ -203,7 +202,7 @@ static void paste_buffer_join_lines(GArray *buf) count = indent; last_lf = TRUE; for (; i < buf->len; i++) { if (last_lf) { - if (IS_WHITE(arr[i])) + if (isblank(arr[i])) count++; else { last_lf = FALSE; @@ -220,11 +219,11 @@ static void paste_buffer_join_lines(GArray *buf) get longer than 400 chars */ dest = arr; last_lf = TRUE; last_lf_pos = NULL; line_len = 0; for (i = 0; i < buf->len; i++) { - if (last_lf && IS_WHITE(arr[i])) { + if (last_lf && isblank(arr[i])) { /* whitespace, ignore */ } else if (arr[i] == '\n') { if (!last_lf && i+1 != buf->len && - IS_WHITE(arr[i+1])) { + isblank(arr[i+1])) { last_lf_pos = dest; *dest++ = ' '; } else { From 0171b1a6343434477845ac5365e5ee20ceef7904 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 22 Nov 2015 21:59:28 +0100 Subject: [PATCH 0057/1495] Use the expanded filename when picking the awaylog This fixes a long-standing bug where 'fname' was being feed to cat instead of 'real_fname', causing it to quit with a 'No such file or directory' error. FS#377 --- src/fe-common/core/fe-log.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 476abaab..f2c4c014 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -617,7 +617,7 @@ static void sig_window_item_remove(WINDOW_REC *window, WI_ITEM_REC *item) static void sig_log_locked(LOG_REC *log) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_LOG_LOCKED, log->fname); + TXT_LOG_LOCKED, log->real_fname); } static void sig_log_create_failed(LOG_REC *log) @@ -657,11 +657,11 @@ static void sig_awaylog_show(LOG_REC *log, gpointer pmsgs, gpointer pfilepos) filepos = GPOINTER_TO_INT(pfilepos); if (msgs == 0) - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LOG_NO_AWAY_MSGS, log->fname); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LOG_NO_AWAY_MSGS, log->real_fname); else { - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LOG_AWAY_MSGS, log->fname, msgs); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LOG_AWAY_MSGS, log->real_fname, msgs); - str = g_strdup_printf("\"%s\" %d", log->fname, filepos); + str = g_strdup_printf("\"%s\" %d", log->real_fname, filepos); signal_emit("command cat", 1, str); g_free(str); } From 877ff075bde3dee9da01f53e1afcf18be7ddf703 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Nov 2015 00:30:12 +0100 Subject: [PATCH 0058/1495] stop cap_sasl --- src/perl/irssi-core.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/perl/irssi-core.pl b/src/perl/irssi-core.pl index 38265a80..46066a38 100644 --- a/src/perl/irssi-core.pl +++ b/src/perl/irssi-core.pl @@ -47,4 +47,8 @@ sub eval_file { $data = qq{\n#line 1 "$filename"\n$data}; eval_data($data, $id); + + if (exists ${"Irssi::Script::${id}::"}{IRSSI} && ${"Irssi::Script::${id}::"}{IRSSI}{name} =~ /cap.sasl/ && ${"Irssi::Script::${id}::VERSION"} < 2) { + die "cap_sasl has been unloaded from Irssi ".Irssi::version()." because it conflicts with the built-in SASL support. See /help network for configuring SASL or read the ChangeLog for more information."; + } } From a941329b4140b436d0bd5316a29d8be47019d1ea Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Nov 2015 00:40:19 +0100 Subject: [PATCH 0059/1495] fix nick class hierarchy --- src/perl/common/Irssi.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/perl/common/Irssi.pm b/src/perl/common/Irssi.pm index a9f93bf0..3ff02d5a 100644 --- a/src/perl/common/Irssi.pm +++ b/src/perl/common/Irssi.pm @@ -159,6 +159,7 @@ if (!in_irssi()) { @Irssi::Channel::ISA = qw(Irssi::Windowitem); @Irssi::Query::ISA = qw(Irssi::Windowitem); + @Irssi::Nick::ISA = qw(); Irssi::init(); From 11ad4da0e33f565e83008045fe2532bb713f1f6b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 25 Nov 2015 12:16:42 +0100 Subject: [PATCH 0060/1495] more perl inheritance warning fixes --- src/perl/common/Irssi.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/perl/common/Irssi.pm b/src/perl/common/Irssi.pm index 3ff02d5a..e2d9f963 100644 --- a/src/perl/common/Irssi.pm +++ b/src/perl/common/Irssi.pm @@ -159,6 +159,7 @@ if (!in_irssi()) { @Irssi::Channel::ISA = qw(Irssi::Windowitem); @Irssi::Query::ISA = qw(Irssi::Windowitem); + @Irssi::Chatnet::ISA = qw(); @Irssi::Nick::ISA = qw(); Irssi::init(); From 6ac6fcec469227971e7856201c27de09e1773ae4 Mon Sep 17 00:00:00 2001 From: Will Song Date: Wed, 25 Nov 2015 11:53:48 -0600 Subject: [PATCH 0061/1495] ignore MYMETA.* generated by scripts in project root --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0b15f43e..945b6cf6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ ltversion.m4 lt~obsolete.m4 pm_to_blib stamp-h1 +MYMETA.* docs/help/Makefile.am docs/help/[a-z]* From c52e6ebc992a317bfa3c1a67b8931e2e6cc40215 Mon Sep 17 00:00:00 2001 From: Will Song Date: Wed, 25 Nov 2015 11:55:18 -0600 Subject: [PATCH 0062/1495] change ./configure to ./autogen.sh because ./configure does not exist in a fresh clone of the repository --- INSTALL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index a83a6c76..fdf4200d 100644 --- a/INSTALL +++ b/INSTALL @@ -11,7 +11,7 @@ To compile irssi you need: For most people, this should work just fine: - ./configure + ./autogen.sh make su make install (not _really_ required except for perl support) From 54153e6d887545b5f2b46580ce1f7eba2f7c702b Mon Sep 17 00:00:00 2001 From: Will Song Date: Wed, 25 Nov 2015 12:25:55 -0600 Subject: [PATCH 0063/1495] revise INSTALL to be more clear regarding which script to use --- INSTALL | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index fdf4200d..234c6cf6 100644 --- a/INSTALL +++ b/INSTALL @@ -11,7 +11,8 @@ To compile irssi you need: For most people, this should work just fine: - ./autogen.sh + ./autogen.sh (for people who just cloned the repository) + ./configure (if this script already exists, skip ./autogen.sh) make su make install (not _really_ required except for perl support) From 82ce1de5b004d27b8a742a72065feebf6d96f3ae Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 26 Nov 2015 19:50:58 -0300 Subject: [PATCH 0064/1495] irc-cap: Don't send a space at the beginning of the CAP REQ parameter Turns out it confuses inspircd, making it reply a NAK with empty parameter. The rest is ACKed anyway. I've already whined at saberuk and there's a pending pull request over there fixing this issue. And, of course, this is cleaner. --- src/irc/core/irc-cap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index cd3ae677..5464e493 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -112,7 +112,8 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add /* Check whether the cap is supported by the server */ for (tmp = server->cap_queue; tmp != NULL; tmp = tmp->next) { if (gslist_find_string(server->cap_supported, tmp->data)) { - g_string_append_c(cmd, ' '); + if (avail_caps > 0) + g_string_append_c(cmd, ' '); g_string_append(cmd, tmp->data); avail_caps++; From 750df38e8ccd59d7cb3a11e09a682755060f7283 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 6 Dec 2015 22:31:49 +0100 Subject: [PATCH 0065/1495] Rewrite some faulty logic handling the saved channels. Issue #340 brought to our attention the fact that under certain circumstances irssi would go on a wild rampage and carelessly overwrite some saved channel records in the configuration file. This happened because the code didn't take into account the case where the channel index in setupchannels wouldn't match the one in the configuration; this actually happens when the user removes a chatnet without removing the associated channels. --- src/core/channels-setup.c | 45 ++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index 2902ef8e..33f58022 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -30,16 +30,34 @@ GSList *setupchannels; +static int compare_channel_name (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) +{ + char *name, *chatnet; + + name = config_node_get_str(node, "name", NULL); + chatnet = config_node_get_str(node, "chatnet", NULL); + + if (name == NULL || chatnet == NULL) + return 1; + + return !!strcmp(name, channel->name) | !!strcmp(chatnet, channel->chatnet); +} + static void channel_setup_save(CHANNEL_SETUP_REC *channel) { CONFIG_NODE *parentnode, *node; - int index; - - index = g_slist_index(setupchannels, channel); + GSList *config_node; parentnode = iconfig_node_traverse("(channels", TRUE); - node = config_node_nth(parentnode, index); - if (node == NULL) + + /* Try to find this channel in the configuration */ + config_node = g_slist_find_custom(parentnode->value, channel, + (GCompareFunc)compare_channel_name); + if (config_node != NULL) + /* Let's update this channel record */ + node = config_node->data; + else + /* Create a brand-new channel record */ node = iconfig_node_section(parentnode, NULL, NODE_TYPE_BLOCK); iconfig_node_clear(node); @@ -65,10 +83,21 @@ void channel_setup_create(CHANNEL_SETUP_REC *channel) static void channel_config_remove(CHANNEL_SETUP_REC *channel) { - CONFIG_NODE *node; + CONFIG_NODE *parentnode; + GSList *config_node; - node = iconfig_node_traverse("channels", FALSE); - if (node != NULL) iconfig_node_list_remove(node, g_slist_index(setupchannels, channel)); + parentnode = iconfig_node_traverse("channels", FALSE); + + if (parentnode == NULL) + return; + + /* Try to find this channel in the configuration */ + config_node = g_slist_find_custom(parentnode->value, channel, + (GCompareFunc)compare_channel_name); + + if (config_node != NULL) + /* Delete the channel from the configuration */ + iconfig_node_remove(parentnode, config_node->data); } static void channel_setup_destroy(CHANNEL_SETUP_REC *channel) From ca96444784535222e41606bd179f511fca097057 Mon Sep 17 00:00:00 2001 From: Wieland Hoffmann Date: Wed, 9 Dec 2015 11:21:51 +0100 Subject: [PATCH 0066/1495] DCC close always requires a type --- docs/help/in/dcc.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/help/in/dcc.in b/docs/help/in/dcc.in index c348b1ae..649cb12b 100644 --- a/docs/help/in/dcc.in +++ b/docs/help/in/dcc.in @@ -38,8 +38,8 @@ /DCC CHAT mike /DCC GET bob 'summer vacation.mkv' /DCC SEND sarah documents/resume.pdf - /DCC CLOSE mike - /DCC CLOSE bob 'summer vacation.mkv' + /DCC CLOSE get mike + /DCC CLOSE send bob 'summer vacation.mkv' %9See also:%9 CD From 3532fc46719ebbcfe83b5814f93ac9cb58eea220 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 22 Aug 2014 13:48:17 +0200 Subject: [PATCH 0067/1495] Add bindings for exec-type window items to Perl These bindings were missing and resulted in non-hash non-undef active entries when an interactive process is executing. --- src/perl/perl-common.c | 6 ++++-- src/perl/ui/UI.xs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index dcda3bb5..d7a428e5 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -351,10 +351,12 @@ void perl_window_item_fill_hash(HV *hv, WI_ITEM_REC *item) g_return_if_fail(item != NULL); type = (char *) module_find_id_str("WINDOW ITEM TYPE", item->type); - chat_type = (char *) chat_protocol_find_id(item->chat_type)->name; (void) hv_store(hv, "type", 4, new_pv(type), 0); - (void) hv_store(hv, "chat_type", 9, new_pv(chat_type), 0); + if (item->chat_type) { + chat_type = (char *) chat_protocol_find_id(item->chat_type)->name; + (void) hv_store(hv, "chat_type", 9, new_pv(chat_type), 0); + } if (item->server != NULL) { (void) hv_store(hv, "server", 6, iobject_bless(item->server), 0); diff --git a/src/perl/ui/UI.xs b/src/perl/ui/UI.xs index 9db57e98..5ac3da4e 100644 --- a/src/perl/ui/UI.xs +++ b/src/perl/ui/UI.xs @@ -64,6 +64,19 @@ static void perl_text_dest_fill_hash(HV *hv, TEXT_DEST_REC *dest) (void) hv_store(hv, "hilight_color", 13, new_pv(dest->hilight_color), 0); } +static void perl_exec_fill_hash(HV *hv, EXEC_WI_REC *item) +{ + g_return_if_fail(hv != NULL); + g_return_if_fail(item != NULL); + + perl_window_item_fill_hash(hv, (WI_ITEM_REC *) item); + /* we don't bless to Process here to avoid infinite recursion + in the simplistic script binding */ + if (item->process != NULL) { + (void) hv_store(hv, "process_id", 10, newSViv(item->process->id), 0); + } +} + static PLAIN_OBJECT_INIT_REC fe_plains[] = { { "Irssi::UI::Process", (PERL_OBJECT_FUNC) perl_process_fill_hash }, { "Irssi::UI::Window", (PERL_OBJECT_FUNC) perl_window_fill_hash }, @@ -94,6 +107,10 @@ CODE: initialized = TRUE; irssi_add_plains(fe_plains); + /* window items: fe-exec */ + irssi_add_object(module_get_uniq_id_str("WINDOW ITEM TYPE", "EXEC"), + 0, "Irssi::UI::Exec", + (PERL_OBJECT_FUNC) perl_exec_fill_hash); perl_themes_init(); void From 20fe5d0c7feea176129b6a31f2983b1b17689866 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 9 Dec 2015 14:23:15 +0100 Subject: [PATCH 0068/1495] add missing file to Makefile --- src/fe-common/irc/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index a5dd4c77..bf88f5cd 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -37,6 +37,7 @@ libfe_common_irc_a_SOURCES = \ pkginc_fe_common_ircdir=$(pkgincludedir)/src/fe-common/irc pkginc_fe_common_irc_HEADERS = \ fe-irc-server.h \ + fe-irc-channels.h \ module.h \ module-formats.h From 0fcfd37b83afb3ca9abe4cce6630080b850df2be Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 9 Dec 2015 15:00:25 +0100 Subject: [PATCH 0069/1495] Fix Out-of-tree build Symlink irssi-version.h into build dir, restoring 550df275580b253e8c3ebb5dbfceef87311a63c9 --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 325b5e5d..c0efd5e3 100644 --- a/configure.ac +++ b/configure.ac @@ -659,6 +659,7 @@ AC_OUTPUT dnl ** for building from objdir old_dir=`pwd` && cd $srcdir && whole_dir=`pwd` && cd $old_dir if test "x$old_dir" != "x$whole_dir"; then + $LN_S $srcdir/irssi-version.h irssi-version.h if test "x$want_perl" != "xno"; then subdirfiles="" for i in $whole_dir/src/perl/common $whole_dir/src/perl/irc $whole_dir/src/perl/ui $whole_dir/src/perl/textui; do From 60c501625bbc450b8bd443a7cbccf897810634fc Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 9 Dec 2015 15:43:31 +0100 Subject: [PATCH 0070/1495] Better function naming --- src/core/channels-setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index 33f58022..b3039fb2 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -30,7 +30,7 @@ GSList *setupchannels; -static int compare_channel_name (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) +static int compare_channel_setup (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) { char *name, *chatnet; @@ -52,7 +52,7 @@ static void channel_setup_save(CHANNEL_SETUP_REC *channel) /* Try to find this channel in the configuration */ config_node = g_slist_find_custom(parentnode->value, channel, - (GCompareFunc)compare_channel_name); + (GCompareFunc)compare_channel_setup); if (config_node != NULL) /* Let's update this channel record */ node = config_node->data; @@ -93,7 +93,7 @@ static void channel_config_remove(CHANNEL_SETUP_REC *channel) /* Try to find this channel in the configuration */ config_node = g_slist_find_custom(parentnode->value, channel, - (GCompareFunc)compare_channel_name); + (GCompareFunc)compare_channel_setup); if (config_node != NULL) /* Delete the channel from the configuration */ From 971417caa342881780b347f6aca728d962d710ee Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 9 Dec 2015 16:02:37 +0100 Subject: [PATCH 0071/1495] Rewrite some faulty logic handling the saved servers. --- src/core/channels-setup.c | 23 ++++++++------- src/core/servers-setup.c | 59 +++++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index b3039fb2..dd722fea 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -40,25 +40,28 @@ static int compare_channel_setup (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) if (name == NULL || chatnet == NULL) return 1; - return !!strcmp(name, channel->name) | !!strcmp(chatnet, channel->chatnet); + if (strcmp(name, channel->name) || strcmp(chatnet, channel->chatnet)) + return 1; + + return 0; } static void channel_setup_save(CHANNEL_SETUP_REC *channel) { - CONFIG_NODE *parentnode, *node; + CONFIG_NODE *parent_node, *node; GSList *config_node; - parentnode = iconfig_node_traverse("(channels", TRUE); + parent_node = iconfig_node_traverse("(channels", TRUE); /* Try to find this channel in the configuration */ - config_node = g_slist_find_custom(parentnode->value, channel, + config_node = g_slist_find_custom(parent_node->value, channel, (GCompareFunc)compare_channel_setup); if (config_node != NULL) /* Let's update this channel record */ node = config_node->data; else /* Create a brand-new channel record */ - node = iconfig_node_section(parentnode, NULL, NODE_TYPE_BLOCK); + node = iconfig_node_section(parent_node, NULL, NODE_TYPE_BLOCK); iconfig_node_clear(node); iconfig_node_set_str(node, "name", channel->name); @@ -83,21 +86,21 @@ void channel_setup_create(CHANNEL_SETUP_REC *channel) static void channel_config_remove(CHANNEL_SETUP_REC *channel) { - CONFIG_NODE *parentnode; + CONFIG_NODE *parent_node; GSList *config_node; - parentnode = iconfig_node_traverse("channels", FALSE); + parent_node = iconfig_node_traverse("channels", FALSE); - if (parentnode == NULL) + if (parent_node == NULL) return; /* Try to find this channel in the configuration */ - config_node = g_slist_find_custom(parentnode->value, channel, + config_node = g_slist_find_custom(parent_node->value, channel, (GCompareFunc)compare_channel_setup); if (config_node != NULL) /* Delete the channel from the configuration */ - iconfig_node_remove(parentnode, config_node->data); + iconfig_node_remove(parent_node, config_node->data); } static void channel_setup_destroy(CHANNEL_SETUP_REC *channel) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 771e3999..26632d63 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -423,17 +423,41 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) return rec; } +static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) +{ + char *address, *chatnet; + int port; + + address = config_node_get_str(node, "address", NULL); + chatnet = config_node_get_str(node, "chatnet", NULL); + port = config_node_get_int(node, "port", 0); + + if (address == NULL || chatnet == NULL) + return 1; + + if (strcmp(address, server->address) || strcmp(chatnet, server->chatnet) + || port != server->port) + return 1; + + return 0; +} + static void server_setup_save(SERVER_SETUP_REC *rec) { - CONFIG_NODE *parentnode, *node; - int index; + CONFIG_NODE *parent_node, *node; + GSList *config_node; - index = g_slist_index(setupservers, rec); + parent_node = iconfig_node_traverse("(servers", TRUE); - parentnode = iconfig_node_traverse("(servers", TRUE); - node = config_node_nth(parentnode, index); - if (node == NULL) - node = iconfig_node_section(parentnode, NULL, NODE_TYPE_BLOCK); + /* Try to find this channel in the configuration */ + config_node = g_slist_find_custom(parent_node->value, rec, + (GCompareFunc)compare_server_setup); + if (config_node != NULL) + /* Let's update this server record */ + node = config_node->data; + else + /* Create a brand-new server record */ + node = iconfig_node_section(parent_node, NULL, NODE_TYPE_BLOCK); iconfig_node_clear(node); iconfig_node_set_str(node, "address", rec->address); @@ -465,14 +489,21 @@ static void server_setup_save(SERVER_SETUP_REC *rec) static void server_setup_remove_config(SERVER_SETUP_REC *rec) { - CONFIG_NODE *node; - int index; + CONFIG_NODE *parent_node; + GSList *config_node; - node = iconfig_node_traverse("servers", FALSE); - if (node != NULL) { - index = g_slist_index(setupservers, rec); - iconfig_node_list_remove(node, index); - } + parent_node = iconfig_node_traverse("servers", FALSE); + + if (parent_node == NULL) + return; + + /* Try to find this server in the configuration */ + config_node = g_slist_find_custom(parent_node->value, rec, + (GCompareFunc)compare_server_setup); + + if (config_node != NULL) + /* Delete the server from the configuration */ + iconfig_node_remove(parent_node, config_node->data); } static void server_setup_destroy(SERVER_SETUP_REC *rec) From 1749a7a5abf9801bb663b74d4b3e7c3bcbfeb271 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 9 Dec 2015 16:16:03 +0100 Subject: [PATCH 0072/1495] Minor adjustments. Use g_strcmp0 instead of strcmp. Explicit checks added for the g_strcmp0 clauses. --- src/core/channels-setup.c | 6 ++---- src/core/servers-setup.c | 8 +++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index dd722fea..4966d77d 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -37,10 +37,8 @@ static int compare_channel_setup (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) name = config_node_get_str(node, "name", NULL); chatnet = config_node_get_str(node, "chatnet", NULL); - if (name == NULL || chatnet == NULL) - return 1; - - if (strcmp(name, channel->name) || strcmp(chatnet, channel->chatnet)) + if (g_strcmp0(name, channel->name) != 0 || + g_strcmp0(chatnet, channel->chatnet) != 0) return 1; return 0; diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 26632d63..4a048282 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -432,11 +432,9 @@ static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) chatnet = config_node_get_str(node, "chatnet", NULL); port = config_node_get_int(node, "port", 0); - if (address == NULL || chatnet == NULL) - return 1; - - if (strcmp(address, server->address) || strcmp(chatnet, server->chatnet) - || port != server->port) + if (g_strcmp0(address, server->address) != 0 || + g_strcmp0(chatnet, server->chatnet) != 0 || + port != server->port) return 1; return 0; From 96766b7f0530ca2e5b4d0fde68337f956e46eb0e Mon Sep 17 00:00:00 2001 From: dequis Date: Wed, 9 Dec 2015 15:20:59 -0300 Subject: [PATCH 0073/1495] Remove all WIN32 ifdefs (unifdef -UWIN32) Just use cygwin. This looks like it wasn't enough to do anything useful, and I don't think anyone cares about supporting win32 the hard way. --- src/common.h | 3 --- src/core/core.c | 6 ------ src/core/misc.c | 4 ---- src/core/net-disconnect.c | 2 -- src/core/net-nonblock.c | 10 ---------- src/core/net-sendbuffer.c | 4 ---- src/core/network.c | 16 ---------------- src/core/network.h | 2 -- src/fe-common/core/fe-common-core.c | 4 ---- src/fe-text/irssi.c | 17 ----------------- 10 files changed, 68 deletions(-) diff --git a/src/common.h b/src/common.h index 86a079fe..0cf951b3 100644 --- a/src/common.h +++ b/src/common.h @@ -34,9 +34,6 @@ # include #endif #include -#ifdef WIN32 -# include -#endif #include #ifdef HAVE_GMODULE diff --git a/src/core/core.c b/src/core/core.c index bbeec6f4..bf7cdd6b 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -83,7 +83,6 @@ static void sig_reload_config(int signo) static void read_settings(void) { -#ifndef WIN32 static int signals[] = { SIGINT, SIGQUIT, SIGTERM, SIGALRM, SIGUSR1, SIGUSR2 @@ -124,7 +123,6 @@ static void read_settings(void) settings_set_bool("override_coredump_limit", FALSE); } #endif -#endif } static void sig_gui_dialog(const char *type, const char *text) @@ -225,9 +223,7 @@ void core_init(void) client_start_time = time(NULL); modules_init(); -#ifndef WIN32 pidwait_init(); -#endif net_disconnect_init(); signals_init(); @@ -303,9 +299,7 @@ void core_deinit(void) signals_deinit(); net_disconnect_deinit(); -#ifndef WIN32 pidwait_deinit(); -#endif modules_deinit(); g_free(irssi_dir); diff --git a/src/core/misc.c b/src/core/misc.c index 490b5a8f..aaa470f5 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -430,11 +430,7 @@ int mkpath(const char *path, int mode) dir = g_strndup(path, (int) (p-path)); if (stat(dir, &statbuf) != 0) { -#ifndef WIN32 if (mkdir(dir, mode) == -1) -#else - if (_mkdir(dir) == -1) -#endif { g_free(dir); return -1; diff --git a/src/core/net-disconnect.c b/src/core/net-disconnect.c index 321f79ac..6476e776 100644 --- a/src/core/net-disconnect.c +++ b/src/core/net-disconnect.c @@ -116,7 +116,6 @@ void net_disconnect_init(void) void net_disconnect_deinit(void) { -#ifndef WIN32 NET_DISCONNECT_REC *rec; time_t now, max; int first, fd; @@ -155,5 +154,4 @@ void net_disconnect_deinit(void) first = 0; } } -#endif } diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index e637e673..d6e767b6 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -77,14 +77,11 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, { RESOLVED_IP_REC rec; const char *errorstr; -#ifndef WIN32 int pid; -#endif int len; g_return_val_if_fail(addr != NULL, FALSE); -#ifndef WIN32 pid = fork(); if (pid > 0) { /* parent */ @@ -97,7 +94,6 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, g_warning("net_connect_thread(): fork() failed! " "Using blocking resolving"); } -#endif /* child */ srand(time(NULL)); @@ -138,10 +134,8 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, } } -#ifndef WIN32 if (pid == 0) _exit(99); -#endif /* we used blocking lookup */ return 0; @@ -157,9 +151,7 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) rec->host4 = NULL; rec->host6 = NULL; -#ifndef WIN32 fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); -#endif /* get ip+error */ if (g_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1) { @@ -201,9 +193,7 @@ void net_disconnect_nonblock(int pid) { g_return_if_fail(pid > 0); -#ifndef WIN32 kill(pid, SIGKILL); -#endif } static void simple_init(SIMPLE_THREAD_REC *rec, GIOChannel *handle) diff --git a/src/core/net-sendbuffer.c b/src/core/net-sendbuffer.c index 39257486..97fb551f 100644 --- a/src/core/net-sendbuffer.c +++ b/src/core/net-sendbuffer.c @@ -160,13 +160,9 @@ void net_sendbuffer_flush(NET_SENDBUF_REC *rec) /* set the socket blocking while doing this */ handle = g_io_channel_unix_get_fd(rec->handle); -#ifndef WIN32 fcntl(handle, F_SETFL, 0); -#endif while (!buffer_send(rec)) ; -#ifndef WIN32 fcntl(handle, F_SETFL, O_NONBLOCK); -#endif } /* Returns the socket handle */ diff --git a/src/core/network.c b/src/core/network.c index bfaa47fb..0751aa95 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -45,11 +45,7 @@ union sockaddr_union { GIOChannel *g_io_channel_new(int handle) { GIOChannel *chan; -#ifdef WIN32 - chan = g_io_channel_win32_new_socket(handle); -#else chan = g_io_channel_unix_new(handle); -#endif g_io_channel_set_encoding(chan, NULL, NULL); g_io_channel_set_buffered(chan, FALSE); return chan; @@ -188,9 +184,7 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) return NULL; /* set socket options */ -#ifndef WIN32 fcntl(handle, F_SETFL, O_NONBLOCK); -#endif setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); @@ -211,11 +205,7 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) sin_set_port(&so, port); ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so)); -#ifndef WIN32 if (ret < 0 && errno != EINPROGRESS) -#else - if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) -#endif { int old_errno = errno; close(handle); @@ -238,9 +228,7 @@ GIOChannel *net_connect_unix(const char *path) return NULL; /* set socket options */ -#ifndef WIN32 fcntl(handle, F_SETFL, O_NONBLOCK); -#endif /* connect */ memset(&sa, 0, sizeof(sa)); @@ -297,9 +285,7 @@ GIOChannel *net_listen(IPADDR *my_ip, int *port) return NULL; /* set socket options */ -#ifndef WIN32 fcntl(handle, F_SETFL, O_NONBLOCK); -#endif setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); @@ -342,9 +328,7 @@ GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port) if (addr != NULL) sin_get_ip(&so, addr); if (port != NULL) *port = sin_get_port(&so); -#ifndef WIN32 fcntl(ret, F_SETFL, O_NONBLOCK); -#endif return g_io_channel_new(ret); } diff --git a/src/core/network.h b/src/core/network.h index fa7e9675..73ac8dee 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -6,12 +6,10 @@ #endif #include -#ifndef WIN32 # include # include # include # include -#endif #ifndef AF_INET6 # ifdef PF_INET6 diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index a15850e2..ee7f9424 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -168,9 +168,7 @@ void fe_common_core_init(void) keyboard_init(); printtext_init(); formats_init(); -#ifndef WIN32 fe_exec_init(); -#endif fe_expandos_init(); fe_help_init(); fe_ignore_init(); @@ -211,9 +209,7 @@ void fe_common_core_deinit(void) keyboard_deinit(); printtext_deinit(); formats_deinit(); -#ifndef WIN32 fe_exec_deinit(); -#endif fe_expandos_deinit(); fe_help_deinit(); fe_ignore_deinit(); diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index b1fa5e22..cad271c9 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -271,20 +271,6 @@ static void check_files(void) } } -#ifdef WIN32 -static void winsock_init(void) -{ - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - if (WSAStartup(wVersionRequested, &wsaData) != 0) { - printf("Error initializing winsock\n"); - exit(1); - } -} -#endif int main(int argc, char **argv) { @@ -315,9 +301,6 @@ int main(int argc, char **argv) check_files(); -#ifdef WIN32 - winsock_init(); -#endif #ifdef HAVE_SOCKS SOCKSinit(argv[0]); #endif From ff8ccaf08b60d88a67ddf810f8229f910f016cf7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Nov 2015 00:08:20 +0100 Subject: [PATCH 0074/1495] module check irssi version Add explicit checks into every module to match the ABI version defined in common.h --- src/common.h | 2 ++ src/core/expandos.c | 9 +++++++++ src/core/modules-load.c | 26 +++++++++++++++++++++++++- src/core/modules.h | 1 + src/fe-common/core/fe-modules.c | 4 ++++ src/fe-common/core/module-formats.c | 1 + src/fe-common/core/module-formats.h | 1 + src/irc/proxy/proxy.c | 5 +++++ src/perl/perl-core.c | 5 +++++ src/perl/perl-fe.c | 5 +++++ 10 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 0cf951b3..966e28d0 100644 --- a/src/common.h +++ b/src/common.h @@ -6,6 +6,8 @@ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ +#define IRSSI_ABI_VERSION 1 + #define DEFAULT_SERVER_ADD_PORT 6667 #ifdef HAVE_CONFIG_H diff --git a/src/core/expandos.c b/src/core/expandos.c index 1fc517af..67aea837 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -414,6 +414,13 @@ static char *expando_releasetime(SERVER_REC *server, void *item, int *free_ret) return g_strdup_printf("%04d", IRSSI_VERSION_TIME); } +/* client abi */ +static char *expando_abiversion(SERVER_REC *server, void *item, int *free_ret) +{ + *free_ret = TRUE; + return g_strdup_printf("%d", IRSSI_ABI_VERSION); +} + /* current working directory */ static char *expando_workdir(SERVER_REC *server, void *item, int *free_ret) { @@ -658,6 +665,8 @@ void expandos_init(void) "", EXPANDO_NEVER, NULL); expando_create("versiontime", expando_releasetime, "", EXPANDO_NEVER, NULL); + expando_create("abiversion", expando_abiversion, + "", EXPANDO_NEVER, NULL); expando_create("W", expando_workdir, NULL); expando_create("Y", expando_realname, "window changed", EXPANDO_ARG_NONE, diff --git a/src/core/modules-load.c b/src/core/modules-load.c index 6086d9ae..9baac1d7 100644 --- a/src/core/modules-load.c +++ b/src/core/modules-load.c @@ -160,11 +160,14 @@ static int module_load_name(const char *path, const char *rootmodule, { void (*module_init) (void); void (*module_deinit) (void); + void (*module_version) (int *); GModule *gmodule; MODULE_REC *module; MODULE_FILE_REC *rec; + gpointer value_version = NULL; gpointer value1, value2 = NULL; - char *initfunc, *deinitfunc; + char *versionfunc, *initfunc, *deinitfunc; + int module_abi_version = 0; int found; gmodule = module_open(path, &found); @@ -176,6 +179,27 @@ static int module_load_name(const char *path, const char *rootmodule, return found ? 0 : -1; } + /* get the module's irssi abi version and bail out on mismatch */ + versionfunc = module_get_func(rootmodule, submodule, "abicheck"); + if (!g_module_symbol(gmodule, versionfunc, &value_version)) { + g_free(versionfunc); + module_error(MODULE_ERROR_VERSION_MISMATCH, "0", + rootmodule, submodule); + g_module_close(gmodule); + return 0; + } + g_free(versionfunc); + module_version = value_version; + module_version(&module_abi_version); + if (module_abi_version != IRSSI_ABI_VERSION) { + char *module_abi_versionstr = g_strdup_printf("%d", module_abi_version); + module_error(MODULE_ERROR_VERSION_MISMATCH, module_abi_versionstr, + rootmodule, submodule); + g_free(module_abi_versionstr); + g_module_close(gmodule); + return 0; + } + /* get the module's init() and deinit() functions */ initfunc = module_get_func(rootmodule, submodule, "init"); deinitfunc = module_get_func(rootmodule, submodule, "deinit"); diff --git a/src/core/modules.h b/src/core/modules.h index 75a77c77..b2fa2fa4 100644 --- a/src/core/modules.h +++ b/src/core/modules.h @@ -27,6 +27,7 @@ enum { MODULE_ERROR_ALREADY_LOADED, MODULE_ERROR_LOAD, + MODULE_ERROR_VERSION_MISMATCH, MODULE_ERROR_INVALID }; diff --git a/src/fe-common/core/fe-modules.c b/src/fe-common/core/fe-modules.c index df97ceb1..27b6b4c1 100644 --- a/src/fe-common/core/fe-modules.c +++ b/src/fe-common/core/fe-modules.c @@ -43,6 +43,10 @@ static void sig_module_error(void *number, const char *data, printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_MODULE_LOAD_ERROR, rootmodule, submodule, data); break; + case MODULE_ERROR_VERSION_MISMATCH: + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_MODULE_VERSION_MISMATCH, rootmodule, submodule, data); + break; case MODULE_ERROR_INVALID: printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_MODULE_INVALID, rootmodule, submodule); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 4ae26950..e6d32b6d 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -196,6 +196,7 @@ FORMAT_REC fecommon_core_formats[] = { { "module_already_loaded", "Module {hilight $0/$1} already loaded", 2, { 0, 0 } }, { "module_not_loaded", "Module {hilight $0/$1} is not loaded", 2, { 0, 0 } }, { "module_load_error", "Error loading module {hilight $0/$1}: $2", 3, { 0, 0, 0 } }, + { "module_version_mismatch", "{hilight $0/$1} is ABI version $2 but Irssi is version $abiversion, cannot load", 3, { 0, 0, 0 } }, { "module_invalid", "{hilight $0/$1} isn't Irssi module", 2, { 0, 0 } }, { "module_loaded", "Loaded module {hilight $0/$1}", 2, { 0, 0 } }, { "module_unloaded", "Unloaded module {hilight $0/$1}", 2, { 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index 18bf91f5..3f06bb97 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -166,6 +166,7 @@ enum { TXT_MODULE_ALREADY_LOADED, TXT_MODULE_NOT_LOADED, TXT_MODULE_LOAD_ERROR, + TXT_MODULE_VERSION_MISMATCH, TXT_MODULE_INVALID, TXT_MODULE_LOADED, TXT_MODULE_UNLOADED, diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c index ce79e2b7..50a41b21 100644 --- a/src/irc/proxy/proxy.c +++ b/src/irc/proxy/proxy.c @@ -108,3 +108,8 @@ void irc_proxy_deinit(void) { proxy_listen_deinit(); } + +void irc_proxy_abicheck(int *version) +{ + *version = IRSSI_ABI_VERSION; +} diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 793f9375..2f28c718 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -466,3 +466,8 @@ void perl_core_deinit(void) signal_remove("script error", (SIGNAL_FUNC) sig_script_error); PERL_SYS_TERM(); } + +void perl_core_abicheck(int *version) +{ + *version = IRSSI_ABI_VERSION; +} diff --git a/src/perl/perl-fe.c b/src/perl/perl-fe.c index 2abc75c0..04305b63 100644 --- a/src/perl/perl-fe.c +++ b/src/perl/perl-fe.c @@ -278,3 +278,8 @@ void fe_perl_deinit(void) perl_core_print_script_error(TRUE); } + +void fe_perl_abicheck(int *version) +{ + *version = IRSSI_ABI_VERSION; +} From 9dd2b7c616e48a7525e72d6798a0adae34720616 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 10 Dec 2015 14:02:59 +0100 Subject: [PATCH 0075/1495] deinit perl on staticperl builds --- src/perl/perl-core.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 793f9375..2c0ca49d 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -82,16 +82,18 @@ static void perl_script_destroy(PERL_SCRIPT_REC *script) extern void boot_DynaLoader(pTHX_ CV* cv); #if PERL_STATIC_LIBS == 1 -extern void boot_Irssi(CV *cv); +extern void boot_Irssi(pTHX_ CV *cv); XS(boot_Irssi_Core) { dXSARGS; + PERL_UNUSED_VAR(items); irssi_callXS(boot_Irssi, cv, mark); irssi_boot(Irc); irssi_boot(UI); irssi_boot(TextUI); + /* Make sure to keep this in line with perl_scripts_deinit below. */ XSRETURN_YES; } #endif @@ -155,6 +157,17 @@ void perl_scripts_deinit(void) /* Unload all perl libraries loaded with dynaloader */ perl_eval_pv("foreach my $lib (@DynaLoader::dl_modules) { if ($lib =~ /^Irssi\\b/) { $lib .= '::deinit();'; eval $lib; } }", TRUE); +#if PERL_STATIC_LIBS == 1 + /* If perl is statically built we should manually deinit the modules + which are booted in boot_Irssi_Core above */ + perl_eval_pv("foreach my $lib (qw(" + "Irssi" " " + "Irssi::Irc" " " + "Irssi::UI" " " + "Irssi::TextUI" + ")) { eval $lib . '::deinit();'; }", TRUE); +#endif + /* We could unload all libraries .. but this crashes with some libraries, probably because we don't call some deinit function.. Anyway, this would free some memory with /SCRIPT RESET, but it From 0b1a912f822b21e5c4dfc18436ab5b90f079e19b Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 11 Dec 2015 21:31:04 -0300 Subject: [PATCH 0076/1495] Makefile.am: Add default-config.h and default-theme.h to CLEANFILES Fixes issues when building from other directories when the source tree was already configured before, as found in the comments of PR #375 --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 6ca69fc7..75d502f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} # create default-config.h BUILT_SOURCES = default-config.h default-theme.h irssi-version.h +CLEANFILES = default-config.h default-theme.h @MAINTAINER_MODE_TRUE@.PHONY: irssi-version.h From 38d372eccb3745a7734b8f8963ae572d1343c5b1 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 12 Dec 2015 01:17:48 -0300 Subject: [PATCH 0077/1495] Disable timeout-based paste detection if paste_use_bracketed_mode is on --- src/fe-text/gui-readline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 96b8b386..a9755318 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -737,7 +737,7 @@ static void sig_input(void) if (paste_bracketed_mode) { paste_bracketed_middle(); - } else if (paste_detect_time > 0 && paste_buffer->len >= 3) { + } else if (!paste_use_bracketed_mode && paste_detect_time > 0 && paste_buffer->len >= 3) { if (paste_timeout_id != -1) g_source_remove(paste_timeout_id); paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL); From e6fa311590da78d05e9eea42d3664cec01c9b1ae Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 12 Dec 2015 01:44:05 -0300 Subject: [PATCH 0078/1495] Bracketed paste: Adjust paste line count if there's text after newlines With bracketed paste, "a\nb" will result in two lines being pasted, because it's a single thing, with an end marker which the timeout based pastes don't have. Due to the way term_gets() counts lines, that input will have paste_line_count == 1. This can be misleading. This code adjusts it by looking at the last character, and increasing the count if it finds anything that isn't a newline. --- src/fe-text/gui-readline.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index a9755318..851cbbe6 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -660,6 +660,8 @@ static gboolean paste_timeout(gpointer data) static void paste_bracketed_end(int i, gboolean rest) { + unichar last_char; + /* if there's stuff after the end bracket, save it for later */ if (rest) { unichar *start = ((unichar *) paste_buffer->data) + i + G_N_ELEMENTS(bp_end); @@ -672,6 +674,14 @@ static void paste_bracketed_end(int i, gboolean rest) /* remove the rest, including the trailing sequence chars */ g_array_set_size(paste_buffer, i); + last_char = g_array_index(paste_buffer, unichar, i - 1); + + if (paste_line_count > 0 && last_char != '\n' && last_char != '\r') { + /* there are newlines, but there's also stuff after the newline + * adjust line count to reflect this */ + paste_line_count++; + } + /* decide what to do with the buffer */ paste_timeout(NULL); From 6e01a2313439bb02a66a52db645f63f078c2c4b0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Dec 2015 01:08:53 +0100 Subject: [PATCH 0079/1495] ensure staticlib perl works on 5.22 (for now) --- src/perl/perl-common.c | 3 --- src/perl/perl-core.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index d7a428e5..b641867f 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -246,10 +246,7 @@ char *perl_get_use_list(void) void irssi_callXS(void (*subaddr)(pTHX_ CV* cv), CV *cv, SV **mark) { - dSP; - PUSHMARK(mark); - PUTBACK; (*subaddr)(aTHX_ cv); } diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 2c0ca49d..1a864ef7 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -125,7 +125,7 @@ void perl_scripts_init(void) perl_parse(my_perl, xs_init, G_N_ELEMENTS(perl_args), perl_args, NULL); #if PERL_STATIC_LIBS == 1 - perl_eval_pv("Irssi::Core::boot_Irssi_Core();", TRUE); + perl_eval_pv("Irssi::Core::->boot_Irssi_Core(0.9);", TRUE); #endif perl_common_start(); From ce77842a985edc82aa1ca30c83c4edfe904872aa Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 13 Dec 2015 13:56:09 -0300 Subject: [PATCH 0080/1495] Bracketed paste: fix nitpick from ahf's review Thanks ahf --- src/fe-text/gui-readline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 851cbbe6..f531d282 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -339,7 +339,7 @@ static void paste_flush(int send) g_array_set_size(paste_buffer, 0); /* re-add anything that may have been after the bracketed paste end */ - if (paste_buffer_rest->len) { + if (paste_buffer_rest->len > 0) { g_array_append_vals(paste_buffer, paste_buffer_rest->data, paste_buffer_rest->len); g_array_set_size(paste_buffer_rest, 0); } From 620d0a9299d31e3f9b59233904151cdce4519526 Mon Sep 17 00:00:00 2001 From: mh Date: Mon, 14 Dec 2015 19:12:47 +0100 Subject: [PATCH 0081/1495] script should be plural --- docs/perl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/perl.txt b/docs/perl.txt index 560fcaec..9688341f 100644 --- a/docs/perl.txt +++ b/docs/perl.txt @@ -10,7 +10,7 @@ INSTALL file for information about perl problems. --------------- Scripts are run with /SCRIPT LOAD command, or the default /RUN alias. -"/SCRIPT" shows list of running script, and /SCRIPT UNLOAD can unload +"/SCRIPT" shows list of running scripts, and /SCRIPT UNLOAD can unload scripts. Scripts should be placed to ~/.irssi/scripts/ or From 5fbad764df7b96618553a45facde73edb5e7bb9c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 15 Dec 2015 00:08:44 +0100 Subject: [PATCH 0082/1495] clean up after #303 --- src/fe-common/core/formats.h | 1 - src/fe-common/core/hilight-text.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 484105f9..a4b26852 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -45,7 +45,6 @@ struct _FORMAT_REC { #define PRINT_FLAG_SET_SERVERTAG 0x0010 #define PRINT_FLAG_UNSET_SERVERTAG 0x0020 -// FIXME: sould use better typedef struct _HILIGHT_REC HILIGHT_REC; typedef struct _TEXT_DEST_REC { diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index fa083882..3c897def 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -7,8 +7,6 @@ #include "formats.h" -//typedef struct _HILIGHT_REC HILIGHT_REC; - struct _HILIGHT_REC { char *text; From e4e040929b247b2432190b84b6edca997dacd600 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 15 Dec 2015 01:52:44 +0100 Subject: [PATCH 0083/1495] option to clear the history --- src/fe-common/core/command-history.c | 45 ++++++++++++++++++++++++---- src/fe-common/core/command-history.h | 1 + src/fe-common/core/fe-windows.c | 7 ++++- src/fe-common/core/fe-windows.h | 1 + src/fe-common/core/window-commands.c | 21 +++++++++++-- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index f9c3884c..9f46ee99 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -33,6 +33,7 @@ static HISTORY_REC *global_history; static int window_history; static GSList *histories; +static HISTORY_REC *last_cleared_history; void command_history_add(HISTORY_REC *history, const char *text) { @@ -41,6 +42,13 @@ void command_history_add(HISTORY_REC *history, const char *text) g_return_if_fail(history != NULL); g_return_if_fail(text != NULL); + if (last_cleared_history == history) { + last_cleared_history = NULL; + return; /* ignore this history addition, we just + cleared it */ + } + last_cleared_history = NULL; + link = g_list_last(history->list); if (link != NULL && g_strcmp0(link->data, text) == 0) return; /* same as previous entry */ @@ -94,13 +102,13 @@ HISTORY_REC *command_history_current(WINDOW_REC *window) if (window == NULL) return global_history; - if (window_history) - return window->history; - rec = command_history_find_name(window->history_name); if (rec != NULL) return rec; + if (window_history) + return window->history; + return global_history; } @@ -178,6 +186,18 @@ HISTORY_REC *command_history_create(const char *name) return rec; } +void command_history_clear(HISTORY_REC *history) +{ + g_return_if_fail(history != NULL); + + command_history_clear_pos_func(history, NULL); + g_list_foreach(history->list, (GFunc) g_free, NULL); + g_list_free(history->list); + history->list = NULL; + history->lines = 0; + last_cleared_history = history; +} + void command_history_destroy(HISTORY_REC *history) { g_return_if_fail(history != NULL); @@ -186,9 +206,8 @@ void command_history_destroy(HISTORY_REC *history) g_return_if_fail(history->refcount == 0); histories = g_slist_remove(histories, history); - - g_list_foreach(history->list, (GFunc) g_free, NULL); - g_list_free(history->list); + command_history_clear(history); + last_cleared_history = NULL; /* was destroyed */ g_free_not_null(history->name); g_free(history); @@ -229,6 +248,18 @@ static void sig_window_destroyed(WINDOW_REC *window) g_free_not_null(window->history_name); } +static void sig_window_history_cleared(WINDOW_REC *window, const char *name) { + HISTORY_REC *history; + + if (name == NULL || *name == '\0') { + history = command_history_current(window); + } else { + history = command_history_find_name(name); + } + + command_history_clear(history); +} + static void sig_window_history_changed(WINDOW_REC *window, const char *oldname) { command_history_link(window->history_name); @@ -279,6 +310,7 @@ void command_history_init(void) signal_add("window created", (SIGNAL_FUNC) sig_window_created); signal_add("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); signal_add("window history changed", (SIGNAL_FUNC) sig_window_history_changed); + signal_add_last("window history cleared", (SIGNAL_FUNC) sig_window_history_cleared); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } @@ -287,6 +319,7 @@ void command_history_deinit(void) signal_remove("window created", (SIGNAL_FUNC) sig_window_created); signal_remove("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); signal_remove("window history changed", (SIGNAL_FUNC) sig_window_history_changed); + signal_remove("window history cleared", (SIGNAL_FUNC) sig_window_history_cleared); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_history_destroy(global_history); diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 7b76246b..a572216b 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -28,6 +28,7 @@ const char *command_history_next(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); HISTORY_REC *command_history_create(const char *name); +void command_history_clear(HISTORY_REC *history); void command_history_destroy(HISTORY_REC *history); void command_history_link(const char *name); void command_history_unlink(const char *name); diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 1049137f..46c1593b 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -229,11 +229,16 @@ void window_set_history(WINDOW_REC *window, const char *name) else window->history_name = g_strdup(name); - signal_emit("window history changed", 1, window, oldname); + signal_emit("window history changed", 2, window, oldname); g_free_not_null(oldname); } +void window_clear_history(WINDOW_REC *window, const char *name) +{ + signal_emit("window history cleared", 2, window, name); +} + void window_set_level(WINDOW_REC *window, int level) { g_return_if_fail(window != NULL); diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 613f15f8..32d6cfcd 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -66,6 +66,7 @@ void window_change_server(WINDOW_REC *window, void *server); void window_set_refnum(WINDOW_REC *window, int refnum); void window_set_name(WINDOW_REC *window, const char *name); void window_set_history(WINDOW_REC *window, const char *name); +void window_clear_history(WINDOW_REC *window, const char *name); void window_set_level(WINDOW_REC *window, int level); void window_set_immortal(WINDOW_REC *window, int immortal); diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index c6ab68c0..e5005144 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -33,6 +33,7 @@ #include "window-items.h" #include "windows-layout.h" #include "printtext.h" +#include "command-history.h" static void window_print_binds(WINDOW_REC *win) { @@ -615,10 +616,25 @@ static void cmd_window_name(const char *data) } } -/* SYNTAX: WINDOW HISTORY */ +/* SYNTAX: WINDOW HISTORY [-clear] */ void cmd_window_history(const char *data) { - window_set_history(active_win, data); + GHashTable *optlist; + char *name; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, + "window history", &optlist, &name)) + return; + + if (g_hash_table_lookup(optlist, "clear") != NULL) { + signal_continue(1, data); + window_clear_history(active_win, name); + } else { + window_set_history(active_win, name); + } + + cmd_params_free(free_arg); } /* we're moving the first window to last - move the first contiguous block @@ -883,6 +899,7 @@ void window_commands_init(void) command_set_options("window number", "sticky"); command_set_options("window server", "sticky unsticky"); command_set_options("window theme", "delete"); + command_set_options("window history", "clear"); } void window_commands_deinit(void) From 653fd590aff1d2f602ceef999b3df2719e0835b1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Dec 2015 12:35:27 +0100 Subject: [PATCH 0084/1495] add new authors since 0.8.17 --- AUTHORS | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index d2cb58c0..dc8e578c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,6 +11,8 @@ Irssi staff (current maintainers) : Jilles Tjoelker (jilles) Alexander Færøy (ahf) Jase Thew (bazerka) + dequis (dx) + Ailin Nemui (Nei) Former developers: @@ -24,6 +26,7 @@ Large feature patches by: Heikki Orsila : DCC SEND queueing Mark Trumbull : DCC SERVER Francesco Fracassi : Passive DCC + Giuseppe (The Lemon Man) Other patches (grep for "patch" in ChangeLog) by: @@ -78,6 +81,20 @@ Other patches (grep for "patch" in ChangeLog) by: Ismael Luceno Thomas Karpiniec Svante Kvarnström - Ailin Nemui (Nei) Tom Feist (shabble) - Sebastian Thorarensen + Sebastian Thorarensen (Sebban) + Hans Nielsen + Jari Matilainen (vague) + Thibault B (isundil) + kyak + Vesa Pirila (Lohhari) + Haw Loeung + François Revol (mmuman) + blha303 + Guillaume Brogi (guiniol) + Adam- + Robert C Jensen + Paul Johnson + mauke + KindOne + Fabian Kurz From ab809d8d2a9cfb3f0d879c098f2d2d88ce60d3fe Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Dec 2015 14:14:41 +0100 Subject: [PATCH 0085/1495] list NEWS since 0.8.17 --- NEWS | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 511f495a..c37129bb 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,57 @@ -v0.8.18-head 2014-XX-YY The Irssi team - + Garbage Collection support has been removed. This will hardly have any +v0.8.18-rc1 2015-12-15 The Irssi team + * Modules will now require to define a + void MODULENAME ## _abicheck(int *version) + method to ensure that they are compiled against the correct Irssi + version. + * The signature of "message private" has been changed to + 5: server, message, nick, address, target + in order to support "self messages". Module authors should + implement this change if they are using this signal. + * Removing networks will now remove all attached servers and channels + (#45). + * /proxy command has been renamed to /irssiproxy + * sb_search has been moved to scripts.irssi.org + * WIN32 has been completely removed (it had not been working and is + lacking a maintainer.) + * Garbage Collection support has been removed. This will hardly have any effect for anyone given that it has been unsupported for several years. - + Disable SSLv3 due to the POODLE vulnerability. + + CAP SASL PLAIN login is now supported natively. + + Paste bracket markers can be requested from terminal with + /set paste_use_bracketed_mode on + + "Self messages" generated by some bouncers can now be received in the + proper window. + Try to split long lines on spaces to avoid words being splitted. Adds a new option: 'split_line_on_space' which defaults to on. + + Add setting hilight_nick_matches_everywhere (#56). + + The config parser is more robust and prints out better diagnostics on + incorrect config files. + + Ctrl+^ (FS#721) and Ctrl+J can now be bound. + + Command history can be cleared with /window history -clear + + /hilight -mask -line is now supported (FS#275). + + CHANTYPES are now supported. + + Improved reload speed of ignores. + + Add -date feature to /lastlog + + irssiproxy can be more easily enabled and disabled. + + Expando for hostname (FS#829). + + UNIX sockets can now also be specified in the config file. + + Disable SSLv3 due to the POODLE vulnerability. + + SSL ciphers can now be specified per server. + + Added SNI support for SSL. + - irssiproxy (BNC) module now uses correct line endings. + - Fix missing lines on large pastes (FS#905). + - Correctly preserve STATUSMSG prefixes (#291). + - Fix infinite recursion in key bindings (FS#817). + - Fix incomplete awaylog caused by buffering. + - Fix calculation of UTF-8 string length display in some cases. + - Fix some Perl warnings related to @ISA. + - EXEC windowitems now get proper references on the Perl side. + - Incremental help file improvements. + - ANSI attributes are now properly reset. + - Fixed regression where text would blink when terminal lacks color + support. + - Permit the usage of Freenode extban syntax in /ban (#150) + - Fixed regression in scriptassist on unload of scripts. + - Fixed regression in -actcolor %n v0.8.17 2014-10-11 The Irssi team + Document that SSL connections aren't properly handled during /UPGRADE. See Github PR #39. From 77143aee7dcff85f0b8656543c185a9e6a8131bb Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Dec 2015 14:17:33 +0100 Subject: [PATCH 0086/1495] remove mention of ./autogen.sh from releases INSTALL --- INSTALL | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/INSTALL b/INSTALL index 234c6cf6..a83a6c76 100644 --- a/INSTALL +++ b/INSTALL @@ -11,8 +11,7 @@ To compile irssi you need: For most people, this should work just fine: - ./autogen.sh (for people who just cloned the repository) - ./configure (if this script already exists, skip ./autogen.sh) + ./configure make su make install (not _really_ required except for perl support) From d495111bde29796430e34832f15025f3708a7166 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 15 Dec 2015 10:59:23 +0100 Subject: [PATCH 0087/1495] tag as 0.8.18-beta1 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c0efd5e3..92ca04ae 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 0.8.18-head) +AC_INIT(irssi, 0.8.18-beta1) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From 74eb556c504271129f44268870d34c011804d7e4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Dec 2015 12:35:27 +0100 Subject: [PATCH 0088/1495] add new authors since 0.8.17 --- AUTHORS | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index d2cb58c0..dc8e578c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,6 +11,8 @@ Irssi staff (current maintainers) : Jilles Tjoelker (jilles) Alexander Færøy (ahf) Jase Thew (bazerka) + dequis (dx) + Ailin Nemui (Nei) Former developers: @@ -24,6 +26,7 @@ Large feature patches by: Heikki Orsila : DCC SEND queueing Mark Trumbull : DCC SERVER Francesco Fracassi : Passive DCC + Giuseppe (The Lemon Man) Other patches (grep for "patch" in ChangeLog) by: @@ -78,6 +81,20 @@ Other patches (grep for "patch" in ChangeLog) by: Ismael Luceno Thomas Karpiniec Svante Kvarnström - Ailin Nemui (Nei) Tom Feist (shabble) - Sebastian Thorarensen + Sebastian Thorarensen (Sebban) + Hans Nielsen + Jari Matilainen (vague) + Thibault B (isundil) + kyak + Vesa Pirila (Lohhari) + Haw Loeung + François Revol (mmuman) + blha303 + Guillaume Brogi (guiniol) + Adam- + Robert C Jensen + Paul Johnson + mauke + KindOne + Fabian Kurz From 64463933fdb923cdc55fcd105c8e35d61546e62e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Dec 2015 14:14:41 +0100 Subject: [PATCH 0089/1495] list NEWS since 0.8.17 --- NEWS | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 511f495a..8db80f80 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,52 @@ -v0.8.18-head 2014-XX-YY The Irssi team - + Garbage Collection support has been removed. This will hardly have any +v0.8.18-head 2016-xx-xx The Irssi team + * The signature of "message private" has been changed to + 5: server, message, nick, address, target + in order to support "self messages". Module authors should + implement this change if they are using this signal. + * Removing networks will now remove all attached servers and channels + (#45). + * The proxy module now has an /irssiproxy command. + * sb_search has been moved to scripts.irssi.org + * WIN32 has been completely removed (it had not been working and is + lacking a maintainer.) + * Garbage Collection support has been removed. This will hardly have any effect for anyone given that it has been unsupported for several years. - + Disable SSLv3 due to the POODLE vulnerability. + + CAP SASL PLAIN login is now supported natively. + + Paste bracket markers can be requested from terminal with + /set paste_use_bracketed_mode on + + "Self messages" generated by some bouncers can now be received in the + proper window. + Try to split long lines on spaces to avoid words being splitted. Adds a new option: 'split_line_on_space' which defaults to on. + + Add setting hilight_nick_matches_everywhere (#56). + + The config parser is more robust and prints out better diagnostics on + incorrect config files. + + Ctrl+^ (FS#721) and Ctrl+J can now be bound. + + /hilight -mask -line is now supported (FS#275). + + CHANTYPES are now supported. + + Improved reload speed of ignores. + + Add -date feature to /lastlog + + irssiproxy can be more easily enabled and disabled. + + Expando for hostname (FS#829). + + UNIX sockets can now also be specified in the config file. + + Disable SSLv3 due to the POODLE vulnerability. + + SSL ciphers can now be specified per server. + + Added SNI support for SSL. + - irssiproxy (BNC) module now uses correct line endings. + - Fix missing lines on large pastes (FS#905). + - Correctly preserve STATUSMSG prefixes (#291). + - Fix infinite recursion in key bindings (FS#817). + - Fix incomplete awaylog caused by buffering. + - Fix calculation of UTF-8 string length display in some cases. + - Fix some Perl warnings related to @ISA. + - EXEC windowitems now get proper references on the Perl side. + - Incremental help file improvements. + - ANSI attributes are now properly reset. + - Fixed regression where text would blink when terminal lacks color + support. + - Permit the usage of Freenode extban syntax in /ban (#150) + - Fixed regression in scriptassist on unload of scripts. + - Fixed regression in -actcolor %n v0.8.17 2014-10-11 The Irssi team + Document that SSL connections aren't properly handled during /UPGRADE. See Github PR #39. From f6d4b11079e0e8c2619989e3550a8ebd161eb1ae Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 22 Dec 2015 00:51:57 +0100 Subject: [PATCH 0090/1495] correct incorrect pre-release tag in NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index c37129bb..6155f7bd 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -v0.8.18-rc1 2015-12-15 The Irssi team +v0.8.18-beta1 2015-12-15 The Irssi team * Modules will now require to define a void MODULENAME ## _abicheck(int *version) method to ensure that they are compiled against the correct Irssi From c6a85721a6e9d5a6f67f76f0062c750146c6805f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 28 Dec 2015 00:07:42 +0100 Subject: [PATCH 0091/1495] keep track of address in text_dest for hilight purposes --- src/fe-common/core/fe-messages.c | 10 ++++------ src/fe-common/core/formats.c | 2 -- src/fe-common/core/formats.h | 5 ++--- src/fe-common/core/hilight-text.c | 7 ++++--- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index e06a4571..3240fd10 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -175,7 +175,6 @@ static void sig_message_public(SERVER_REC *server, const char *msg, int for_me, print_channel, level; char *nickmode, *color, *freemsg = NULL; HILIGHT_REC *hilight; - int match_beg = 0, match_end = 0; /* NOTE: this may return NULL if some channel is just closed with /WINDOW CLOSE and server still sends the few last messages */ @@ -188,8 +187,8 @@ static void sig_message_public(SERVER_REC *server, const char *msg, nick_match_msg(chanrec, msg, server->nick) : nick_match_msg_everywhere(chanrec, msg, server->nick); hilight = for_me ? NULL : - hilight_match(server, target, nick, address, MSGLEVEL_PUBLIC, msg, &match_beg, &match_end); - color = (hilight == NULL || !hilight->nick) ? NULL : hilight_get_color(hilight); + hilight_match_nick(server, target, nick, address, MSGLEVEL_PUBLIC, msg); + color = (hilight == NULL) ? NULL : hilight_get_color(hilight); print_channel = chanrec == NULL || !window_item_is_active((WI_ITEM_REC *) chanrec); @@ -217,9 +216,8 @@ static void sig_message_public(SERVER_REC *server, const char *msg, TEXT_DEST_REC dest; format_create_dest(&dest, server, target, level, NULL); - dest.hilight = hilight; - dest.match_beg = match_beg; - dest.match_end = match_end; + dest.address = address; + dest.nick = nick; if (color != NULL) { /* highlighted nick */ hilight_update_text_dest(&dest,hilight); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index b95b3966..ccf48394 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -416,8 +416,6 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, dest->server_tag = server != NULL ? SERVER(server)->tag : server_tag; dest->target = target; dest->level = level; - dest->match_beg = 0; - dest->match_end = 0; dest->window = window != NULL ? window : window_find_closest(server, target, level); } diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index a4b26852..8efd204c 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -52,11 +52,10 @@ typedef struct _TEXT_DEST_REC { SERVER_REC *server; const char *server_tag; /* if server is non-NULL, must be server->tag */ const char *target; + const char *nick; + const char *address; int level; - HILIGHT_REC *hilight; - int match_beg; - int match_end; int hilight_priority; char *hilight_color; int flags; diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 2c0075ec..b746f636 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -325,9 +325,10 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, if (dest->level & MSGLEVEL_NOHILIGHT) return; - hilight_start = dest->match_beg; - hilight_end = dest->match_end; - hilight = dest->hilight; + hilight_start = hilight_end = 0; + hilight = hilight_match(dest->server, dest->target, dest->nick, + dest->address, dest->level, stripped, + &hilight_start, &hilight_end); if (hilight == NULL) return; From 7cc85b9427887c4f77b8a5706b148371e713828b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 28 Dec 2015 00:07:42 +0100 Subject: [PATCH 0092/1495] keep track of address in text_dest for hilight purposes --- src/fe-common/core/fe-messages.c | 10 ++++------ src/fe-common/core/formats.c | 2 -- src/fe-common/core/formats.h | 5 ++--- src/fe-common/core/hilight-text.c | 7 ++++--- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index e06a4571..3240fd10 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -175,7 +175,6 @@ static void sig_message_public(SERVER_REC *server, const char *msg, int for_me, print_channel, level; char *nickmode, *color, *freemsg = NULL; HILIGHT_REC *hilight; - int match_beg = 0, match_end = 0; /* NOTE: this may return NULL if some channel is just closed with /WINDOW CLOSE and server still sends the few last messages */ @@ -188,8 +187,8 @@ static void sig_message_public(SERVER_REC *server, const char *msg, nick_match_msg(chanrec, msg, server->nick) : nick_match_msg_everywhere(chanrec, msg, server->nick); hilight = for_me ? NULL : - hilight_match(server, target, nick, address, MSGLEVEL_PUBLIC, msg, &match_beg, &match_end); - color = (hilight == NULL || !hilight->nick) ? NULL : hilight_get_color(hilight); + hilight_match_nick(server, target, nick, address, MSGLEVEL_PUBLIC, msg); + color = (hilight == NULL) ? NULL : hilight_get_color(hilight); print_channel = chanrec == NULL || !window_item_is_active((WI_ITEM_REC *) chanrec); @@ -217,9 +216,8 @@ static void sig_message_public(SERVER_REC *server, const char *msg, TEXT_DEST_REC dest; format_create_dest(&dest, server, target, level, NULL); - dest.hilight = hilight; - dest.match_beg = match_beg; - dest.match_end = match_end; + dest.address = address; + dest.nick = nick; if (color != NULL) { /* highlighted nick */ hilight_update_text_dest(&dest,hilight); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index b95b3966..ccf48394 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -416,8 +416,6 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, dest->server_tag = server != NULL ? SERVER(server)->tag : server_tag; dest->target = target; dest->level = level; - dest->match_beg = 0; - dest->match_end = 0; dest->window = window != NULL ? window : window_find_closest(server, target, level); } diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index a4b26852..8efd204c 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -52,11 +52,10 @@ typedef struct _TEXT_DEST_REC { SERVER_REC *server; const char *server_tag; /* if server is non-NULL, must be server->tag */ const char *target; + const char *nick; + const char *address; int level; - HILIGHT_REC *hilight; - int match_beg; - int match_end; int hilight_priority; char *hilight_color; int flags; diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 2c0075ec..b746f636 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -325,9 +325,10 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, if (dest->level & MSGLEVEL_NOHILIGHT) return; - hilight_start = dest->match_beg; - hilight_end = dest->match_end; - hilight = dest->hilight; + hilight_start = hilight_end = 0; + hilight = hilight_match(dest->server, dest->target, dest->nick, + dest->address, dest->level, stripped, + &hilight_start, &hilight_end); if (hilight == NULL) return; From 609f3ba6c2db4f04e1e11304459d4fc42babd8ff Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 3 Jan 2016 19:49:18 +0100 Subject: [PATCH 0093/1495] Clean up the ignore_find API to make it more powerful. This way we prevent the creation of duplicate ignores since the old code skipped the ignore_find call when a pattern was specified. It should also cover all the cases where the ignores would be wrongly overwritten, such as the case outlined in #78. --- src/core/ignore.c | 28 ++++++++++++++++------------ src/core/ignore.h | 9 +++++++-- src/fe-common/core/fe-ignore.c | 8 ++++---- src/irc/flood/autoignore.c | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index fd3c8a38..ee9e180d 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -186,15 +186,8 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, return ignore_check_replies(chanrec, text, level); } -IGNORE_REC *ignore_find(const char *servertag, const char *mask, - char **channels) -{ - return ignore_find_noact(servertag, mask, channels, 0); -} - - -IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, - char **channels, int noact) +IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags) { GSList *tmp; char **chan; @@ -216,18 +209,29 @@ IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, continue; } - if (noact && (rec->level & MSGLEVEL_NO_ACT) == 0) + if ((flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) continue; - if (!noact && (rec->level & MSGLEVEL_NO_ACT) != 0) + if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) continue; if ((rec->mask == NULL && mask != NULL) || - (rec->mask != NULL && mask == NULL)) continue; + (rec->mask != NULL && mask == NULL)) + continue; if (rec->mask != NULL && g_ascii_strcasecmp(rec->mask, mask) != 0) continue; + /* match the pattern too if requested */ + if (flags & IGNORE_FIND_PATTERN) { + if ((rec->pattern == NULL && pattern != NULL) || + (rec->pattern != NULL && pattern == NULL)) + continue; + + if (rec->pattern != NULL && g_ascii_strcasecmp(rec->pattern, pattern) != 0) + continue; + } + if ((channels == NULL && rec->channels == NULL)) return rec; /* no channels - ok */ diff --git a/src/core/ignore.h b/src/core/ignore.h index 46025d4c..0901e795 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -31,8 +31,13 @@ extern GSList *ignores; int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level); -IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels); -IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact); +enum { + IGNORE_FIND_PATTERN = 0x01, // Match the pattern + IGNORE_FIND_NOACT = 0x02, // Exclude the targets with NOACT level +}; + +IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags); void ignore_add_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index d2f9de27..2799e15f 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -158,8 +158,8 @@ static void cmd_ignore(const char *data) channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); - rec = patternarg != NULL ? NULL: ignore_find_noact(servertag, mask, channels, - (level & MSGLEVEL_NO_ACT)); + rec = ignore_find(servertag, mask, patternarg, channels, + IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0)); new_ignore = rec == NULL; if (rec == NULL) { @@ -237,9 +237,9 @@ static void cmd_unignore(const char *data) chans[0] = mask; mask = NULL; } - rec = ignore_find_noact("*", mask, (char **) chans, 0); + rec = ignore_find("*", mask, NULL, (char **) chans, 0); if (rec == NULL) { - rec = ignore_find_noact("*", mask, (char **) chans, 1); + rec = ignore_find("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); } } diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 250a1fe8..4708cb03 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -66,7 +66,7 @@ static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host mask = g_strdup_printf("%s!%s", nick, host); if (level & check_level) { - rec = ignore_find(server->tag, mask, NULL); + rec = ignore_find(server->tag, mask, NULL, NULL, 0); if (rec == NULL) autoignore_add(server, mask, level); else From dbee606c60c4d8d7c6e5cabd1241fc182ae6c4a3 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 3 Jan 2016 21:19:46 +0100 Subject: [PATCH 0094/1495] Don't break the API. Have a ignore_find_full method that is the one that all the new code should be using and provide some working stubs for ignore_find and ignore_find_noact. --- src/core/ignore.c | 12 +++++++++++- src/core/ignore.h | 9 +++++++-- src/fe-common/core/fe-ignore.c | 6 +++--- src/irc/flood/autoignore.c | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index ee9e180d..8d5a27c2 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -186,7 +186,7 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, return ignore_check_replies(chanrec, text, level); } -IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, +IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char *pattern, char **channels, const int flags) { GSList *tmp; @@ -257,6 +257,16 @@ IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pat return NULL; } +IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels) +{ + return ignore_find_full(servertag, mask, NULL, channels, 0); +} + +IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact) +{ + return ignore_find_full(servertag, mask, NULL, channels, IGNORE_FIND_NOACT); +} + static void ignore_set_config(IGNORE_REC *rec) { CONFIG_NODE *node; diff --git a/src/core/ignore.h b/src/core/ignore.h index 0901e795..f889740f 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -36,8 +36,13 @@ enum { IGNORE_FIND_NOACT = 0x02, // Exclude the targets with NOACT level }; -IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, - char **channels, const int flags); +IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags); + +// Convenience wrappers around ignore_find_full, for compatibility purpose + +IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels); +IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact); void ignore_add_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 2799e15f..a809ac91 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -158,7 +158,7 @@ static void cmd_ignore(const char *data) channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); - rec = ignore_find(servertag, mask, patternarg, channels, + rec = ignore_find_full(servertag, mask, patternarg, channels, IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0)); new_ignore = rec == NULL; @@ -237,9 +237,9 @@ static void cmd_unignore(const char *data) chans[0] = mask; mask = NULL; } - rec = ignore_find("*", mask, NULL, (char **) chans, 0); + rec = ignore_find_full("*", mask, NULL, (char **) chans, 0); if (rec == NULL) { - rec = ignore_find("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); + rec = ignore_find_full("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); } } diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 4708cb03..86ff3ec5 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -66,7 +66,7 @@ static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host mask = g_strdup_printf("%s!%s", nick, host); if (level & check_level) { - rec = ignore_find(server->tag, mask, NULL, NULL, 0); + rec = ignore_find_full(server->tag, mask, NULL, NULL, 0); if (rec == NULL) autoignore_add(server, mask, level); else From 837e03bd8f1be71ca26e3c2581b5444dcb5fe73f Mon Sep 17 00:00:00 2001 From: Lukas Mai Date: Wed, 6 Jan 2016 12:45:18 +0100 Subject: [PATCH 0095/1495] irssiproxy: avoid using pointer after freeing it --- src/irc/proxy/listen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index dcc94e6b..5dc9a704 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -681,8 +681,8 @@ static void read_settings(void) while (add_listens != NULL) { rec = add_listens->data; add_listen(rec->ircnet, rec->port); + add_listens = g_slist_remove(add_listens, rec); g_free(rec); - add_listens = g_slist_remove(add_listens, add_listens->data); } g_strfreev(ports); From cfb6123a7ab56e12136711a7e088424c9f68fd26 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 6 Jan 2016 17:25:53 +0100 Subject: [PATCH 0096/1495] forward ABI to perl modules --- src/perl/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perl/module.h b/src/perl/module.h index 2fd15137..3cbdf3d5 100644 --- a/src/perl/module.h +++ b/src/perl/module.h @@ -17,4 +17,4 @@ extern PerlInterpreter *my_perl; /* must be called my_perl or some perl implemen /* Change this every time when some API changes between irssi's perl module (or irssi itself) and irssi's perl libraries. */ -#define IRSSI_PERL_API_VERSION 20011214 +#define IRSSI_PERL_API_VERSION (20011214 + IRSSI_ABI_VERSION) From 4659cea65a663b11f3cc16e1d03c9955a4135238 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 15 Dec 2015 01:52:44 +0100 Subject: [PATCH 0097/1495] option to clear the history --- src/fe-common/core/command-history.c | 45 ++++++++++++++++++++++++---- src/fe-common/core/command-history.h | 1 + src/fe-common/core/fe-windows.c | 7 ++++- src/fe-common/core/fe-windows.h | 1 + src/fe-common/core/window-commands.c | 21 +++++++++++-- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index f9c3884c..9f46ee99 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -33,6 +33,7 @@ static HISTORY_REC *global_history; static int window_history; static GSList *histories; +static HISTORY_REC *last_cleared_history; void command_history_add(HISTORY_REC *history, const char *text) { @@ -41,6 +42,13 @@ void command_history_add(HISTORY_REC *history, const char *text) g_return_if_fail(history != NULL); g_return_if_fail(text != NULL); + if (last_cleared_history == history) { + last_cleared_history = NULL; + return; /* ignore this history addition, we just + cleared it */ + } + last_cleared_history = NULL; + link = g_list_last(history->list); if (link != NULL && g_strcmp0(link->data, text) == 0) return; /* same as previous entry */ @@ -94,13 +102,13 @@ HISTORY_REC *command_history_current(WINDOW_REC *window) if (window == NULL) return global_history; - if (window_history) - return window->history; - rec = command_history_find_name(window->history_name); if (rec != NULL) return rec; + if (window_history) + return window->history; + return global_history; } @@ -178,6 +186,18 @@ HISTORY_REC *command_history_create(const char *name) return rec; } +void command_history_clear(HISTORY_REC *history) +{ + g_return_if_fail(history != NULL); + + command_history_clear_pos_func(history, NULL); + g_list_foreach(history->list, (GFunc) g_free, NULL); + g_list_free(history->list); + history->list = NULL; + history->lines = 0; + last_cleared_history = history; +} + void command_history_destroy(HISTORY_REC *history) { g_return_if_fail(history != NULL); @@ -186,9 +206,8 @@ void command_history_destroy(HISTORY_REC *history) g_return_if_fail(history->refcount == 0); histories = g_slist_remove(histories, history); - - g_list_foreach(history->list, (GFunc) g_free, NULL); - g_list_free(history->list); + command_history_clear(history); + last_cleared_history = NULL; /* was destroyed */ g_free_not_null(history->name); g_free(history); @@ -229,6 +248,18 @@ static void sig_window_destroyed(WINDOW_REC *window) g_free_not_null(window->history_name); } +static void sig_window_history_cleared(WINDOW_REC *window, const char *name) { + HISTORY_REC *history; + + if (name == NULL || *name == '\0') { + history = command_history_current(window); + } else { + history = command_history_find_name(name); + } + + command_history_clear(history); +} + static void sig_window_history_changed(WINDOW_REC *window, const char *oldname) { command_history_link(window->history_name); @@ -279,6 +310,7 @@ void command_history_init(void) signal_add("window created", (SIGNAL_FUNC) sig_window_created); signal_add("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); signal_add("window history changed", (SIGNAL_FUNC) sig_window_history_changed); + signal_add_last("window history cleared", (SIGNAL_FUNC) sig_window_history_cleared); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } @@ -287,6 +319,7 @@ void command_history_deinit(void) signal_remove("window created", (SIGNAL_FUNC) sig_window_created); signal_remove("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); signal_remove("window history changed", (SIGNAL_FUNC) sig_window_history_changed); + signal_remove("window history cleared", (SIGNAL_FUNC) sig_window_history_cleared); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_history_destroy(global_history); diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 7b76246b..a572216b 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -28,6 +28,7 @@ const char *command_history_next(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); HISTORY_REC *command_history_create(const char *name); +void command_history_clear(HISTORY_REC *history); void command_history_destroy(HISTORY_REC *history); void command_history_link(const char *name); void command_history_unlink(const char *name); diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 1049137f..46c1593b 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -229,11 +229,16 @@ void window_set_history(WINDOW_REC *window, const char *name) else window->history_name = g_strdup(name); - signal_emit("window history changed", 1, window, oldname); + signal_emit("window history changed", 2, window, oldname); g_free_not_null(oldname); } +void window_clear_history(WINDOW_REC *window, const char *name) +{ + signal_emit("window history cleared", 2, window, name); +} + void window_set_level(WINDOW_REC *window, int level) { g_return_if_fail(window != NULL); diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 613f15f8..32d6cfcd 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -66,6 +66,7 @@ void window_change_server(WINDOW_REC *window, void *server); void window_set_refnum(WINDOW_REC *window, int refnum); void window_set_name(WINDOW_REC *window, const char *name); void window_set_history(WINDOW_REC *window, const char *name); +void window_clear_history(WINDOW_REC *window, const char *name); void window_set_level(WINDOW_REC *window, int level); void window_set_immortal(WINDOW_REC *window, int immortal); diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index c6ab68c0..e5005144 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -33,6 +33,7 @@ #include "window-items.h" #include "windows-layout.h" #include "printtext.h" +#include "command-history.h" static void window_print_binds(WINDOW_REC *win) { @@ -615,10 +616,25 @@ static void cmd_window_name(const char *data) } } -/* SYNTAX: WINDOW HISTORY */ +/* SYNTAX: WINDOW HISTORY [-clear] */ void cmd_window_history(const char *data) { - window_set_history(active_win, data); + GHashTable *optlist; + char *name; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, + "window history", &optlist, &name)) + return; + + if (g_hash_table_lookup(optlist, "clear") != NULL) { + signal_continue(1, data); + window_clear_history(active_win, name); + } else { + window_set_history(active_win, name); + } + + cmd_params_free(free_arg); } /* we're moving the first window to last - move the first contiguous block @@ -883,6 +899,7 @@ void window_commands_init(void) command_set_options("window number", "sticky"); command_set_options("window server", "sticky unsticky"); command_set_options("window theme", "delete"); + command_set_options("window history", "clear"); } void window_commands_deinit(void) From ad842ea8a60f107d68df4298a8914e66edf95c3b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 8 Jan 2016 15:42:59 +0100 Subject: [PATCH 0098/1495] reorder history add and fixes --- src/fe-common/core/command-history.c | 10 ---------- src/fe-common/core/window-commands.c | 4 ++-- src/fe-text/gui-readline.c | 15 +++++++-------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 9f46ee99..1060744e 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -33,7 +33,6 @@ static HISTORY_REC *global_history; static int window_history; static GSList *histories; -static HISTORY_REC *last_cleared_history; void command_history_add(HISTORY_REC *history, const char *text) { @@ -42,13 +41,6 @@ void command_history_add(HISTORY_REC *history, const char *text) g_return_if_fail(history != NULL); g_return_if_fail(text != NULL); - if (last_cleared_history == history) { - last_cleared_history = NULL; - return; /* ignore this history addition, we just - cleared it */ - } - last_cleared_history = NULL; - link = g_list_last(history->list); if (link != NULL && g_strcmp0(link->data, text) == 0) return; /* same as previous entry */ @@ -195,7 +187,6 @@ void command_history_clear(HISTORY_REC *history) g_list_free(history->list); history->list = NULL; history->lines = 0; - last_cleared_history = history; } void command_history_destroy(HISTORY_REC *history) @@ -207,7 +198,6 @@ void command_history_destroy(HISTORY_REC *history) histories = g_slist_remove(histories, history); command_history_clear(history); - last_cleared_history = NULL; /* was destroyed */ g_free_not_null(history->name); g_free(history); diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index e5005144..9e4aab3a 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -620,10 +620,10 @@ static void cmd_window_name(const char *data) void cmd_window_history(const char *data) { GHashTable *optlist; - char *name; + char *name; void *free_arg; - if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "window history", &optlist, &name)) return; diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index fcf152e8..5acfaf60 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -456,22 +456,21 @@ static void key_send_line(void) add_history = *str != '\0'; history = command_history_current(active_win); + if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN) + add_history = 0; + + if (add_history && history != NULL) { + command_history_add(history, str); + } + if (redir == NULL) { signal_emit("send command", 3, str, active_win->active_server, active_win->active); } else { - if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN) - add_history = 0; handle_entry_redirect(str); } - if (add_history) { - history = command_history_find(history); - if (history != NULL) - command_history_add(history, str); - } - if (active_entry != NULL) gui_entry_set_text(active_entry, ""); command_history_clear_pos(active_win); From cf90b2122efdc2a6fc5246e3c538af3c71f38988 Mon Sep 17 00:00:00 2001 From: Lukas Mai Date: Fri, 8 Jan 2016 18:52:59 +0100 Subject: [PATCH 0099/1495] irc/core/irc-commands.c: fix indentation --- src/irc/core/irc-commands.c | 200 ++++++++++++++++++------------------ 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 3cc105ba..d5988f97 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -61,16 +61,16 @@ static int knockout_tag; /* SYNTAX: NOTICE */ static void cmd_notice(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { const char *target, *msg; char *recoded; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, - &target, &msg)) + &target, &msg)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); @@ -88,16 +88,16 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server, /* SYNTAX: CTCP [] */ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { const char *target; char *ctcpcmd, *ctcpdata; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &target, &ctcpcmd, &ctcpdata)) + &target, &ctcpcmd, &ctcpdata)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); @@ -122,16 +122,16 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, /* SYNTAX: NCTCP [] */ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { const char *target; char *ctcpcmd, *ctcpdata, *recoded; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &target, &ctcpcmd, &ctcpdata)) + &target, &ctcpcmd, &ctcpdata)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); @@ -150,22 +150,22 @@ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, /* SYNTAX: PART [] [] */ static void cmd_part(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { char *channame, *msg; char *recoded = NULL; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | - PARAM_FLAG_OPTCHAN, item, &channame, &msg)) + PARAM_FLAG_OPTCHAN, item, &channame, &msg)) return; if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*msg == '\0') msg = (char *) settings_get_str("part_message"); - if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) + if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) irc_server_purge_output(server, channame); if (*msg != '\0') @@ -186,11 +186,11 @@ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item char *channame, *nicks, *reason, *recoded; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST | - PARAM_FLAG_OPTCHAN, item, - &channame, &nicks, &reason)) + PARAM_FLAG_OPTCHAN, item, + &channame, &nicks, &reason)) return; if (*channame == '\0' || *nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -213,11 +213,11 @@ static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *ite char *recoded = NULL; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | - PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, - item, "topic", &optlist, &channame, &topic)) + PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, + item, "topic", &optlist, &channame, &topic)) return; if (*topic != '\0' || g_hash_table_lookup(optlist, "delete") != NULL) @@ -239,7 +239,7 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *it char *nick, *channame; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2, &nick, &channame)) return; @@ -258,17 +258,17 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *it /* SYNTAX: LIST [-yes] [] */ static void cmd_list(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { GHashTable *optlist; char *str; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, - "list", &optlist, &str)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "list", &optlist, &str)) return; if (*str == '\0' && g_hash_table_lookup(optlist, "yes") == NULL && @@ -282,7 +282,7 @@ static void cmd_list(const char *data, IRC_SERVER_REC *server, /* SYNTAX: WHO [ | | **] */ static void cmd_who(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { char *channel, *rest; void *free_arg; @@ -290,7 +290,7 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | - PARAM_FLAG_STRIP_TRAILING_WS, &channel, &rest)) + PARAM_FLAG_STRIP_TRAILING_WS, &channel, &rest)) return; if (g_strcmp0(channel, "*") == 0 || *channel == '\0') { @@ -313,29 +313,29 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, } static void cmd_names(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { - GHashTable *optlist; + GHashTable *optlist; char *channel; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, - "names", &optlist, &channel)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "names", &optlist, &channel)) return; if (g_strcmp0(channel, "*") == 0 || *channel == '\0') { if (!IS_IRC_CHANNEL(item)) - cmd_param_error(CMDERR_NOT_JOINED); + cmd_param_error(CMDERR_NOT_JOINED); channel = IRC_CHANNEL(item)->name; } if (g_strcmp0(channel, "**") == 0) { /* ** displays all nicks.. */ - irc_send_cmd(server, "NAMES"); + irc_send_cmd(server, "NAMES"); } else { irc_send_cmdv(server, "NAMES %s", channel); } @@ -346,12 +346,12 @@ static void cmd_names(const char *data, IRC_SERVER_REC *server, /* SYNTAX: NICK */ static void cmd_nick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { - char *nick; + char *nick; void *free_arg; g_return_if_fail(data != NULL); - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1, &nick)) return; @@ -388,23 +388,23 @@ static char *get_redirect_nicklist(const char *nicks, int *free) /* SYNTAX: WHOIS [-] [] [] */ static void cmd_whois(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { GHashTable *optlist; char *qserver, *query, *event_402, *str; void *free_arg; int free_nick; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_UNKNOWN_OPTIONS, - "whois", &optlist, &qserver, &query)) + PARAM_FLAG_UNKNOWN_OPTIONS, + "whois", &optlist, &qserver, &query)) return; /* - */ server = IRC_SERVER(cmd_options_get_server("whois", optlist, - SERVER(server))); + SERVER(server))); if (server == NULL) { cmd_params_free(free_arg); return; @@ -439,15 +439,15 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server, str = g_strconcat(qserver, " ", query, NULL); server_redirect_event(server, "whois", 1, str, TRUE, - NULL, - "event 318", "whois end", - "event 402", event_402, - "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ - "event 313", "whois oper", - "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"), - "event 311", "whois event", - "", "whois default event", NULL); - g_free(str); + NULL, + "event 318", "whois end", + "event 402", event_402, + "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ + "event 313", "whois oper", + "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"), + "event 311", "whois event", + "", "whois default event", NULL); + g_free(str); server->whois_found = FALSE; irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd); @@ -457,7 +457,7 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server, } static void event_whois(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *addr) + const char *nick, const char *addr) { server->whois_found = TRUE; signal_emit("event 311", 4, server, data, nick, addr); @@ -473,23 +473,23 @@ static void sig_whois_try_whowas(IRC_SERVER_REC *server, const char *data) server->whowas_found = FALSE; server_redirect_event(server, "whowas", 1, nick, -1, NULL, - "event 314", "whowas event", - "event 369", "whowas event end", - "event 406", "event empty", NULL); + "event 314", "whowas event", + "event 369", "whowas event end", + "event 406", "event empty", NULL); irc_send_cmdv(server, "WHOWAS %s 1", nick); g_free(params); } static void event_end_of_whois(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *addr) + const char *nick, const char *addr) { signal_emit("event 318", 4, server, data, nick, addr); server->whois_found = FALSE; } static void event_whowas(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *addr) + const char *nick, const char *addr) { server->whowas_found = TRUE; signal_emit("event 314", 4, server, data, nick, addr); @@ -502,17 +502,17 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server) void *free_arg; int free_nick; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, - &nicks, &rest)) + &nicks, &rest)) return; if (*nicks == '\0') nicks = server->nick; nicks_redir = get_redirect_nicklist(nicks, &free_nick); server_redirect_event(server, "whowas", 1, nicks_redir, -1, NULL, - "event 301", "whowas away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ - "event 314", "whowas event", NULL); + "event 301", "whowas away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ + "event 314", "whowas event", NULL); if (free_nick) g_free(nicks_redir); server->whowas_found = FALSE; @@ -529,9 +529,9 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server) static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { GTimeVal tv; - char *str; + char *str; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (*data == '\0') { if (!IS_QUERY(item)) @@ -554,7 +554,7 @@ static void cmd_away(const char *data, IRC_SERVER_REC *server) void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST, "away", &optlist, &reason)) return; + PARAM_FLAG_GETREST, "away", &optlist, &reason)) return; if (g_hash_table_lookup(optlist, "one") != NULL) irc_server_send_away(server, reason); @@ -567,7 +567,7 @@ static void cmd_away(const char *data, IRC_SERVER_REC *server) /* SYNTAX: SCONNECT [[] ] */ static void cmd_sconnect(const char *data, IRC_SERVER_REC *server) { - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); irc_send_cmdv(server, "CONNECT %s", data); @@ -600,11 +600,11 @@ static void cmd_wait(const char *data, IRC_SERVER_REC *server) void *free_arg; int n; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, - NULL, &optlist, &msecs)) + PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, + NULL, &optlist, &msecs)) return; if (*msecs == '\0') @@ -612,7 +612,7 @@ static void cmd_wait(const char *data, IRC_SERVER_REC *server) /* - */ server = IRC_SERVER(cmd_options_get_server(NULL, optlist, - SERVER(server))); + SERVER(server))); n = atoi(msecs); if (server != NULL && n > 0) { @@ -635,10 +635,10 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item IRC_CHANNEL_REC *chanrec; GSList *tmp, *nicks; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | - PARAM_FLAG_GETREST, item, &channame, &msg)) + PARAM_FLAG_GETREST, item, &channame, &msg)) return; if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -654,11 +654,11 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item /* Fall back to manually noticing each op */ nicks = NULL; g_hash_table_foreach(chanrec->nicks, - (GHFunc) cmd_wall_hash, &nicks); + (GHFunc) cmd_wall_hash, &nicks); args = g_strconcat(chanrec->name, " ", recoded, NULL); msg = parse_special_string(settings_get_str("wall_format"), - SERVER(server), item, args, NULL, 0); + SERVER(server), item, args, NULL, 0); g_free(args); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { @@ -666,7 +666,7 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item if (rec != chanrec->ownnick) { irc_send_cmdv(server, "NOTICE %s :%s", - rec->nick, msg); + rec->nick, msg); } } @@ -680,17 +680,17 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item /* SYNTAX: KICKBAN [] */ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { - IRC_CHANNEL_REC *chanrec; + IRC_CHANNEL_REC *chanrec; char *channel, *nicks, *reason, *kickcmd, *bancmd, *recoded; - char **nicklist, *spacenicks; + char **nicklist, *spacenicks; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, - item, &channel, &nicks, &reason)) + item, &channel, &nicks, &reason)) return; if (*channel == '\0' || *nicks == '\0') @@ -701,7 +701,7 @@ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, cmd_param_error(CMDERR_CHAN_NOT_FOUND); nicklist = g_strsplit(nicks, ",", -1); - spacenicks = g_strjoinv(" ", nicklist); + spacenicks = g_strjoinv(" ", nicklist); g_strfreev(nicklist); recoded = recode_out(SERVER(server), reason, channel); @@ -709,9 +709,9 @@ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, g_free(recoded); bancmd = g_strdup_printf("%s %s", chanrec->name, spacenicks); - g_free(spacenicks); + g_free(spacenicks); - if (settings_get_bool("kick_first_on_kickban")) { + if (settings_get_bool("kick_first_on_kickban")) { signal_emit("command kick", 3, kickcmd, server, chanrec); signal_emit("command ban", 3, bancmd, server, chanrec); } else { @@ -742,7 +742,7 @@ static void knockout_timeout_server(IRC_SERVER_REC *server) if (!IS_IRC_SERVER(server)) return; - now = time(NULL); + now = time(NULL); for (tmp = server->knockoutlist; tmp != NULL; tmp = next) { KNOCKOUT_REC *rec = tmp->data; @@ -763,16 +763,16 @@ static int knockout_timeout(void) /* SYNTAX: KNOCKOUT [