diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | docs/help/in/bind.in | 3 | ||||
-rw-r--r-- | docs/help/in/cat.in | 6 | ||||
-rw-r--r-- | docs/startup-HOWTO.html | 6 | ||||
-rw-r--r-- | docs/startup-HOWTO.txt | 15 | ||||
-rw-r--r-- | scripts/scriptassist.pl | 13 | ||||
-rw-r--r-- | src/core/channels-setup.c | 9 | ||||
-rw-r--r-- | src/core/network-openssl.c | 6 | ||||
-rw-r--r-- | src/core/servers-setup.c | 11 | ||||
-rw-r--r-- | src/core/servers.c | 45 | ||||
-rw-r--r-- | src/fe-common/core/fe-common-core.c | 6 | ||||
-rw-r--r-- | src/fe-common/core/fe-core-commands.c | 2 | ||||
-rw-r--r-- | src/fe-common/core/keyboard.c | 54 | ||||
-rw-r--r-- | src/fe-text/gui-printtext.c | 40 | ||||
-rw-r--r-- | src/fe-text/gui-windows.c | 2 | ||||
-rw-r--r-- | src/fe-text/textbuffer-view.c | 5 | ||||
-rw-r--r-- | src/irc/core/irc-servers.c | 6 | ||||
-rw-r--r-- | src/irc/flood/flood.c | 4 | ||||
-rw-r--r-- | src/irc/notifylist/notifylist.c | 4 | ||||
-rw-r--r-- | tests/irc/Makefile.am | 4 | ||||
-rw-r--r-- | tests/irc/flood/Makefile.am | 40 | ||||
-rw-r--r-- | tests/irc/flood/test-796.c | 174 | ||||
-rwxr-xr-x | utils/syncdocs.sh | 2 |
23 files changed, 383 insertions, 75 deletions
diff --git a/configure.ac b/configure.ac index 2852480c..d29c132b 100644 --- a/configure.ac +++ b/configure.ac @@ -729,6 +729,7 @@ tests/fe-common/Makefile tests/fe-common/core/Makefile tests/irc/Makefile tests/irc/core/Makefile +tests/irc/flood/Makefile docs/Makefile docs/help/Makefile docs/help/in/Makefile diff --git a/docs/help/in/bind.in b/docs/help/in/bind.in index d6151b23..8fcc744b 100644 --- a/docs/help/in/bind.in +++ b/docs/help/in/bind.in @@ -6,7 +6,8 @@ %9Parameters:%9 -list: Displays a list of all the bindable commands. - -delete: Removes the binding, + -delete: Removes the binding. + -reset: Reset a key to its default binding. A name of the binding and the command to perform; if no parameter is given, the list of bindings will be displayed. diff --git a/docs/help/in/cat.in b/docs/help/in/cat.in index 3a3ed32b..9f9f242f 100644 --- a/docs/help/in/cat.in +++ b/docs/help/in/cat.in @@ -5,12 +5,16 @@ %9Parameters:%9 - The file to display. + The file to display and optionally a position to seek in the file, + in bytes. %9Description:%9 Displays the contents of the specified file into the active window. + The seek position parameter is used internally to display away logs, if + omitted the whole file is shown. + %9Examples:%9 /CAT /etc/network/interfaces diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index aaf9e5fe..8cd7a010 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -411,7 +411,7 @@ Ctrl-X - set the next server in list active <p>Irssi supports connecting to IRC servers via a proxy. All server connections are then made through it, and if you’ve set up everything properly, you don’t need to do any <code>/QUOTE SERVER</code> commands manually.</p> -<p>Here’s an example: You have your bouncer (lets say, BNC or BNC-like) listening in irc.bouncer.org port 5000. You want to use it to connect to servers irc.dalnet and irc.efnet.org. First you’d need to setup the bouncer:</p> +<p>Here’s an example: You have your bouncer (lets say, BNC or BNC-like) listening in irc.bouncer.org port 5000. You want to use it to connect to servers irc.dal.net and irc.efnet.org. First you’d need to setup the bouncer:</p> <div><div><pre><code>/SET use_proxy ON /SET proxy_address irc.bouncer.org @@ -434,7 +434,7 @@ Ctrl-X - set the next server in list active <p><strong>Proxy specific settings:</strong></p> -<p>All proxies have these settings in common:</p> +<p>All proxies except irssi proxy and socks proxy have these settings in common:</p> <div><div><pre><code>/SET use_proxy ON /SET proxy_address <Proxy host address> @@ -488,7 +488,7 @@ Ctrl-X - set the next server in list active <p>Irssi contains it’s own proxy which you can build giving <code>\--with-proxy</code> option to configure. You’ll still need to run irssi in a screen to use it though.</p> -<p>Irssi proxy is a bit different than most proxies, normally proxies create a new connection to IRC server when you connect to it, but <strong>irssi proxy shares your existing IRC connection(s) to multiple clients</strong>. And even more clearly: <strong>You can use only one IRC server connection to IRC with as many clients as you want</strong>. Can anyone figure out even more easier ways to say this, so I wouldn’t need to try to explain this thing for minutes every time? :)</p> +<p>Irssi proxy is a bit different than most proxies, normally proxies create a new connection to IRC server when a new client connects to it, but <strong>irssi proxy shares your existing IRC connection(s) to multiple clients</strong>. And even more clearly: <strong>You can use only one IRC server connection of the irssi proxy to IRC with as many clients as you want</strong>. Can anyone figure out even more easier ways to say this, so I wouldn’t need to try to explain this thing for minutes every time? :)</p> <p>Irssi proxy supports sharing multiple server connections in different ports, like you can share network in port 2777 and efnet in port 2778.</p> diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index 23d7cf94..88912ef3 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -460,7 +460,7 @@ need to do any /QUOTE SERVER commands manually. Here’s an example: You have your bouncer (lets say, BNC or BNC-like) listening in irc.bouncer.org port 5000. You want to use it to connect to servers -irc.dalnet and irc.efnet.org. First you’d need to setup the bouncer: +irc.dal.net and irc.efnet.org. First you’d need to setup the bouncer: /SET use_proxy ON /SET proxy_address irc.bouncer.org @@ -485,7 +485,7 @@ which you can give to /SERVER and /SERVER ADD commands. Proxy specific settings: -All proxies have these settings in common: +All proxies except irssi proxy and socks proxy have these settings in common: /SET use_proxy ON /SET proxy_address <Proxy host address> @@ -543,11 +543,12 @@ Irssi contains it’s own proxy which you can build giving \--with-proxy option to configure. You’ll still need to run irssi in a screen to use it though. Irssi proxy is a bit different than most proxies, normally proxies create a new -connection to IRC server when you connect to it, but irssi proxy shares your -existing IRC connection(s) to multiple clients. And even more clearly: You can -use only one IRC server connection to IRC with as many clients as you want. Can -anyone figure out even more easier ways to say this, so I wouldn’t need to try -to explain this thing for minutes every time? :) +connection to IRC server when a new client connects to it, but irssi proxy +shares your existing IRC connection(s) to multiple clients. And even more +clearly: You can use only one IRC server connection of the irssi proxy to IRC +with as many clients as you want. Can anyone figure out even more easier ways +to say this, so I wouldn’t need to try to explain this thing for minutes every +time? :) Irssi proxy supports sharing multiple server connections in different ports, like you can share network in port 2777 and efnet in port 2778. diff --git a/scripts/scriptassist.pl b/scripts/scriptassist.pl index 459d97f6..68708945 100644 --- a/scripts/scriptassist.pl +++ b/scripts/scriptassist.pl @@ -5,7 +5,7 @@ use strict; -our $VERSION = '2003020804'; +our $VERSION = '2003020806'; our %IRSSI = ( authors => 'Stefan \'tommie\' Tomanek', contact => 'stefan@pico.ruhr.de', @@ -315,6 +315,7 @@ sub get_new { my $xml = get_scripts(); foreach (sort {$xml->{$b}{last_modified} cmp $xml->{$a}{last_modified}} keys %$xml) { my %entry = %{ $xml->{$_} }; + next if $entry{HIDDEN}; $result->{$_} = \%entry; $num--; last unless $num; @@ -390,6 +391,7 @@ sub search_scripts { my %result; foreach (sort keys %{$database}) { my %entry = %{$database->{$_}}; + next if $entry{HIDDEN}; my $string = $_." "; $string .= $entry{description} if defined $entry{description}; if ($string =~ /$query/i) { @@ -1051,7 +1053,7 @@ sub toggle_autorun { my $dir = Irssi::get_irssi_dir()."/scripts/"; mkdir $dir."autorun/" unless (-e $dir."autorun/"); return unless (-e $dir.$plname); - if (check_autorun($sname)) { + if (-e $dir."/autorun/".$plname) { if (readlink($dir."/autorun/".$plname) eq "../".$plname) { if (unlink($dir."/autorun/".$plname)) { print CLIENTCRAP "%R>>%n Autorun of ".$sname." disabled"; @@ -1062,8 +1064,11 @@ sub toggle_autorun { print CLIENTCRAP "%R>>%n ".$dir."/autorun/".$plname." is not a correct link"; } } else { - symlink("../".$plname, $dir."/autorun/".$plname); - print CLIENTCRAP "%R>>%n Autorun of ".$sname." enabled"; + if (symlink("../".$plname, $dir."/autorun/".$plname)) { + print CLIENTCRAP "%R>>%n Autorun of ".$sname." enabled"; + } else { + print CLIENTCRAP "%R>>%n Unable to create autorun link"; + } } } diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index 4966d77d..8002646d 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -37,9 +37,14 @@ 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 (g_strcmp0(name, channel->name) != 0 || - g_strcmp0(chatnet, channel->chatnet) != 0) + if (name == NULL || chatnet == NULL) { + return 0; + } + + if (g_ascii_strcasecmp(name, channel->name) != 0 || + g_ascii_strcasecmp(chatnet, channel->chatnet) != 0) { return 1; + } return 0; } diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 9fddf073..692c7e71 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -35,7 +35,8 @@ #include <openssl/err.h> /* OpenSSL 1.1.0 introduced some backward-incompatible changes to the api */ -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ + (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2070000fL) /* The two functions below could be already defined if OPENSSL_API_COMPAT is * below the 1.1.0 version so let's do a clean start */ #undef X509_get_notBefore @@ -47,7 +48,8 @@ /* OpenSSL 1.1.0 also introduced some useful additions to the api */ #if (OPENSSL_VERSION_NUMBER >= 0x10002000L) -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined (LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) static int X509_STORE_up_ref(X509_STORE *vfy) { int n; diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 9492c58c..2a92a367 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -474,10 +474,15 @@ 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 (g_strcmp0(address, server->address) != 0 || - g_strcmp0(chatnet, server->chatnet) != 0 || - port != server->port) + if (address == NULL || chatnet == NULL) { + return 0; + } + + if (g_ascii_strcasecmp(address, server->address) != 0 || + g_ascii_strcasecmp(chatnet, server->chatnet) != 0 || + port != server->port) { return 1; + } return 0; } diff --git a/src/core/servers.c b/src/core/servers.c index b9faab81..11eccc53 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -460,8 +460,6 @@ static int server_remove_channels(SERVER_REC *server) void server_disconnect(SERVER_REC *server) { - int chans; - g_return_if_fail(IS_SERVER(server)); if (server->disconnected) @@ -480,21 +478,9 @@ void server_disconnect(SERVER_REC *server) server->disconnected = TRUE; signal_emit("server disconnected", 1, server); - /* close all channels */ - chans = server_remove_channels(server); - - if (server->handle != NULL) { - if (!chans || server->connection_lost) - net_sendbuffer_destroy(server->handle, TRUE); - else { - /* we were on some channels, try to let the server - disconnect so that our quit message is guaranteed - to get displayed */ - net_disconnect_later(net_sendbuffer_handle(server->handle)); - net_sendbuffer_destroy(server->handle, FALSE); - } - server->handle = NULL; - } + /* we used to destroy the handle here but it may be still in + use during signal processing, so destroy it on unref + instead */ if (server->readtag > 0) { g_source_remove(server->readtag); @@ -513,6 +499,8 @@ void server_ref(SERVER_REC *server) int server_unref(SERVER_REC *server) { + int chans; + g_return_val_if_fail(IS_SERVER(server), FALSE); if (--server->refcount > 0) @@ -524,6 +512,29 @@ int server_unref(SERVER_REC *server) return TRUE; } + /* close all channels */ + chans = server_remove_channels(server); + + /* since module initialisation uses server connected, only let + them know that the object got destroyed if the server was + disconnected */ + if (server->disconnected) { + signal_emit("server destroyed", 1, server); + } + + if (server->handle != NULL) { + if (!chans || server->connection_lost) + net_sendbuffer_destroy(server->handle, TRUE); + else { + /* we were on some channels, try to let the server + disconnect so that our quit message is guaranteed + to get displayed */ + net_disconnect_later(net_sendbuffer_handle(server->handle)); + net_sendbuffer_destroy(server->handle, FALSE); + } + server->handle = NULL; + } + MODULE_DATA_DEINIT(server); server_connect_unref(server->connrec); if (server->rawlog != NULL) rawlog_destroy(server->rawlog); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 209c2d9e..ef5d2113 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -104,7 +104,7 @@ static void sig_connected(SERVER_REC *server) MODULE_DATA_SET(server, g_new0(MODULE_SERVER_REC, 1)); } -static void sig_disconnected(SERVER_REC *server) +static void sig_destroyed(SERVER_REC *server) { void *data = MODULE_DATA(server); g_free(data); @@ -203,7 +203,7 @@ void fe_common_core_init(void) settings_check(); signal_add_first("server connected", (SIGNAL_FUNC) sig_connected); - signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected); + signal_add_last("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_add_first("channel created", (SIGNAL_FUNC) sig_channel_created); signal_add_last("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); @@ -249,7 +249,7 @@ void fe_common_core_deinit(void) signal_remove("setup changed", (SIGNAL_FUNC) sig_setup_changed); signal_remove("server connected", (SIGNAL_FUNC) sig_connected); - signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected); + signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_remove("channel created", (SIGNAL_FUNC) sig_channel_created); signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); } diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index fb98cc25..222543d5 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -114,7 +114,7 @@ static void cmd_version(char *data) } } -/* SYNTAX: CAT <file> */ +/* SYNTAX: CAT <file> [<seek position>] */ static void cmd_cat(const char *data) { char *fname, *fposstr; diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index 6f7907eb..c3df5ed7 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -156,6 +156,7 @@ static void keyconfig_save(const char *id, const char *key, const char *data) static void keyconfig_clear(const char *key) { CONFIG_NODE *node; + KEY_REC *rec; g_return_if_fail(key != NULL); @@ -165,6 +166,11 @@ static void keyconfig_clear(const char *key) iconfig_node_remove(iconfig_node_traverse("(keyboard", FALSE), node); } + if ((rec = g_hash_table_lookup(default_keys, key)) != NULL) { + node = iconfig_node_traverse("(keyboard", TRUE); + node = iconfig_node_section(node, NULL, NODE_TYPE_BLOCK); + iconfig_node_set_str(node, "key", key); + } } KEYINFO_REC *key_info_find(const char *id) @@ -569,13 +575,38 @@ void key_configure_remove(const char *key) g_return_if_fail(key != NULL); + keyconfig_clear(key); + rec = g_hash_table_lookup(keys, key); if (rec == NULL) return; - keyconfig_clear(key); key_configure_destroy(rec); } +/* Reset key to default */ +void key_configure_reset(const char *key) +{ + KEY_REC *rec; + CONFIG_NODE *node; + + g_return_if_fail(key != NULL); + + node = key_config_find(key); + if (node != NULL) { + iconfig_node_remove(iconfig_node_traverse("(keyboard", FALSE), node); + } + + if ((rec = g_hash_table_lookup(default_keys, key)) != NULL) { + key_configure_create(rec->info->id, rec->key, rec->data); + } else { + rec = g_hash_table_lookup(keys, key); + if (rec == NULL) + return; + + key_configure_destroy(rec); + } +} + static int key_emit_signal(KEYBOARD_REC *keyboard, KEY_REC *key) { int consumed; @@ -739,7 +770,9 @@ static void cmd_show_keys(const char *searchkey, int full) for (key = rec->keys; key != NULL; key = key->next) { KEY_REC *rec = key->data; - if ((len == 0 || g_ascii_strncasecmp(rec->key, searchkey, len) == 0) && + if ((len == 0 || + (full ? strncmp(rec->key, searchkey, len) == 0 : + g_ascii_strncasecmp(rec->key, searchkey, len) == 0)) && (!full || rec->key[len] == '\0')) { printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_LIST, rec->key, rec->info->id, rec->data == NULL ? "" : rec->data); @@ -750,7 +783,7 @@ static void cmd_show_keys(const char *searchkey, int full) printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_FOOTER); } -/* SYNTAX: BIND [-list] [-delete] [<key> [<command> [<data>]]] */ +/* SYNTAX: BIND [-list] [-delete | -reset] [<key> [<command> [<data>]]] */ static void cmd_bind(const char *data) { GHashTable *optlist; @@ -780,6 +813,12 @@ static void cmd_bind(const char *data) key_configure_remove(key); cmd_params_free(free_arg); return; + } else if (*key != '\0' && g_hash_table_lookup(optlist, "reset")) { + /* reset key */ + key_configure_reset(key); + cmd_show_keys(key, TRUE); + cmd_params_free(free_arg); + return; } if (*id == '\0') { @@ -878,8 +917,13 @@ static void key_config_read(CONFIG_NODE *node) id = config_node_get_str(node, "id", NULL); data = config_node_get_str(node, "data", NULL); - if (key != NULL && id != NULL) + if (key != NULL && id != NULL) { key_configure_create(id, key, data); + } else if (key != NULL && id == NULL && data == NULL) { + KEY_REC *rec = g_hash_table_lookup(keys, key); + if (rec != NULL) + key_configure_destroy(rec); + } } static void read_keyboard_config(void) @@ -938,7 +982,7 @@ void keyboard_init(void) signal_add("complete command bind", (SIGNAL_FUNC) sig_complete_bind); command_bind("bind", NULL, (SIGNAL_FUNC) cmd_bind); - command_set_options("bind", "delete list"); + command_set_options("bind", "delete reset list"); } void keyboard_deinit(void) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index c52f9ced..83a36f14 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -120,12 +120,19 @@ void gui_printtext_internal(int xpos, int ypos, const char *str) next_xpos = next_ypos = -1; } +static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line); + void gui_printtext_after_time(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str, time_t time) { GUI_WINDOW_REC *gui; gui = WINDOW_GUI(dest->window); + if (prev == NULL && !gui->view->buffer->last_eol) { + /* we have an unfinished line in the buffer still */ + view_add_eol(gui->view, &gui->insert_after); + } + gui->use_insert_after = TRUE; gui->insert_after = prev; gui->insert_after_time = time; @@ -249,9 +256,26 @@ static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line) textbuffer_view_insert_line(view, *line); } +static void print_text_no_window(int flags, int fg, int bg, int attr, const char *str) +{ + 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) { + if (clrtoeol_info->window != NULL) { + term_window_clrtoeol_abs(clrtoeol_info->window, next_ypos); + } else { + term_clrtoeol(root_window); + } + } + next_xpos += term_addstr(root_window, str); +} + static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, void *bgcolor, void *pflags, - char *str, TEXT_DEST_REC *dest) + const char *str, TEXT_DEST_REC *dest) { GUI_WINDOW_REC *gui; TEXT_BUFFER_VIEW_REC *view; @@ -265,19 +289,7 @@ 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); - - term_set_color2(root_window, attr, fg, bg); - - term_move(root_window, next_xpos, next_ypos); - if (flags & GUI_PRINT_FLAG_CLRTOEOL) { - if (clrtoeol_info->window != NULL) { - term_window_clrtoeol_abs(clrtoeol_info->window, next_ypos); - } else { - term_clrtoeol(root_window); - } - } - next_xpos += term_addstr(root_window, str); + print_text_no_window(flags, fg, bg, attr, str); return; } diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 3efb9803..f761e390 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -207,8 +207,6 @@ void gui_windows_reset_settings(void) WINDOW_REC *rec = tmp->data; GUI_WINDOW_REC *gui = WINDOW_GUI(rec); - textbuffer_view_set_hidden_level(gui->view, MSGLEVEL_HIDDEN); - textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); textbuffer_view_set_default_indent(gui->view, diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 99625ecc..3ccd95f5 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -913,11 +913,14 @@ void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height) } else if (view->startline == view->bottom_startline && view->subline > view->bottom_subline) { view->subline = view->bottom_subline; - } else { + } else if (view->startline != NULL) { /* make sure the subline is still in allowed range */ linecount = view_get_linecount(view, view->startline); if (view->subline > linecount) view->subline = linecount; + } else { + /* we don't have a startline. still under construction? */ + view->subline = 0; } textbuffer_view_init_ypos(view); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index e154d17f..02d971dc 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -425,7 +425,7 @@ static void isupport_destroy_hash(void *key, void *value) g_free(value); } -static void sig_disconnected(IRC_SERVER_REC *server) +static void sig_destroyed(IRC_SERVER_REC *server) { GSList *tmp; @@ -1033,7 +1033,7 @@ void irc_servers_init(void) cmd_tag = -1; signal_add_first("server connected", (SIGNAL_FUNC) sig_connected); - signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected); + signal_add_last("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit); signal_add("event 001", (SIGNAL_FUNC) event_connected); signal_add("event 004", (SIGNAL_FUNC) event_server_info); @@ -1060,7 +1060,7 @@ void irc_servers_deinit(void) g_source_remove(cmd_tag); signal_remove("server connected", (SIGNAL_FUNC) sig_connected); - signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected); + signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit); signal_remove("event 001", (SIGNAL_FUNC) event_connected); signal_remove("event 004", (SIGNAL_FUNC) event_server_info); diff --git a/src/irc/flood/flood.c b/src/irc/flood/flood.c index 0944a6eb..b528f707 100644 --- a/src/irc/flood/flood.c +++ b/src/irc/flood/flood.c @@ -324,7 +324,7 @@ void irc_flood_init(void) read_settings(); signal_add("setup changed", (SIGNAL_FUNC) read_settings); signal_add_first("server connected", (SIGNAL_FUNC) flood_init_server); - signal_add("server disconnected", (SIGNAL_FUNC) flood_deinit_server); + signal_add("server destroyed", (SIGNAL_FUNC) flood_deinit_server); autoignore_init(); settings_check(); @@ -344,5 +344,5 @@ void irc_flood_deinit(void) signal_remove("setup changed", (SIGNAL_FUNC) read_settings); signal_remove("server connected", (SIGNAL_FUNC) flood_init_server); - signal_remove("server disconnected", (SIGNAL_FUNC) flood_deinit_server); + signal_remove("server destroyed", (SIGNAL_FUNC) flood_deinit_server); } diff --git a/src/irc/notifylist/notifylist.c b/src/irc/notifylist/notifylist.c index 573f7a7f..4fd5ef1a 100644 --- a/src/irc/notifylist/notifylist.c +++ b/src/irc/notifylist/notifylist.c @@ -331,7 +331,7 @@ void irc_notifylist_init(void) notifylist_ison_init(); notifylist_whois_init(); signal_add("server connected", (SIGNAL_FUNC) notifylist_init_server); - signal_add("server disconnected", (SIGNAL_FUNC) notifylist_deinit_server); + signal_add("server destroyed", (SIGNAL_FUNC) notifylist_deinit_server); signal_add("event quit", (SIGNAL_FUNC) event_quit); signal_add("event privmsg", (SIGNAL_FUNC) event_privmsg); signal_add("event join", (SIGNAL_FUNC) event_join); @@ -349,7 +349,7 @@ void irc_notifylist_deinit(void) notifylist_whois_deinit(); signal_remove("server connected", (SIGNAL_FUNC) notifylist_init_server); - signal_remove("server disconnected", (SIGNAL_FUNC) notifylist_deinit_server); + signal_remove("server destroyed", (SIGNAL_FUNC) notifylist_deinit_server); signal_remove("event quit", (SIGNAL_FUNC) event_quit); signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg); signal_remove("event join", (SIGNAL_FUNC) event_join); diff --git a/tests/irc/Makefile.am b/tests/irc/Makefile.am index 52770885..d42cfc87 100644 --- a/tests/irc/Makefile.am +++ b/tests/irc/Makefile.am @@ -1 +1,3 @@ -SUBDIRS = core +SUBDIRS = \ + core \ + flood diff --git a/tests/irc/flood/Makefile.am b/tests/irc/flood/Makefile.am new file mode 100644 index 00000000..85b52eab --- /dev/null +++ b/tests/irc/flood/Makefile.am @@ -0,0 +1,40 @@ +include $(top_srcdir)/utils/glib-tap.mk + +PACKAGE_STRING=irc/flood + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + $(GLIB_CFLAGS) + +test_programs = \ + test-796 + +test_796_CPPFLAGS = \ + -I$(top_srcdir)/src/fe-common/core \ + -I$(top_srcdir)/src/irc/core \ + -I$(top_srcdir)/src/irc/flood \ + $(AM_CPPFLAGS) + +test_796_DEPENDENCIES = \ + ../../../src/core/libcore.a \ + ../../../src/lib-config/libirssi_config.a + +test_796_LDADD = \ + ../../../src/irc/libirc.a \ + ../../../src/fe-common/irc/libfe_common_irc.a \ + ../../../src/fe-common/irc/dcc/libfe_irc_dcc.a \ + ../../../src/fe-common/irc/notifylist/libfe_irc_notifylist.a \ + ../../../src/irc/dcc/libirc_dcc.a \ + ../../../src/irc/notifylist/libirc_notifylist.a \ + ../../../src/irc/flood/libirc_flood.a \ + ../../../src/irc/core/libirc_core.a \ + ../../../src/fe-common/core/libfe_common_core.a \ + ../../../src/core/libcore.a \ + ../../../src/lib-config/libirssi_config.a \ + @GLIB_LIBS@ \ + @OPENSSL_LIBS@ + +test_796_SOURCES = \ + test-796.c diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c new file mode 100644 index 00000000..2e4affa0 --- /dev/null +++ b/tests/irc/flood/test-796.c @@ -0,0 +1,174 @@ +/* + test-796.c : irssi + + Copyright (C) 2017 The Irssi project. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "common.h" +#include "args.h" +#include "core.h" +#include "misc.h" +#include "servers-setup.h" + +#include "formats.h" +#include "fe-common-core.h" + +#include "irc.h" +#include "irc-servers.h" +#include "irc-channels.h" + +/* irc.c */ +void irc_init(void); +void irc_deinit(void); + +/* irc-session.c */ +void irc_session_init(void); +void irc_session_deinit(void); + +/* fe-common-irc.c */ +void fe_common_irc_init(void); +void fe_common_irc_deinit(void); + +typedef struct { +} ServerDestroyFloodData; + +#define MODULE_NAME "tests" + +static void cmd_echo(const char *data, void *server, WI_ITEM_REC *item) +{ + g_test_message("echo: [server=%p,item=%p] %s", server, item, data); +} + +static void sig_public(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) +{ + signal_emit("send command", 3, "/eval echo $tag", server, NULL); +} + +static void print_disconnect(SERVER_REC *server) +{ + g_test_message("server %p was disconnected", server); +} + +static void print_destroyed(SERVER_REC *server) +{ + g_test_message("server %p was destroyed", server); +} + +static void server_destroy_flood_set_up(ServerDestroyFloodData *fixture, const void *data) +{ + args_execute(0, NULL); + core_init(); + irc_init(); + fe_common_core_init(); + fe_common_irc_init(); + signal_emit("irssi init finished", 0); + command_bind("echo", NULL, (SIGNAL_FUNC) cmd_echo); + signal_add("message public", (SIGNAL_FUNC) sig_public); + signal_add("server destroyed", (SIGNAL_FUNC) print_destroyed); + signal_add_first("server disconnected", (SIGNAL_FUNC) print_disconnect); +} + +static void server_destroy_flood_tear_down(ServerDestroyFloodData *fixture, const void *data) +{ + signal_remove("server disconnected", (SIGNAL_FUNC) print_disconnect); + signal_remove("server destroyed", (SIGNAL_FUNC) print_destroyed); + signal_remove("message public", (SIGNAL_FUNC) sig_public); + command_unbind("echo", (SIGNAL_FUNC) cmd_echo); + fe_common_irc_deinit(); + fe_common_core_deinit(); + irc_deinit(); + core_deinit(); +} + +static void irc_server_init_bare_minimum(IRC_SERVER_REC *server) +{ + server->isupport = g_hash_table_new((GHashFunc) g_istr_hash, + (GCompareFunc) g_istr_equal); + + /* set the standards */ + g_hash_table_insert(server->isupport, g_strdup("CHANMODES"), g_strdup("beI,k,l,imnpst")); + g_hash_table_insert(server->isupport, g_strdup("PREFIX"), g_strdup("(ohv)@%+")); +} + +static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const void *data) +{ + SERVER_REC *server; /* = g_new0(IRC_SERVER_REC, 1); */ + CHAT_PROTOCOL_REC *proto; + SERVER_CONNECT_REC *conn; + GLogLevelFlags loglev; + + g_test_bug("796"); + + /* for the purpose of this exercise, we are ignoring the + errors of g_hash_table_lookup failure */ + loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK); + + proto = chat_protocol_find("IRC"); + conn = server_create_conn(proto->id, "localhost", 0, "", "", "user"); + server = proto->server_init_connect(conn); + server->session_reconnect = TRUE; + server->tag = g_strdup("testserver"); + + g_test_message("created server: %p", server); + + /* we skip some initialisations that would try to send data */ + /* irc_servers_deinit(); */ + irc_session_deinit(); + irc_irc_deinit(); + + + server_connect_finished(server); + + /* make up for the skipped session init */ + irc_server_init_bare_minimum(IRC_SERVER(server)); + + irc_irc_init(); + irc_session_init(); + /* irc_servers_init(); */ + + /* simulate failing irc_server_send_data() */ + server->connection_lost = TRUE; + + /* + chat_completion_deinit(); + fe_messages_deinit(); + irc_notifylist_deinit(); + */ + + server_ref(server); + signal_emit("event privmsg", 4, server, "#someroom :test message", "nick", "user@host"); + server_unref(server); + + g_log_set_always_fatal(loglev); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + g_test_bug_base("https://github.com/irssi/irssi/issues/"); + + g_test_add("/test/server_destroy_flood", ServerDestroyFloodData, NULL, + server_destroy_flood_set_up, test_server_destroy_flood, + server_destroy_flood_tear_down); + + g_test_set_nonfatal_assertions(); + + core_preinit(*argv); + irssi_gui = IRSSI_GUI_NONE; + + return g_test_run(); +} diff --git a/utils/syncdocs.sh b/utils/syncdocs.sh index e723edd2..ed76bf85 100755 --- a/utils/syncdocs.sh +++ b/utils/syncdocs.sh @@ -11,7 +11,7 @@ howto=$site/documentation/startup/ # remove everything until H1 and optionally 2 DIVs before the # FOOTER. May need to be adjusted as the source pages change pageclean_regex='s{.*(?=<h1)}{}s; -s{\s*(</div>\s*)?(</div>\s*)?<footer.*}{}s; +s{(\s*<script\s.*?</script>)?\s*(</div>\s*){0,3}<footer.*}{}s; s{(<.*?)\sclass="(?:highlighter-rouge|highlight)"(.*?>)}{\1\2}g;' srcdir=`dirname "$0"` |